blob: 209f3237cecb6cb6b9ce5c047591b2bd089819b8 [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;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005802 //assumption is that timestamp is in milliseconds
5803 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5804 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005805 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5806
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005808 if(rc)
5809 {
5810 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5811 return OMX_ErrorHardware;
5812 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813 if(!streaming[OUTPUT_PORT])
5814 {
5815 enum v4l2_buf_type buf_type;
5816 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005817
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5819 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5820 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5821 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005822 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005823 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005824 } else{
5825 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005826 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005827 }
5828}
5829 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5830 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5831 time_stamp_dts.insert_timestamp(buffer);
5832
5833 return ret;
5834}
5835
5836/* ======================================================================
5837FUNCTION
5838 omx_vdec::FillThisBuffer
5839
5840DESCRIPTION
5841 IL client uses this method to release the frame buffer
5842 after displaying them.
5843
5844PARAMETERS
5845 None.
5846
5847RETURN VALUE
5848 true/false
5849
5850========================================================================== */
5851OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5852 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5853{
5854
5855 if(m_state == OMX_StateInvalid)
5856 {
5857 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5858 return OMX_ErrorInvalidState;
5859 }
5860
5861 if (!m_out_bEnabled)
5862 {
5863 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5864 return OMX_ErrorIncorrectStateOperation;
5865 }
5866
Vinay Kaliada4f4422013-01-09 10:45:03 -08005867 if (buffer == NULL ||
5868 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005869 {
5870 return OMX_ErrorBadParameter;
5871 }
5872
5873 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5874 {
5875 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex);
5876 return OMX_ErrorBadPortIndex;
5877 }
5878
5879 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005880 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005881 return OMX_ErrorNone;
5882}
5883/* ======================================================================
5884FUNCTION
5885 omx_vdec::fill_this_buffer_proxy
5886
5887DESCRIPTION
5888 IL client uses this method to release the frame buffer
5889 after displaying them.
5890
5891PARAMETERS
5892 None.
5893
5894RETURN VALUE
5895 true/false
5896
5897========================================================================== */
5898OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5899 OMX_IN OMX_HANDLETYPE hComp,
5900 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5901{
5902 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5903 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
5904 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5905 unsigned nPortIndex = 0;
5906 struct vdec_fillbuffer_cmd fillbuffer;
5907 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5908 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5909
Vinay Kaliada4f4422013-01-09 10:45:03 -08005910 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005911
Vinay Kaliada4f4422013-01-09 10:45:03 -08005912 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913 return OMX_ErrorBadParameter;
5914
5915 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5916 bufferAdd, bufferAdd->pBuffer);
5917 /*Return back the output buffer to client*/
5918 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5919 {
5920 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5921 buffer->nFilledLen = 0;
5922 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5923 return OMX_ErrorNone;
5924 }
5925 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005926 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005927 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5928 if (ptr_respbuffer)
5929 {
5930 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5931 }
5932
5933 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5934 {
5935 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5936 buffer->nFilledLen = 0;
5937 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5938 pending_output_buffers--;
5939 return OMX_ErrorBadParameter;
5940 }
5941
5942 // memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
5943 sizeof(struct vdec_bufferpayload));
5944 // fillbuffer.client_data = bufferAdd;
5945
5946#ifdef _ANDROID_ICS_
5947 if (m_enable_android_native_buffers)
5948 {
5949 // Acquire a write lock on this buffer.
5950 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5951 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5952 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5953 buffer->nFilledLen = 0;
5954 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5955 pending_output_buffers--;
5956 return OMX_ErrorInsufficientResources;
5957 } else {
5958 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5959 }
5960 }
5961#endif
5962 int rc = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005963 struct v4l2_buffer buf={0};
5964 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5965 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005966
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005967 buf.index = nPortIndex;
5968 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5969 buf.memory = V4L2_MEMORY_USERPTR;
5970 plane[0].bytesused = buffer->nFilledLen;
5971 plane[0].length = drv_ctx.op_buf.buffer_size;
5972 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr-drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5973 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5974 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5975 plane[0].data_offset = 0;
5976 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5977 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5978 plane[extra_idx].bytesused = 0;
5979 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5980 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5981#ifdef USE_ION
5982 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5983#endif
5984 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5985 plane[extra_idx].data_offset = 0;
5986 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5987 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5988 return OMX_ErrorBadParameter;
5989 }
5990 buf.m.planes = plane;
5991 buf.length = drv_ctx.num_planes;
5992 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5993 if (rc) {
5994 /*TODO: How to handle this case */
5995 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5996 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997//#ifdef _ANDROID_ICS_
5998 // if (m_enable_android_native_buffers)
5999 // {
6000 // Unlock the buffer
6001 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6002 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6003 // return OMX_ErrorInsufficientResources;
6004 /// } else {
6005 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6006 // }
6007 // }
6008//#endif
6009 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6010 // pending_output_buffers--;
6011 // return OMX_ErrorBadParameter;
6012 //}
6013 return OMX_ErrorNone;
6014}
6015
6016/* ======================================================================
6017FUNCTION
6018 omx_vdec::SetCallbacks
6019
6020DESCRIPTION
6021 Set the callbacks.
6022
6023PARAMETERS
6024 None.
6025
6026RETURN VALUE
6027 OMX Error None if everything successful.
6028
6029========================================================================== */
6030OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6031 OMX_IN OMX_CALLBACKTYPE* callbacks,
6032 OMX_IN OMX_PTR appData)
6033{
6034
6035 m_cb = *callbacks;
6036 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6037 m_cb.EventHandler,m_cb.FillBufferDone);
6038 m_app_data = appData;
6039 return OMX_ErrorNotImplemented;
6040}
6041
6042/* ======================================================================
6043FUNCTION
6044 omx_vdec::ComponentDeInit
6045
6046DESCRIPTION
6047 Destroys the component and release memory allocated to the heap.
6048
6049PARAMETERS
6050 <TBD>.
6051
6052RETURN VALUE
6053 OMX Error None if everything successful.
6054
6055========================================================================== */
6056OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6057{
6058#ifdef _ANDROID_
6059 if(iDivXDrmDecrypt)
6060 {
6061 delete iDivXDrmDecrypt;
6062 iDivXDrmDecrypt=NULL;
6063 }
6064#endif //_ANDROID_
6065
6066 int i = 0;
6067 if (OMX_StateLoaded != m_state)
6068 {
6069 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6070 m_state);
6071 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6072 }
6073 else
6074 {
6075 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6076 }
6077
6078 /*Check if the output buffers have to be cleaned up*/
6079 if(m_out_mem_ptr)
6080 {
6081 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
6082 for (i=0; i < drv_ctx.op_buf.actualcount; i++ )
6083 {
6084 free_output_buffer (&m_out_mem_ptr[i]);
6085#ifdef _ANDROID_ICS_
6086 if (m_enable_android_native_buffers)
6087 {
6088 if (native_buffer[i].inuse)
6089 {
6090 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6091 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6092 }
6093 native_buffer[i].inuse = false;
6094 }
6095 }
6096#endif
6097 }
6098#ifdef _ANDROID_ICS_
6099 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6100#endif
6101 }
6102
6103 /*Check if the input buffers have to be cleaned up*/
6104 if(m_inp_mem_ptr || m_inp_heap_ptr)
6105 {
6106 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
6107 for (i=0; i<drv_ctx.ip_buf.actualcount; i++ )
6108 {
6109 if (m_inp_mem_ptr)
6110 free_input_buffer (i,&m_inp_mem_ptr[i]);
6111 else
6112 free_input_buffer (i,NULL);
6113 }
6114 }
6115 free_input_buffer_header();
6116 free_output_buffer_header();
6117 if(h264_scratch.pBuffer)
6118 {
6119 free(h264_scratch.pBuffer);
6120 h264_scratch.pBuffer = NULL;
6121 }
6122
6123 if (h264_parser)
6124 {
6125 delete h264_parser;
6126 h264_parser = NULL;
6127 }
6128
6129 if(m_platform_list)
6130 {
6131 free(m_platform_list);
6132 m_platform_list = NULL;
6133 }
6134 if(m_vendor_config.pData)
6135 {
6136 free(m_vendor_config.pData);
6137 m_vendor_config.pData = NULL;
6138 }
6139
6140 // Reset counters in mesg queues
6141 m_ftb_q.m_size=0;
6142 m_cmd_q.m_size=0;
6143 m_etb_q.m_size=0;
6144 m_ftb_q.m_read = m_ftb_q.m_write =0;
6145 m_cmd_q.m_read = m_cmd_q.m_write =0;
6146 m_etb_q.m_read = m_etb_q.m_write =0;
6147#ifdef _ANDROID_
6148 if (m_debug_timestamp)
6149 {
6150 m_timestamp_list.reset_ts_list();
6151 }
6152#endif
6153
6154 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6155 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6156 // NULL);
6157 DEBUG_PRINT_HIGH("\n Close the driver instance");
6158
6159#ifdef INPUT_BUFFER_LOG
6160 fclose (inputBufferFile1);
6161#endif
6162#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006163 if (outputBufferFile1)
6164 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006165#endif
6166#ifdef OUTPUT_EXTRADATA_LOG
6167 fclose (outputExtradataFile);
6168#endif
6169 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6170 return OMX_ErrorNone;
6171}
6172
6173/* ======================================================================
6174FUNCTION
6175 omx_vdec::UseEGLImage
6176
6177DESCRIPTION
6178 OMX Use EGL Image method implementation <TBD>.
6179
6180PARAMETERS
6181 <TBD>.
6182
6183RETURN VALUE
6184 Not Implemented error.
6185
6186========================================================================== */
6187OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6188 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6189 OMX_IN OMX_U32 port,
6190 OMX_IN OMX_PTR appData,
6191 OMX_IN void* eglImage)
6192{
6193 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6194 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6195 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6196
6197#ifdef USE_EGL_IMAGE_GPU
6198 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6199 EGLint fd = -1, offset = 0,pmemPtr = 0;
6200#else
6201 int fd = -1, offset = 0;
6202#endif
6203 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6204 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6205 DEBUG_PRINT_ERROR("\n ");
6206 }
6207#ifdef USE_EGL_IMAGE_GPU
6208 if(m_display_id == NULL) {
6209 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6210 return OMX_ErrorInsufficientResources;
6211 }
6212 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6213 eglGetProcAddress("eglQueryImageKHR");
6214 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6215 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6216 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6217#else //with OMX test app
6218 struct temp_egl {
6219 int pmem_fd;
6220 int offset;
6221 };
6222 struct temp_egl *temp_egl_id = NULL;
6223 void * pmemPtr = (void *) eglImage;
6224 temp_egl_id = (struct temp_egl *)eglImage;
6225 if (temp_egl_id != NULL)
6226 {
6227 fd = temp_egl_id->pmem_fd;
6228 offset = temp_egl_id->offset;
6229 }
6230#endif
6231 if (fd < 0) {
6232 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6233 return OMX_ErrorInsufficientResources;
6234 }
6235 pmem_info.pmem_fd = (OMX_U32) fd;
6236 pmem_info.offset = (OMX_U32) offset;
6237 pmem_entry.entry = (void *) &pmem_info;
6238 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6239 pmem_list.entryList = &pmem_entry;
6240 pmem_list.nEntries = 1;
6241 ouput_egl_buffers = true;
6242 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6243 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6244 (OMX_U8 *)pmemPtr)) {
6245 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6246 return OMX_ErrorInsufficientResources;
6247 }
6248 return OMX_ErrorNone;
6249}
6250
6251/* ======================================================================
6252FUNCTION
6253 omx_vdec::ComponentRoleEnum
6254
6255DESCRIPTION
6256 OMX Component Role Enum method implementation.
6257
6258PARAMETERS
6259 <TBD>.
6260
6261RETURN VALUE
6262 OMX Error None if everything is successful.
6263========================================================================== */
6264OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6265 OMX_OUT OMX_U8* role,
6266 OMX_IN OMX_U32 index)
6267{
6268 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6269
6270 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6271 {
6272 if((0 == index) && role)
6273 {
6274 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6275 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6276 }
6277 else
6278 {
6279 eRet = OMX_ErrorNoMore;
6280 }
6281 }
6282 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6283 {
6284 if((0 == index) && role)
6285 {
6286 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6287 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6288 }
6289 else
6290 {
6291 eRet = OMX_ErrorNoMore;
6292 }
6293 }
6294 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6295 {
6296 if((0 == index) && role)
6297 {
6298 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6299 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6300 }
6301 else
6302 {
6303 DEBUG_PRINT_LOW("\n No more roles \n");
6304 eRet = OMX_ErrorNoMore;
6305 }
6306 }
6307
6308 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6309 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6310 )
6311
6312 {
6313 if((0 == index) && role)
6314 {
6315 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6316 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6317 }
6318 else
6319 {
6320 DEBUG_PRINT_LOW("\n No more roles \n");
6321 eRet = OMX_ErrorNoMore;
6322 }
6323 }
6324 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6325 {
6326 if((0 == index) && role)
6327 {
6328 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6329 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6330 }
6331 else
6332 {
6333 DEBUG_PRINT_LOW("\n No more roles \n");
6334 eRet = OMX_ErrorNoMore;
6335 }
6336 }
6337 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6338 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6339 )
6340 {
6341 if((0 == index) && role)
6342 {
6343 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6344 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6345 }
6346 else
6347 {
6348 DEBUG_PRINT_LOW("\n No more roles \n");
6349 eRet = OMX_ErrorNoMore;
6350 }
6351 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006352 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6353 {
6354 if((0 == index) && role)
6355 {
6356 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6357 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6358 }
6359 else
6360 {
6361 DEBUG_PRINT_LOW("\n No more roles \n");
6362 eRet = OMX_ErrorNoMore;
6363 }
6364 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006365 else
6366 {
6367 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6368 eRet = OMX_ErrorInvalidComponentName;
6369 }
6370 return eRet;
6371}
6372
6373
6374
6375
6376/* ======================================================================
6377FUNCTION
6378 omx_vdec::AllocateDone
6379
6380DESCRIPTION
6381 Checks if entire buffer pool is allocated by IL Client or not.
6382 Need this to move to IDLE state.
6383
6384PARAMETERS
6385 None.
6386
6387RETURN VALUE
6388 true/false.
6389
6390========================================================================== */
6391bool omx_vdec::allocate_done(void)
6392{
6393 bool bRet = false;
6394 bool bRet_In = false;
6395 bool bRet_Out = false;
6396
6397 bRet_In = allocate_input_done();
6398 bRet_Out = allocate_output_done();
6399
6400 if(bRet_In && bRet_Out)
6401 {
6402 bRet = true;
6403 }
6404
6405 return bRet;
6406}
6407/* ======================================================================
6408FUNCTION
6409 omx_vdec::AllocateInputDone
6410
6411DESCRIPTION
6412 Checks if I/P buffer pool is allocated by IL Client or not.
6413
6414PARAMETERS
6415 None.
6416
6417RETURN VALUE
6418 true/false.
6419
6420========================================================================== */
6421bool omx_vdec::allocate_input_done(void)
6422{
6423 bool bRet = false;
6424 unsigned i=0;
6425
6426 if (m_inp_mem_ptr == NULL)
6427 {
6428 return bRet;
6429 }
6430 if(m_inp_mem_ptr )
6431 {
6432 for(;i<drv_ctx.ip_buf.actualcount;i++)
6433 {
6434 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6435 {
6436 break;
6437 }
6438 }
6439 }
6440 if(i == drv_ctx.ip_buf.actualcount)
6441 {
6442 bRet = true;
6443 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6444 }
6445 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6446 {
6447 m_inp_bPopulated = OMX_TRUE;
6448 }
6449 return bRet;
6450}
6451/* ======================================================================
6452FUNCTION
6453 omx_vdec::AllocateOutputDone
6454
6455DESCRIPTION
6456 Checks if entire O/P buffer pool is allocated by IL Client or not.
6457
6458PARAMETERS
6459 None.
6460
6461RETURN VALUE
6462 true/false.
6463
6464========================================================================== */
6465bool omx_vdec::allocate_output_done(void)
6466{
6467 bool bRet = false;
6468 unsigned j=0;
6469
6470 if (m_out_mem_ptr == NULL)
6471 {
6472 return bRet;
6473 }
6474
6475 if (m_out_mem_ptr)
6476 {
6477 for(;j < drv_ctx.op_buf.actualcount;j++)
6478 {
6479 if(BITMASK_ABSENT(&m_out_bm_count,j))
6480 {
6481 break;
6482 }
6483 }
6484 }
6485
6486 if(j == drv_ctx.op_buf.actualcount)
6487 {
6488 bRet = true;
6489 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6490 if(m_out_bEnabled)
6491 m_out_bPopulated = OMX_TRUE;
6492 }
6493
6494 return bRet;
6495}
6496
6497/* ======================================================================
6498FUNCTION
6499 omx_vdec::ReleaseDone
6500
6501DESCRIPTION
6502 Checks if IL client has released all the buffers.
6503
6504PARAMETERS
6505 None.
6506
6507RETURN VALUE
6508 true/false
6509
6510========================================================================== */
6511bool omx_vdec::release_done(void)
6512{
6513 bool bRet = false;
6514
6515 if(release_input_done())
6516 {
6517 if(release_output_done())
6518 {
6519 bRet = true;
6520 }
6521 }
6522 return bRet;
6523}
6524
6525
6526/* ======================================================================
6527FUNCTION
6528 omx_vdec::ReleaseOutputDone
6529
6530DESCRIPTION
6531 Checks if IL client has released all the buffers.
6532
6533PARAMETERS
6534 None.
6535
6536RETURN VALUE
6537 true/false
6538
6539========================================================================== */
6540bool omx_vdec::release_output_done(void)
6541{
6542 bool bRet = false;
6543 unsigned i=0,j=0;
6544
6545 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6546 if(m_out_mem_ptr)
6547 {
6548 for(;j < drv_ctx.op_buf.actualcount ; j++)
6549 {
6550 if(BITMASK_PRESENT(&m_out_bm_count,j))
6551 {
6552 break;
6553 }
6554 }
6555 if(j == drv_ctx.op_buf.actualcount)
6556 {
6557 m_out_bm_count = 0;
6558 bRet = true;
6559 }
6560 }
6561 else
6562 {
6563 m_out_bm_count = 0;
6564 bRet = true;
6565 }
6566 return bRet;
6567}
6568/* ======================================================================
6569FUNCTION
6570 omx_vdec::ReleaseInputDone
6571
6572DESCRIPTION
6573 Checks if IL client has released all the buffers.
6574
6575PARAMETERS
6576 None.
6577
6578RETURN VALUE
6579 true/false
6580
6581========================================================================== */
6582bool omx_vdec::release_input_done(void)
6583{
6584 bool bRet = false;
6585 unsigned i=0,j=0;
6586
6587 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6588 if(m_inp_mem_ptr)
6589 {
6590 for(;j<drv_ctx.ip_buf.actualcount;j++)
6591 {
6592 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6593 {
6594 break;
6595 }
6596 }
6597 if(j==drv_ctx.ip_buf.actualcount)
6598 {
6599 bRet = true;
6600 }
6601 }
6602 else
6603 {
6604 bRet = true;
6605 }
6606 return bRet;
6607}
6608
6609OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6610 OMX_BUFFERHEADERTYPE * buffer)
6611{
6612 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6613 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6614 {
6615 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6616 return OMX_ErrorBadParameter;
6617 }
6618 else if (output_flush_progress)
6619 {
6620 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6621 buffer->nFilledLen = 0;
6622 buffer->nTimeStamp = 0;
6623 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6624 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6625 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6626 }
6627
6628 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6629 buffer, buffer->pBuffer);
6630 pending_output_buffers --;
6631
6632 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6633 {
6634 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6635 if (!output_flush_progress)
6636 post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE);
6637
6638 if (psource_frame)
6639 {
6640 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6641 psource_frame = NULL;
6642 }
6643 if (pdest_frame)
6644 {
6645 pdest_frame->nFilledLen = 0;
6646 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6647 pdest_frame = NULL;
6648 }
6649 }
6650
6651 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6652#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006653 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006654 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006655 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006656 int stride = drv_ctx.video_resolution.stride;
6657 int scanlines = drv_ctx.video_resolution.scan_lines;
6658 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006659 int i;
6660 int bytes_written = 0;
6661 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6662 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6663 temp += stride;
6664 }
6665 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006666 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006667 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6668 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6669 temp += stride_c;
6670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006671 }
6672#endif
6673
6674 /* For use buffer we need to copy the data */
6675 if (!output_flush_progress)
6676 {
6677 time_stamp_dts.get_next_timestamp(buffer,
6678 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6679 ?true:false);
6680 }
6681 if (m_cb.FillBufferDone)
6682 {
6683 if (buffer->nFilledLen > 0)
6684 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006685 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006686 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6687 // Keep min timestamp interval to handle corrupted bit stream scenario
6688 set_frame_rate(buffer->nTimeStamp);
6689 else if (arbitrary_bytes)
6690 adjust_timestamp(buffer->nTimeStamp);
6691 if (perf_flag)
6692 {
6693 if (!proc_frms)
6694 {
6695 dec_time.stop();
6696 latency = dec_time.processing_time_us() - latency;
6697 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6698 dec_time.start();
6699 fps_metrics.start();
6700 }
6701 proc_frms++;
6702 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6703 {
6704 OMX_U64 proc_time = 0;
6705 fps_metrics.stop();
6706 proc_time = fps_metrics.processing_time_us();
6707 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6708 proc_frms, (float)proc_time / 1e6,
6709 (float)(1e6 * proc_frms) / proc_time);
6710 proc_frms = 0;
6711 }
6712 }
6713
6714#ifdef OUTPUT_EXTRADATA_LOG
6715 if (outputExtradataFile)
6716 {
6717
6718 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6719 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6720 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6721 buffer->nFilledLen + 3)&(~3));
6722 while(p_extra &&
6723 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6724 {
6725 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6726 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6727 if (p_extra->eType == OMX_ExtraDataNone)
6728 {
6729 break;
6730 }
6731 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6732 }
6733 }
6734#endif
6735 }
6736 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6737 prev_ts = LLONG_MAX;
6738 rst_prev_ts = true;
6739 }
6740
6741 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6742 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6743 buffer->pPlatformPrivate)->entryList->entry;
6744 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
6745#ifdef _ANDROID_ICS_
6746 if (m_enable_android_native_buffers)
6747 {
6748 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6749 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6750 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6751 return OMX_ErrorInsufficientResources;
6752 }
6753 else {
6754 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6755 }
6756 }
6757 }
6758#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006759 OMX_BUFFERHEADERTYPE *il_buffer;
6760 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6761 if (il_buffer)
6762 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6763 else {
6764 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6765 return OMX_ErrorBadParameter;
6766 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006767 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
6768 }
6769 else
6770 {
6771 return OMX_ErrorBadParameter;
6772 }
6773
6774 return OMX_ErrorNone;
6775}
6776
6777OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6778 OMX_BUFFERHEADERTYPE* buffer)
6779{
6780
6781 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6782 {
6783 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6784 return OMX_ErrorBadParameter;
6785 }
6786
6787 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6788 buffer, buffer->pBuffer);
6789 pending_input_buffers--;
6790
6791 if (arbitrary_bytes)
6792 {
6793 if (pdest_frame == NULL && input_flush_progress == false)
6794 {
6795 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6796 pdest_frame = buffer;
6797 buffer->nFilledLen = 0;
6798 buffer->nTimeStamp = LLONG_MAX;
6799 push_input_buffer (hComp);
6800 }
6801 else
6802 {
6803 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6804 buffer->nFilledLen = 0;
6805 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
6806 {
6807 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6808 }
6809 }
6810 }
6811 else if(m_cb.EmptyBufferDone)
6812 {
6813 buffer->nFilledLen = 0;
6814 if (input_use_buffer == true){
6815 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6816 }
6817 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6818 }
6819 return OMX_ErrorNone;
6820}
6821
Shalaj Jain273b3e02012-06-22 19:08:03 -07006822int omx_vdec::async_message_process (void *context, void* message)
6823{
6824 omx_vdec* omx = NULL;
6825 struct vdec_msginfo *vdec_msg = NULL;
6826 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6827 struct v4l2_buffer *v4l2_buf_ptr=NULL;
6828 struct vdec_output_frameinfo *output_respbuf = NULL;
6829 int rc=1;
6830 if (context == NULL || message == NULL)
6831 {
6832 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6833 return -1;
6834 }
6835 vdec_msg = (struct vdec_msginfo *)message;
6836
6837 omx = reinterpret_cast<omx_vdec*>(context);
6838
6839#ifdef _ANDROID_
6840 if (omx->m_debug_timestamp)
6841 {
6842 if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) &&
6843 !(omx->output_flush_progress) )
6844 {
6845 OMX_TICKS expected_ts = 0;
6846 omx->m_timestamp_list.pop_min_ts(expected_ts);
6847 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6848 vdec_msg->msgdata.output_frame.time_stamp, expected_ts);
6849
6850 if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts)
6851 {
6852 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6853 }
6854 }
6855 }
6856#endif
6857
6858 switch (vdec_msg->msgcode)
6859 {
6860
6861 case VDEC_MSG_EVT_HW_ERROR:
6862 omx->post_event (NULL,vdec_msg->status_code,\
6863 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6864 break;
6865
6866 case VDEC_MSG_RESP_START_DONE:
6867 omx->post_event (NULL,vdec_msg->status_code,\
6868 OMX_COMPONENT_GENERATE_START_DONE);
6869 break;
6870
6871 case VDEC_MSG_RESP_STOP_DONE:
6872 omx->post_event (NULL,vdec_msg->status_code,\
6873 OMX_COMPONENT_GENERATE_STOP_DONE);
6874 break;
6875
6876 case VDEC_MSG_RESP_RESUME_DONE:
6877 omx->post_event (NULL,vdec_msg->status_code,\
6878 OMX_COMPONENT_GENERATE_RESUME_DONE);
6879 break;
6880
6881 case VDEC_MSG_RESP_PAUSE_DONE:
6882 omx->post_event (NULL,vdec_msg->status_code,\
6883 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6884 break;
6885
6886 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6887 omx->post_event (NULL,vdec_msg->status_code,\
6888 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6889 break;
6890 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6891 omx->post_event (NULL,vdec_msg->status_code,\
6892 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6893 break;
6894 case VDEC_MSG_RESP_INPUT_FLUSHED:
6895 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6896
6897 // omxhdr = (OMX_BUFFERHEADERTYPE* ) \
6898 // vdec_msg->msgdata.input_frame_clientdata;
6899
6900 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6901 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6902 if (omxhdr == NULL ||
6903 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6904 {
6905 omxhdr = NULL;
6906 vdec_msg->status_code = VDEC_S_EFATAL;
6907 }
6908
6909 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6910 OMX_COMPONENT_GENERATE_EBD);
6911 break;
6912 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6913 int64_t *timestamp;
6914 timestamp = (int64_t *) malloc(sizeof(int64_t));
6915 if (timestamp) {
6916 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6917 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6918 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6919 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6920 vdec_msg->msgdata.output_frame.time_stamp);
6921 }
6922 break;
6923 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6924 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6925
6926 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6927 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6928 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6929 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6930 vdec_msg->msgdata.output_frame.pic_type);
6931
6932 if (omxhdr && omxhdr->pOutputPortPrivate &&
6933 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6934 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6935 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6936 {
6937 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6938 {
6939 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6940 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006941 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006942 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6943
6944 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6945 {
6946 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6947 //rc = -1;
6948 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006949 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6950 {
6951 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6952 }
6953 vdec_msg->msgdata.output_frame.bufferaddr=omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6954 if (omxhdr->nFilledLen && ((omx->rectangle.nLeft != vdec_msg->msgdata.output_frame.framesize.left)
6955 || (omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6956 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6957 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6958 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6959 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6960 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6961 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6962 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
6963 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6964 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6965 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006966 output_respbuf = (struct vdec_output_frameinfo *)\
6967 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006968 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6969 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006970 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
6971 {
6972 output_respbuf->pic_type = PICTURE_TYPE_I;
6973 }
6974 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
6975 {
6976 output_respbuf->pic_type = PICTURE_TYPE_P;
6977 }
6978 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6979 output_respbuf->pic_type = PICTURE_TYPE_B;
6980 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006981
6982 if (omx->output_use_buffer)
6983 memcpy ( omxhdr->pBuffer,
6984 (vdec_msg->msgdata.output_frame.bufferaddr +
6985 vdec_msg->msgdata.output_frame.offset),
6986 vdec_msg->msgdata.output_frame.len );
6987 }
6988 else
6989 omxhdr->nFilledLen = 0;
6990 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6991 OMX_COMPONENT_GENERATE_FBD);
6992 }
6993 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6994 omx->post_event (NULL, vdec_msg->status_code,
6995 OMX_COMPONENT_GENERATE_EOS_DONE);
6996 else
6997 omx->post_event (NULL, vdec_msg->status_code,
6998 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6999 break;
7000 case VDEC_MSG_EVT_CONFIG_CHANGED:
7001 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007002 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7003 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004 break;
7005 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
7006 {
7007 DEBUG_PRINT_HIGH("\n Port settings changed info");
7008 // get_buffer_req and populate port defn structure
7009 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07007010 struct v4l2_format fmt;
7011 int ret;
7012 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7013 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007014 omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08007015 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
7016 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
Shalaj Jain273b3e02012-06-22 19:08:03 -07007017 omx->m_port_def.nPortIndex = 1;
7018 eRet = omx->update_portdef(&(omx->m_port_def));
Praneeth Paladuguea69de02012-10-30 11:40:17 -07007019 omx->post_event (NULL,vdec_msg->status_code,\
7020 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007021 break;
7022 }
7023 default:
7024 break;
7025 }
7026 return rc;
7027}
7028
7029OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7030 OMX_HANDLETYPE hComp,
7031 OMX_BUFFERHEADERTYPE *buffer
7032 )
7033{
7034 unsigned address,p2,id;
7035 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7036
7037 if (buffer == NULL)
7038 {
7039 return OMX_ErrorBadParameter;
7040 }
7041 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7042 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
7043 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
7044
7045 /* return zero length and not an EOS buffer */
7046 /* return buffer if input flush in progress */
7047 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7048 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7049 {
7050 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7051 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7052 return OMX_ErrorNone;
7053 }
7054
7055 if (psource_frame == NULL)
7056 {
7057 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
7058 psource_frame = buffer;
7059 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7060 push_input_buffer (hComp);
7061 }
7062 else
7063 {
7064 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
7065 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
7066 {
7067 return OMX_ErrorBadParameter;
7068 }
7069 }
7070
7071
7072 return OMX_ErrorNone;
7073}
7074
7075OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7076{
7077 unsigned address,p2,id;
7078 OMX_ERRORTYPE ret = OMX_ErrorNone;
7079
7080 if (pdest_frame == NULL || psource_frame == NULL)
7081 {
7082 /*Check if we have a destination buffer*/
7083 if (pdest_frame == NULL)
7084 {
7085 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7086 if (m_input_free_q.m_size)
7087 {
7088 m_input_free_q.pop_entry(&address,&p2,&id);
7089 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7090 pdest_frame->nFilledLen = 0;
7091 pdest_frame->nTimeStamp = LLONG_MAX;
7092 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7093 }
7094 }
7095
7096 /*Check if we have a destination buffer*/
7097 if (psource_frame == NULL)
7098 {
7099 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7100 if (m_input_pending_q.m_size)
7101 {
7102 m_input_pending_q.pop_entry(&address,&p2,&id);
7103 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
7104 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7105 psource_frame->nTimeStamp);
7106 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7107 psource_frame->nFlags,psource_frame->nFilledLen);
7108
7109 }
7110 }
7111
7112 }
7113
7114 while ((pdest_frame != NULL) && (psource_frame != NULL))
7115 {
7116 switch (codec_type_parse)
7117 {
7118 case CODEC_TYPE_MPEG4:
7119 case CODEC_TYPE_H263:
7120 case CODEC_TYPE_MPEG2:
7121 ret = push_input_sc_codec(hComp);
7122 break;
7123 case CODEC_TYPE_H264:
7124 ret = push_input_h264(hComp);
7125 break;
7126 case CODEC_TYPE_VC1:
7127 ret = push_input_vc1(hComp);
7128 break;
7129 }
7130 if (ret != OMX_ErrorNone)
7131 {
7132 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7133 omx_report_error ();
7134 break;
7135 }
7136 }
7137
7138 return ret;
7139}
7140
7141OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7142{
7143 OMX_U32 partial_frame = 1;
7144 OMX_BOOL generate_ebd = OMX_TRUE;
7145 unsigned address,p2,id;
7146
7147 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
7148 psource_frame,psource_frame->nTimeStamp);
7149 if (m_frame_parser.parse_sc_frame(psource_frame,
7150 pdest_frame,&partial_frame) == -1)
7151 {
7152 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7153 return OMX_ErrorBadParameter;
7154 }
7155
7156 if (partial_frame == 0)
7157 {
7158 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
7159 pdest_frame->nFilledLen,psource_frame,frame_count);
7160
7161
7162 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
7163 /*First Parsed buffer will have only header Hence skip*/
7164 if (frame_count == 0)
7165 {
7166 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7167
7168 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7169 codec_type_parse == CODEC_TYPE_DIVX) {
7170 mp4StreamType psBits;
7171 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7172 psBits.numBytes = pdest_frame->nFilledLen;
7173 mp4_headerparser.parseHeader(&psBits);
7174 }
7175
7176 frame_count++;
7177 }
7178 else
7179 {
7180 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7181 if(pdest_frame->nFilledLen)
7182 {
7183 /*Push the frame to the Decoder*/
7184 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7185 {
7186 return OMX_ErrorBadParameter;
7187 }
7188 frame_count++;
7189 pdest_frame = NULL;
7190
7191 if (m_input_free_q.m_size)
7192 {
7193 m_input_free_q.pop_entry(&address,&p2,&id);
7194 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7195 pdest_frame->nFilledLen = 0;
7196 }
7197 }
7198 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7199 {
7200 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
7201 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
7202 pdest_frame = NULL;
7203 }
7204 }
7205 }
7206 else
7207 {
7208 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
7209 /*Check if Destination Buffer is full*/
7210 if (pdest_frame->nAllocLen ==
7211 pdest_frame->nFilledLen + pdest_frame->nOffset)
7212 {
7213 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7214 return OMX_ErrorStreamCorrupt;
7215 }
7216 }
7217
7218 if (psource_frame->nFilledLen == 0)
7219 {
7220 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7221 {
7222 if (pdest_frame)
7223 {
7224 pdest_frame->nFlags |= psource_frame->nFlags;
7225 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7226 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7227 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7228 pdest_frame->nFilledLen,frame_count++);
7229 /*Push the frame to the Decoder*/
7230 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7231 {
7232 return OMX_ErrorBadParameter;
7233 }
7234 frame_count++;
7235 pdest_frame = NULL;
7236 }
7237 else
7238 {
7239 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7240 generate_ebd = OMX_FALSE;
7241 }
7242 }
7243 if(generate_ebd)
7244 {
7245 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7246 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7247 psource_frame = NULL;
7248
7249 if (m_input_pending_q.m_size)
7250 {
7251 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7252 m_input_pending_q.pop_entry(&address,&p2,&id);
7253 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7254 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7255 psource_frame->nTimeStamp);
7256 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7257 psource_frame->nFlags,psource_frame->nFilledLen);
7258 }
7259 }
7260 }
7261 return OMX_ErrorNone;
7262}
7263
7264OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7265{
7266 OMX_U32 partial_frame = 1;
7267 unsigned address,p2,id;
7268 OMX_BOOL isNewFrame = OMX_FALSE;
7269 OMX_BOOL generate_ebd = OMX_TRUE;
7270
7271 if (h264_scratch.pBuffer == NULL)
7272 {
7273 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7274 return OMX_ErrorBadParameter;
7275 }
7276 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d "
7277 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7278 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7279 if (h264_scratch.nFilledLen && look_ahead_nal)
7280 {
7281 look_ahead_nal = false;
7282 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7283 h264_scratch.nFilledLen)
7284 {
7285 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7286 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7287 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7288 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7289 h264_scratch.nFilledLen = 0;
7290 }
7291 else
7292 {
7293 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7294 return OMX_ErrorBadParameter;
7295 }
7296 }
7297 if (nal_length == 0)
7298 {
7299 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7300 if (m_frame_parser.parse_sc_frame(psource_frame,
7301 &h264_scratch,&partial_frame) == -1)
7302 {
7303 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7304 return OMX_ErrorBadParameter;
7305 }
7306 }
7307 else
7308 {
7309 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7310 if (m_frame_parser.parse_h264_nallength(psource_frame,
7311 &h264_scratch,&partial_frame) == -1)
7312 {
7313 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7314 return OMX_ErrorBadParameter;
7315 }
7316 }
7317
7318 if (partial_frame == 0)
7319 {
7320 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7321 {
7322 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7323 nal_count++;
7324 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7325 h264_scratch.nFlags = psource_frame->nFlags;
7326 }
7327 else
7328 {
7329 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen);
7330 if(h264_scratch.nFilledLen)
7331 {
7332 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7333 NALU_TYPE_SPS);
7334#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7335 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7336 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7337 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7338 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7339 // If timeinfo is present frame info from SEI is already processed
7340 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7341 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7342#endif
7343 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7344 nal_count++;
7345 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7346 pdest_frame->nTimeStamp = h264_last_au_ts;
7347 pdest_frame->nFlags = h264_last_au_flags;
7348#ifdef PANSCAN_HDLR
7349 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7350 h264_parser->update_panscan_data(h264_last_au_ts);
7351#endif
7352 }
7353 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7354 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7355 h264_last_au_ts = h264_scratch.nTimeStamp;
7356 h264_last_au_flags = h264_scratch.nFlags;
7357#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7358 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7359 {
7360 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7361 if (!VALID_TS(h264_last_au_ts))
7362 h264_last_au_ts = ts_in_sei;
7363 }
7364#endif
7365 } else
7366 h264_last_au_ts = LLONG_MAX;
7367 }
7368
7369 if (!isNewFrame)
7370 {
7371 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7372 h264_scratch.nFilledLen)
7373 {
7374 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
7375 h264_scratch.nFilledLen);
7376 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7377 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7378 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7379 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7380 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7381 h264_scratch.nFilledLen = 0;
7382 }
7383 else
7384 {
7385 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7386 return OMX_ErrorBadParameter;
7387 }
7388 }
7389 else
7390 {
7391 look_ahead_nal = true;
7392 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7393 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7394 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7395 pdest_frame->nFilledLen,frame_count++);
7396
7397 if (pdest_frame->nFilledLen == 0)
7398 {
7399 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7400 look_ahead_nal = false;
7401 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7402 h264_scratch.nFilledLen)
7403 {
7404 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7405 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7406 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7407 h264_scratch.nFilledLen = 0;
7408 }
7409 else
7410 {
7411 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7412 return OMX_ErrorBadParameter;
7413 }
7414 }
7415 else
7416 {
7417 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7418 {
7419 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7420 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7421 }
7422 /*Push the frame to the Decoder*/
7423 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7424 {
7425 return OMX_ErrorBadParameter;
7426 }
7427 //frame_count++;
7428 pdest_frame = NULL;
7429 if (m_input_free_q.m_size)
7430 {
7431 m_input_free_q.pop_entry(&address,&p2,&id);
7432 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7433 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7434 pdest_frame->nFilledLen = 0;
7435 pdest_frame->nFlags = 0;
7436 pdest_frame->nTimeStamp = LLONG_MAX;
7437 }
7438 }
7439 }
7440 }
7441 }
7442 else
7443 {
7444 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7445 /*Check if Destination Buffer is full*/
7446 if (h264_scratch.nAllocLen ==
7447 h264_scratch.nFilledLen + h264_scratch.nOffset)
7448 {
7449 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7450 return OMX_ErrorStreamCorrupt;
7451 }
7452 }
7453
7454 if (!psource_frame->nFilledLen)
7455 {
7456 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7457
7458 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7459 {
7460 if (pdest_frame)
7461 {
7462 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7463 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7464 h264_scratch.nFilledLen)
7465 {
7466 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7467 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7468 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7469 h264_scratch.nFilledLen = 0;
7470 }
7471 else
7472 {
7473 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7474 return OMX_ErrorBadParameter;
7475 }
7476 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7477 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7478
7479 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x",
7480 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7481 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7482#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7483 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7484 {
7485 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7486 if (!VALID_TS(pdest_frame->nTimeStamp))
7487 pdest_frame->nTimeStamp = ts_in_sei;
7488 }
7489#endif
7490 /*Push the frame to the Decoder*/
7491 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7492 {
7493 return OMX_ErrorBadParameter;
7494 }
7495 frame_count++;
7496 pdest_frame = NULL;
7497 }
7498 else
7499 {
7500 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
7501 pdest_frame,h264_scratch.nFilledLen);
7502 generate_ebd = OMX_FALSE;
7503 }
7504 }
7505 }
7506 if(generate_ebd && !psource_frame->nFilledLen)
7507 {
7508 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7509 psource_frame = NULL;
7510 if (m_input_pending_q.m_size)
7511 {
7512 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7513 m_input_pending_q.pop_entry(&address,&p2,&id);
7514 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7515 DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d",
7516 psource_frame->nFlags,psource_frame->nFilledLen);
7517 }
7518 }
7519 return OMX_ErrorNone;
7520}
7521
7522OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7523{
7524 OMX_U8 *buf, *pdest;
7525 OMX_U32 partial_frame = 1;
7526 OMX_U32 buf_len, dest_len;
7527
7528 if(first_frame == 0)
7529 {
7530 first_frame = 1;
7531 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7532 if(!m_vendor_config.pData)
7533 {
7534 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7535 buf = psource_frame->pBuffer;
7536 buf_len = psource_frame->nFilledLen;
7537
7538 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7539 VC1_SP_MP_START_CODE)
7540 {
7541 m_vc1_profile = VC1_SP_MP_RCV;
7542 }
7543 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7544 {
7545 m_vc1_profile = VC1_AP;
7546 }
7547 else
7548 {
7549 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7550 return OMX_ErrorStreamCorrupt;
7551 }
7552 }
7553 else
7554 {
7555 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7556 pdest_frame->nOffset;
7557 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7558 pdest_frame->nOffset);
7559
7560 if(dest_len < m_vendor_config.nDataSize)
7561 {
7562 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7563 return OMX_ErrorBadParameter;
7564 }
7565 else
7566 {
7567 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7568 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7569 }
7570 }
7571 }
7572
7573 switch(m_vc1_profile)
7574 {
7575 case VC1_AP:
7576 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7577 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7578 {
7579 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7580 return OMX_ErrorBadParameter;
7581 }
7582 break;
7583
7584 case VC1_SP_MP_RCV:
7585 default:
7586 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7587 return OMX_ErrorBadParameter;
7588 }
7589 return OMX_ErrorNone;
7590}
7591
7592bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7593 OMX_U32 alignment)
7594{
7595 struct pmem_allocation allocation;
7596 allocation.size = buffer_size;
7597 allocation.align = clip2(alignment);
7598 if (allocation.align < 4096)
7599 {
7600 allocation.align = 4096;
7601 }
7602 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7603 {
7604 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7605 allocation.align, allocation.size);
7606 return false;
7607 }
7608 return true;
7609}
7610#ifdef USE_ION
7611int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7612 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7613 struct ion_fd_data *fd_data, int flag)
7614{
7615 int fd = -EINVAL;
7616 int rc = -EINVAL;
7617 int ion_dev_flag;
7618 struct vdec_ion ion_buf_info;
7619 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7620 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7621 return -EINVAL;
7622 }
Arun Menon737de532012-09-14 14:48:18 -07007623 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007624 fd = open (MEM_DEVICE, ion_dev_flag);
7625 if (fd < 0) {
7626 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7627 return fd;
7628 }
Arun Menon737de532012-09-14 14:48:18 -07007629 alloc_data->flags = 0;
7630 if(!secure_mode && (flag & ION_FLAG_CACHED))
7631 {
7632 alloc_data->flags |= ION_FLAG_CACHED;
7633 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007634 alloc_data->len = buffer_size;
7635 alloc_data->align = clip2(alignment);
7636 if (alloc_data->align < 4096)
7637 {
7638 alloc_data->align = 4096;
7639 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007640 if ((secure_mode) && (flag & ION_SECURE))
7641 alloc_data->flags |= ION_SECURE;
7642
7643 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Vinay Kalia14c26132012-12-07 15:18:14 -08007644 if (!secure_mode)
7645 alloc_data->heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007646 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7647 if (rc || !alloc_data->handle) {
7648 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7649 alloc_data->handle = NULL;
7650 close(fd);
7651 fd = -ENOMEM;
7652 return fd;
7653 }
7654 fd_data->handle = alloc_data->handle;
7655 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7656 if (rc) {
7657 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7658 ion_buf_info.ion_alloc_data = *alloc_data;
7659 ion_buf_info.ion_device_fd = fd;
7660 ion_buf_info.fd_ion_data = *fd_data;
7661 free_ion_memory(&ion_buf_info);
7662 fd_data->fd =-1;
7663 close(fd);
7664 fd = -ENOMEM;
7665 }
7666
7667 return fd;
7668}
7669
7670void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7671
7672 if(!buf_ion_info) {
7673 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7674 return;
7675 }
7676 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7677 &buf_ion_info->ion_alloc_data.handle)) {
7678 DEBUG_PRINT_ERROR("\n ION: free failed" );
7679 }
7680 close(buf_ion_info->ion_device_fd);
7681 buf_ion_info->ion_device_fd = -1;
7682 buf_ion_info->ion_alloc_data.handle = NULL;
7683 buf_ion_info->fd_ion_data.fd = -1;
7684}
7685#endif
7686void omx_vdec::free_output_buffer_header()
7687{
7688 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7689 output_use_buffer = false;
7690 ouput_egl_buffers = false;
7691
7692 if (m_out_mem_ptr)
7693 {
7694 free (m_out_mem_ptr);
7695 m_out_mem_ptr = NULL;
7696 }
7697
7698 if(m_platform_list)
7699 {
7700 free(m_platform_list);
7701 m_platform_list = NULL;
7702 }
7703
7704 if (drv_ctx.ptr_respbuffer)
7705 {
7706 free (drv_ctx.ptr_respbuffer);
7707 drv_ctx.ptr_respbuffer = NULL;
7708 }
7709 if (drv_ctx.ptr_outputbuffer)
7710 {
7711 free (drv_ctx.ptr_outputbuffer);
7712 drv_ctx.ptr_outputbuffer = NULL;
7713 }
7714#ifdef USE_ION
7715 if (drv_ctx.op_buf_ion_info) {
7716 DEBUG_PRINT_LOW("\n Free o/p ion context");
7717 free(drv_ctx.op_buf_ion_info);
7718 drv_ctx.op_buf_ion_info = NULL;
7719 }
7720#endif
7721}
7722
7723void omx_vdec::free_input_buffer_header()
7724{
7725 input_use_buffer = false;
7726 if (arbitrary_bytes)
7727 {
7728 if (m_frame_parser.mutils)
7729 {
7730 DEBUG_PRINT_LOW("\n Free utils parser");
7731 delete (m_frame_parser.mutils);
7732 m_frame_parser.mutils = NULL;
7733 }
7734
7735 if (m_inp_heap_ptr)
7736 {
7737 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7738 free (m_inp_heap_ptr);
7739 m_inp_heap_ptr = NULL;
7740 }
7741
7742 if (m_phdr_pmem_ptr)
7743 {
7744 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7745 free (m_phdr_pmem_ptr);
7746 m_phdr_pmem_ptr = NULL;
7747 }
7748 }
7749 if (m_inp_mem_ptr)
7750 {
7751 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7752 free (m_inp_mem_ptr);
7753 m_inp_mem_ptr = NULL;
7754 }
7755 if (drv_ctx.ptr_inputbuffer)
7756 {
7757 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7758 free (drv_ctx.ptr_inputbuffer);
7759 drv_ctx.ptr_inputbuffer = NULL;
7760 }
7761#ifdef USE_ION
7762 if (drv_ctx.ip_buf_ion_info) {
7763 DEBUG_PRINT_LOW("\n Free ion context");
7764 free(drv_ctx.ip_buf_ion_info);
7765 drv_ctx.ip_buf_ion_info = NULL;
7766 }
7767#endif
7768}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007769
7770int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007771{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007772 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007773 int rc = 0;
7774 enum v4l2_ports v4l2_port;
7775
7776 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7777 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7778 v4l2_port = OUTPUT_PORT;
7779 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7780 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7781 v4l2_port = CAPTURE_PORT;
7782 } else if (port == OMX_ALL) {
7783 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7784 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7785
7786 if (!rc_input)
7787 return rc_input;
7788 else
7789 return rc_output;
7790 }
7791
7792 if (!streaming[v4l2_port]) {
7793 // already streamed off, warn and move on
7794 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7795 " which is already streamed off", v4l2_port);
7796 return 0;
7797 }
7798
7799 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7800
Shalaj Jain273b3e02012-06-22 19:08:03 -07007801 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7802 if (rc) {
7803 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007804 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007805 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007806 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007807 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007808
7809 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007810}
7811
7812OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7813{
7814 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7815 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007816 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007817 struct v4l2_format fmt;
7818 int ret;
7819 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7820 buffer_prop->actualcount, buffer_prop->buffer_size);
7821 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007822 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007823 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7824 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7825 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7826 fmt.fmt.pix_mp.pixelformat = output_capability;
7827 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7828 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7829 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7830 fmt.fmt.pix_mp.pixelformat = capture_capability;
7831 }else {eRet = OMX_ErrorBadParameter;}
7832 if(eRet==OMX_ErrorNone){
7833 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7834 }
7835 if(ret)
7836 {
7837 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7838 /*TODO: How to handle this case */
7839 eRet = OMX_ErrorInsufficientResources;
7840 return eRet;
7841 }
7842 else
7843 {
7844 buffer_prop->actualcount = bufreq.count;
7845 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007846 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007847 }
7848 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7849 buffer_prop->actualcount, buffer_prop->buffer_size);
7850
7851 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7852 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7853
7854 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7855
Vinay Kalia592e4b42012-12-19 15:55:47 -08007856 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007857 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7858 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007859 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007860
7861 if(ret)
7862 {
7863 /*TODO: How to handle this case */
7864 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7865 eRet = OMX_ErrorInsufficientResources;
7866 }
7867 else
7868 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007869 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007870 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7871 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007872 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7873 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7874 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7875 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7876 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7877 return OMX_ErrorBadParameter;
7878 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007879 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7880 {
7881 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007882 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007883 }
7884 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7885 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007886 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007887 }
7888 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7889 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007890 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7891 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7892 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007893 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007894 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007895 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007896 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007897 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7898 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007899 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7900 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7901 drv_ctx.extradata_info.buffer_size = extra_data_size;
7902 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007903 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7904 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007905 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007906 if (in_reconfig) // BufReq will be set to driver when port is disabled
7907 buffer_prop->buffer_size = buf_size;
7908 else if (buf_size != buffer_prop->buffer_size)
7909 {
7910 buffer_prop->buffer_size = buf_size;
7911 eRet = set_buffer_req(buffer_prop);
7912 }
7913 }
7914 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7915 buffer_prop->actualcount, buffer_prop->buffer_size);
7916 return eRet;
7917}
7918
7919OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7920{
7921 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7922 unsigned buf_size = 0;
7923 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007924 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007925 int ret;
7926 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7927 buffer_prop->actualcount, buffer_prop->buffer_size);
7928 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7929 if (buf_size != buffer_prop->buffer_size)
7930 {
7931 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7932 buffer_prop->buffer_size, buf_size);
7933 eRet = OMX_ErrorBadParameter;
7934 }
7935 else
7936 {
7937 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7938 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007939
7940 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7941 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7942 fmt.fmt.pix_mp.pixelformat = output_capability;
7943 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7944 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7945 fmt.fmt.pix_mp.pixelformat = capture_capability;
7946 } else {eRet = OMX_ErrorBadParameter;}
7947
7948 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7949 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007950 {
7951 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007952 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007953 eRet = OMX_ErrorInsufficientResources;
7954 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007955
7956 bufreq.memory = V4L2_MEMORY_USERPTR;
7957 bufreq.count = buffer_prop->actualcount;
7958 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7959 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7960 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7961 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7962 } else {eRet = OMX_ErrorBadParameter;}
7963
7964 if (eRet==OMX_ErrorNone) {
7965 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7966 }
7967
7968 if (ret)
7969 {
7970 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7971 /*TODO: How to handle this case */
7972 eRet = OMX_ErrorInsufficientResources;
7973 } else if (bufreq.count < buffer_prop->actualcount) {
7974 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7975 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7976 buffer_prop->actualcount, bufreq.count);
7977 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007978 } else {
7979 if (!client_buffers.update_buffer_req()) {
7980 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7981 eRet = OMX_ErrorInsufficientResources;
7982 }
7983 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007984 }
7985 return eRet;
7986}
7987
Shalaj Jain273b3e02012-06-22 19:08:03 -07007988OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7989{
7990 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7991 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7992 ioctl_msg.in = NULL;
7993 ioctl_msg.out = &drv_ctx.video_resolution;
7994 if (/*ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)*/0)
7995 {
7996 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES");
7997 eRet = OMX_ErrorHardware;
7998 }
7999 return eRet;
8000}
8001
8002OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8003{
8004 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8005 if (!portDefn)
8006 {
8007 return OMX_ErrorBadParameter;
8008 }
8009 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8010 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8011 portDefn->nSize = sizeof(portDefn);
8012 portDefn->eDomain = OMX_PortDomainVideo;
8013 if (drv_ctx.frame_rate.fps_denominator > 0)
8014 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8015 drv_ctx.frame_rate.fps_denominator;
8016 else {
8017 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8018 return OMX_ErrorBadParameter;
8019 }
8020 if (0 == portDefn->nPortIndex)
8021 {
8022 portDefn->eDir = OMX_DirInput;
8023 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8024 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8025 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8026 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8027 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8028 portDefn->bEnabled = m_inp_bEnabled;
8029 portDefn->bPopulated = m_inp_bPopulated;
8030 }
8031 else if (1 == portDefn->nPortIndex)
8032 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008033 unsigned int buf_size = 0;
8034 if (!client_buffers.update_buffer_req()) {
8035 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8036 return OMX_ErrorHardware;
8037 }
8038 if (!client_buffers.get_buffer_req(buf_size)) {
8039 DEBUG_PRINT_ERROR("\n update buffer requirements");
8040 return OMX_ErrorHardware;
8041 }
8042 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008043 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008044 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8045 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008046 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8047 portDefn->bEnabled = m_out_bEnabled;
8048 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008049 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8050 DEBUG_PRINT_ERROR("\n Error in getting color format");
8051 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008052 }
8053 }
8054 else
8055 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008056 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008057 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8058 (int)portDefn->nPortIndex);
8059 eRet = OMX_ErrorBadPortIndex;
8060 }
8061 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8062 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8063 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8064 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008065 DEBUG_PRINT_ERROR("update_portdef Width = %d Height = %d Stride = %u"
8066 " SliceHeight = %u \n", portDefn->format.video.nFrameWidth,
8067 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008068 portDefn->format.video.nStride,
8069 portDefn->format.video.nSliceHeight);
8070 return eRet;
8071
8072}
8073
8074OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8075{
8076 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8077 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8078 unsigned i= 0;
8079
8080 if(!m_out_mem_ptr) {
8081 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8082 int nBufHdrSize = 0;
8083 int nPlatformEntrySize = 0;
8084 int nPlatformListSize = 0;
8085 int nPMEMInfoSize = 0;
8086 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8087 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8088 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8089
8090 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8091 drv_ctx.op_buf.actualcount);
8092 nBufHdrSize = drv_ctx.op_buf.actualcount *
8093 sizeof(OMX_BUFFERHEADERTYPE);
8094
8095 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8096 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8097 nPlatformListSize = drv_ctx.op_buf.actualcount *
8098 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8099 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8100 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8101
8102 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8103 sizeof(OMX_BUFFERHEADERTYPE),
8104 nPMEMInfoSize,
8105 nPlatformListSize);
8106 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8107 m_out_bm_count);
8108 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8109 // Alloc mem for platform specific info
8110 char *pPtr=NULL;
8111 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8112 nPMEMInfoSize,1);
8113 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8114 calloc (sizeof(struct vdec_bufferpayload),
8115 drv_ctx.op_buf.actualcount);
8116 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8117 calloc (sizeof (struct vdec_output_frameinfo),
8118 drv_ctx.op_buf.actualcount);
8119#ifdef USE_ION
8120 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8121 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8122#endif
8123
8124 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8125 && drv_ctx.ptr_respbuffer)
8126 {
8127 bufHdr = m_out_mem_ptr;
8128 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8129 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8130 (((char *) m_platform_list) + nPlatformListSize);
8131 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8132 (((char *) m_platform_entry) + nPlatformEntrySize);
8133 pPlatformList = m_platform_list;
8134 pPlatformEntry = m_platform_entry;
8135 pPMEMInfo = m_pmem_info;
8136
8137 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8138
8139 // Settting the entire storage nicely
8140 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8141 m_out_mem_ptr,pPlatformEntry);
8142 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8143 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8144 {
8145 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8146 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8147 // Set the values when we determine the right HxW param
8148 bufHdr->nAllocLen = 0;
8149 bufHdr->nFilledLen = 0;
8150 bufHdr->pAppPrivate = NULL;
8151 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8152 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8153 pPlatformEntry->entry = pPMEMInfo;
8154 // Initialize the Platform List
8155 pPlatformList->nEntries = 1;
8156 pPlatformList->entryList = pPlatformEntry;
8157 // Keep pBuffer NULL till vdec is opened
8158 bufHdr->pBuffer = NULL;
8159 pPMEMInfo->offset = 0;
8160 pPMEMInfo->pmem_fd = 0;
8161 bufHdr->pPlatformPrivate = pPlatformList;
8162 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8163#ifdef USE_ION
8164 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8165#endif
8166 /*Create a mapping between buffers*/
8167 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8168 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8169 &drv_ctx.ptr_outputbuffer[i];
8170 // Move the buffer and buffer header pointers
8171 bufHdr++;
8172 pPMEMInfo++;
8173 pPlatformEntry++;
8174 pPlatformList++;
8175 }
8176 }
8177 else
8178 {
8179 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
8180 m_out_mem_ptr, pPtr);
8181 if(m_out_mem_ptr)
8182 {
8183 free(m_out_mem_ptr);
8184 m_out_mem_ptr = NULL;
8185 }
8186 if(pPtr)
8187 {
8188 free(pPtr);
8189 pPtr = NULL;
8190 }
8191 if(drv_ctx.ptr_outputbuffer)
8192 {
8193 free(drv_ctx.ptr_outputbuffer);
8194 drv_ctx.ptr_outputbuffer = NULL;
8195 }
8196 if(drv_ctx.ptr_respbuffer)
8197 {
8198 free(drv_ctx.ptr_respbuffer);
8199 drv_ctx.ptr_respbuffer = NULL;
8200 }
8201#ifdef USE_ION
8202 if (drv_ctx.op_buf_ion_info) {
8203 DEBUG_PRINT_LOW("\n Free o/p ion context");
8204 free(drv_ctx.op_buf_ion_info);
8205 drv_ctx.op_buf_ion_info = NULL;
8206 }
8207#endif
8208 eRet = OMX_ErrorInsufficientResources;
8209 }
8210 } else {
8211 eRet = OMX_ErrorInsufficientResources;
8212 }
8213 return eRet;
8214}
8215
8216void omx_vdec::complete_pending_buffer_done_cbs()
8217{
8218 unsigned p1;
8219 unsigned p2;
8220 unsigned ident;
8221 omx_cmd_queue tmp_q, pending_bd_q;
8222 pthread_mutex_lock(&m_lock);
8223 // pop all pending GENERATE FDB from ftb queue
8224 while (m_ftb_q.m_size)
8225 {
8226 m_ftb_q.pop_entry(&p1,&p2,&ident);
8227 if(ident == OMX_COMPONENT_GENERATE_FBD)
8228 {
8229 pending_bd_q.insert_entry(p1,p2,ident);
8230 }
8231 else
8232 {
8233 tmp_q.insert_entry(p1,p2,ident);
8234 }
8235 }
8236 //return all non GENERATE FDB to ftb queue
8237 while(tmp_q.m_size)
8238 {
8239 tmp_q.pop_entry(&p1,&p2,&ident);
8240 m_ftb_q.insert_entry(p1,p2,ident);
8241 }
8242 // pop all pending GENERATE EDB from etb queue
8243 while (m_etb_q.m_size)
8244 {
8245 m_etb_q.pop_entry(&p1,&p2,&ident);
8246 if(ident == OMX_COMPONENT_GENERATE_EBD)
8247 {
8248 pending_bd_q.insert_entry(p1,p2,ident);
8249 }
8250 else
8251 {
8252 tmp_q.insert_entry(p1,p2,ident);
8253 }
8254 }
8255 //return all non GENERATE FDB to etb queue
8256 while(tmp_q.m_size)
8257 {
8258 tmp_q.pop_entry(&p1,&p2,&ident);
8259 m_etb_q.insert_entry(p1,p2,ident);
8260 }
8261 pthread_mutex_unlock(&m_lock);
8262 // process all pending buffer dones
8263 while(pending_bd_q.m_size)
8264 {
8265 pending_bd_q.pop_entry(&p1,&p2,&ident);
8266 switch(ident)
8267 {
8268 case OMX_COMPONENT_GENERATE_EBD:
8269 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8270 {
8271 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8272 omx_report_error ();
8273 }
8274 break;
8275
8276 case OMX_COMPONENT_GENERATE_FBD:
8277 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8278 {
8279 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8280 omx_report_error ();
8281 }
8282 break;
8283 }
8284 }
8285}
8286
8287void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8288{
8289 OMX_U32 new_frame_interval = 0;
8290 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
8291 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8292 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8293 {
8294 new_frame_interval = (act_timestamp > prev_ts)?
8295 act_timestamp - prev_ts :
8296 prev_ts - act_timestamp;
8297 if (new_frame_interval < frm_int || frm_int == 0)
8298 {
8299 frm_int = new_frame_interval;
8300 if(frm_int)
8301 {
8302 drv_ctx.frame_rate.fps_numerator = 1e6;
8303 drv_ctx.frame_rate.fps_denominator = frm_int;
8304 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
8305 frm_int, drv_ctx.frame_rate.fps_numerator /
8306 (float)drv_ctx.frame_rate.fps_denominator);
8307 ioctl_msg.in = &drv_ctx.frame_rate;
8308 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
8309 (void*)&ioctl_msg) < */0)
8310 {
8311 DEBUG_PRINT_ERROR("Setting frame rate failed");
8312 }
8313 }
8314 }
8315 }
8316 prev_ts = act_timestamp;
8317}
8318
8319void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8320{
8321 if (rst_prev_ts && VALID_TS(act_timestamp))
8322 {
8323 prev_ts = act_timestamp;
8324 rst_prev_ts = false;
8325 }
8326 else if (VALID_TS(prev_ts))
8327 {
8328 bool codec_cond = (drv_ctx.timestamp_adjust)?
8329 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8330 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8331 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8332 if(frm_int > 0 && codec_cond)
8333 {
8334 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8335 act_timestamp = prev_ts + frm_int;
8336 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8337 prev_ts = act_timestamp;
8338 }
8339 else
8340 set_frame_rate(act_timestamp);
8341 }
8342 else if (frm_int > 0) // In this case the frame rate was set along
8343 { // with the port definition, start ts with 0
8344 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8345 rst_prev_ts = true;
8346 }
8347}
8348
8349void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8350{
8351 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8352 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008353 OMX_U32 frame_rate = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008354 OMX_U32 consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008355 OMX_U32 num_MB_in_frame;
8356 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008357 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008358 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008359 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + p_buf_hdr->nOffset);
8360 if (!drv_ctx.extradata_info.uaddr) {
8361 return;
8362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008363 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008364 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8365 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8366 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008367 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008368 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008369 if (data) {
8370 while((consumed_len < drv_ctx.extradata_info.buffer_size)
8371 && (data->eType != EXTRADATA_NONE)) {
8372 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
8373 DEBUG_PRINT_ERROR("Invalid extra data size");
8374 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008375 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008376 switch(data->eType) {
8377 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008378 struct msm_vidc_interlace_payload *payload;
8379 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008380 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8381 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008382 OMX_U32 mbaff = 0;
8383 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8384 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8385 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8386 else
8387 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8388 if(m_enable_android_native_buffers)
8389 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008390 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008391 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008392 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8393 append_interlace_extradata(p_extra, payload->format);
8394 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8395 }
8396 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008397 case EXTRADATA_FRAME_RATE:
8398 struct msm_vidc_framerate_payload *frame_rate_payload;
8399 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8400 frame_rate = frame_rate_payload->frame_rate;
8401 break;
8402 case EXTRADATA_TIMESTAMP:
8403 struct msm_vidc_ts_payload *time_stamp_payload;
8404 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
8405 break;
8406 case EXTRADATA_NUM_CONCEALED_MB:
8407 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8408 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8409 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8410 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8411 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8412 break;
8413 case EXTRADATA_RECOVERY_POINT_SEI:
8414 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8415 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8416 recovery_sei_flags = recovery_sei_payload->flags;
8417 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8418 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008419 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008420 }
8421 break;
8422 case EXTRADATA_PANSCAN_WINDOW:
8423 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8424 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008425 default:
8426 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008427 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008428 consumed_len += data->nSize;
8429 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008430 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008431 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008432 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008433 append_frame_info_extradata(p_extra,
8434 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
8435 panscan_payload);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008436 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008437unrecognized_extradata:
8438 if(!secure_mode && client_extradata)
8439 append_terminator_extradata(p_extra);
8440 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008441}
8442
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008443OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8444 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008445{
8446 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008447 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008448 if(m_state != OMX_StateLoaded)
8449 {
8450 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8451 return OMX_ErrorIncorrectStateOperation;
8452 }
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008453 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%x] requested[%x] enable[%d], is_internal: %d\n",
8454 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008455
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008456 if (!is_internal) {
8457 if (enable)
8458 client_extradata |= requested_extradata;
8459 else
8460 client_extradata = client_extradata & ~requested_extradata;
8461 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008462
8463 if (enable) {
8464 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8465 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8466 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8467 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8468 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8469 " Quality of interlaced clips might be impacted.\n");
8470 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008471 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8472 {
8473 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8474 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8475 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8476 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8477 }
8478 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8479 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8480 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8481 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8482 }
8483 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8484 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8485 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8486 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8487 }
8488 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8489 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8490 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8491 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8492 }
8493 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8494 {
8495 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8496 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8497 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8498 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8499 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008500 }
8501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008502 return ret;
8503}
8504
8505OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8506{
8507 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8508 OMX_U8 *data_ptr = extra->data, data = 0;
8509 while (byte_count < extra->nDataSize)
8510 {
8511 data = *data_ptr;
8512 while (data)
8513 {
8514 num_MB += (data&0x01);
8515 data >>= 1;
8516 }
8517 data_ptr++;
8518 byte_count++;
8519 }
8520 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8521 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8522 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8523}
8524
8525void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8526{
8527 if (!m_debug_extradata)
8528 return;
8529
8530 DEBUG_PRINT_HIGH(
8531 "============== Extra Data ==============\n"
8532 " Size: %u \n"
8533 " Version: %u \n"
8534 " PortIndex: %u \n"
8535 " Type: %x \n"
8536 " DataSize: %u \n",
8537 extra->nSize, extra->nVersion.nVersion,
8538 extra->nPortIndex, extra->eType, extra->nDataSize);
8539
8540 if (extra->eType == OMX_ExtraDataInterlaceFormat)
8541 {
8542 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8543 DEBUG_PRINT_HIGH(
8544 "------ Interlace Format ------\n"
8545 " Size: %u \n"
8546 " Version: %u \n"
8547 " PortIndex: %u \n"
8548 " Is Interlace Format: %u \n"
8549 " Interlace Formats: %u \n"
8550 "=========== End of Interlace ===========\n",
8551 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8552 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8553 }
8554 else if (extra->eType == OMX_ExtraDataFrameInfo)
8555 {
8556 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8557
8558 DEBUG_PRINT_HIGH(
8559 "-------- Frame Format --------\n"
8560 " Picture Type: %u \n"
8561 " Interlace Type: %u \n"
8562 " Pan Scan Total Frame Num: %u \n"
8563 " Concealed Macro Blocks: %u \n"
8564 " frame rate: %u \n"
8565 " Aspect Ratio X: %u \n"
8566 " Aspect Ratio Y: %u \n",
8567 fminfo->ePicType,
8568 fminfo->interlaceType,
8569 fminfo->panScan.numWindows,
8570 fminfo->nConcealedMacroblocks,
8571 fminfo->nFrameRate,
8572 fminfo->aspectRatio.aspectRatioX,
8573 fminfo->aspectRatio.aspectRatioY);
8574
8575 for (int i = 0; i < fminfo->panScan.numWindows; i++)
8576 {
8577 DEBUG_PRINT_HIGH(
8578 "------------------------------\n"
8579 " Pan Scan Frame Num: %d \n"
8580 " Rectangle x: %d \n"
8581 " Rectangle y: %d \n"
8582 " Rectangle dx: %d \n"
8583 " Rectangle dy: %d \n",
8584 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8585 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8586 }
8587
8588 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8589 }
8590 else if (extra->eType == OMX_ExtraDataNone)
8591 {
8592 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8593 }
8594 else
8595 {
8596 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8597 }
8598}
8599
8600void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8601 OMX_U32 interlaced_format_type)
8602{
8603 OMX_STREAMINTERLACEFORMAT *interlace_format;
8604 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008605 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8606 return;
8607 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008608 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8609 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8610 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8611 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8612 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8613 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8614 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8615 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8616 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8617 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008618 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008619 {
8620 interlace_format->bInterlaceFormat = OMX_FALSE;
8621 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8622 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8623 }
8624 else
8625 {
8626 interlace_format->bInterlaceFormat = OMX_TRUE;
8627 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8628 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8629 }
8630 print_debug_extradata(extra);
8631}
8632
8633
8634void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008635 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
8636 struct msm_vidc_panscan_window_payload *panscan_payload)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008637{
8638 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008639 struct msm_vidc_panscan_window *panscan_window;
8640 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8641 return;
8642 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008643 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8644 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8645 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8646 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8647 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8648 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8649 switch (picture_type)
8650 {
8651 case PICTURE_TYPE_I:
8652 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8653 break;
8654 case PICTURE_TYPE_P:
8655 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8656 break;
8657 case PICTURE_TYPE_B:
8658 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8659 break;
8660 default:
8661 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8662 }
8663 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8664 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8665 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8666 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8667 else
8668 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008669 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008670 frame_info->nConcealedMacroblocks = num_conceal_mb;
8671 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008672 frame_info->panScan.numWindows = 0;
8673 if(panscan_payload) {
8674 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8675 panscan_window = &panscan_payload->wnd[0];
8676 for (int i = 0; i < frame_info->panScan.numWindows; i++)
8677 {
8678 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8679 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8680 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8681 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8682 panscan_window++;
8683 }
8684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008685 print_debug_extradata(extra);
8686}
8687
8688void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8689{
8690 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8691 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8692 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8693 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8694 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8695 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8696 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8697 *portDefn = m_port_def;
8698 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u"
8699 "sliceheight = %u \n",portDefn->format.video.nFrameHeight,
8700 portDefn->format.video.nFrameWidth,
8701 portDefn->format.video.nStride,
8702 portDefn->format.video.nSliceHeight);
8703}
8704
8705void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8706{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008707 if (!client_extradata) {
8708 return;
8709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008710 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8711 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8712 extra->eType = OMX_ExtraDataNone;
8713 extra->nDataSize = 0;
8714 extra->data[0] = 0;
8715
8716 print_debug_extradata(extra);
8717}
8718
8719OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8720{
8721 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8722 if (index >= drv_ctx.ip_buf.actualcount)
8723 {
8724 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8725 return OMX_ErrorInsufficientResources;
8726 }
8727 if (m_desc_buffer_ptr == NULL)
8728 {
8729 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8730 calloc( (sizeof(desc_buffer_hdr)),
8731 drv_ctx.ip_buf.actualcount);
8732 if (m_desc_buffer_ptr == NULL)
8733 {
8734 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8735 return OMX_ErrorInsufficientResources;
8736 }
8737 }
8738
8739 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8740 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8741 {
8742 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8743 return OMX_ErrorInsufficientResources;
8744 }
8745
8746 return eRet;
8747}
8748
8749void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8750{
8751 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries);
8752 if (m_demux_entries < 8192)
8753 {
8754 m_demux_offsets[m_demux_entries++] = address_offset;
8755 }
8756 return;
8757}
8758
8759void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8760{
8761 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8762 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8763 OMX_U32 index = 0;
8764
8765 m_demux_entries = 0;
8766
8767 while (index < bytes_to_parse)
8768 {
8769 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8770 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8771 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8772 (buf[index+2] == 0x01)) )
8773 {
8774 //Found start code, insert address offset
8775 insert_demux_addr_offset(index);
8776 if (buf[index+2] == 0x01) // 3 byte start code
8777 index += 3;
8778 else //4 byte start code
8779 index += 4;
8780 }
8781 else
8782 index++;
8783 }
8784 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries);
8785 return;
8786}
8787
8788OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8789{
8790 //fix this, handle 3 byte start code, vc1 terminator entry
8791 OMX_U8 *p_demux_data = NULL;
8792 OMX_U32 desc_data = 0;
8793 OMX_U32 start_addr = 0;
8794 OMX_U32 nal_size = 0;
8795 OMX_U32 suffix_byte = 0;
8796 OMX_U32 demux_index = 0;
8797 OMX_U32 buffer_index = 0;
8798
8799 if (m_desc_buffer_ptr == NULL)
8800 {
8801 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8802 return OMX_ErrorBadParameter;
8803 }
8804
8805 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8806 if (buffer_index > drv_ctx.ip_buf.actualcount)
8807 {
8808 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index);
8809 return OMX_ErrorBadParameter;
8810 }
8811
8812 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8813
8814 if ( ((OMX_U8*)p_demux_data == NULL) ||
8815 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8816 {
8817 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8818 return OMX_ErrorBadParameter;
8819 }
8820 else
8821 {
8822 for (; demux_index < m_demux_entries; demux_index++)
8823 {
8824 desc_data = 0;
8825 start_addr = m_demux_offsets[demux_index];
8826 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8827 {
8828 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8829 }
8830 else
8831 {
8832 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8833 }
8834 if (demux_index < (m_demux_entries - 1))
8835 {
8836 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8837 }
8838 else
8839 {
8840 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8841 }
8842 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)",
8843 start_addr,
8844 suffix_byte,
8845 nal_size,
8846 demux_index);
8847 desc_data = (start_addr >> 3) << 1;
8848 desc_data |= (start_addr & 7) << 21;
8849 desc_data |= suffix_byte << 24;
8850
8851 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8852 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8853 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8854 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8855
8856 p_demux_data += 16;
8857 }
8858 if (codec_type_parse == CODEC_TYPE_VC1)
8859 {
8860 DEBUG_PRINT_LOW("VC1 terminator entry");
8861 desc_data = 0;
8862 desc_data = 0x82 << 24;
8863 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8864 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8865 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8866 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8867 p_demux_data += 16;
8868 m_demux_entries++;
8869 }
8870 //Add zero word to indicate end of descriptors
8871 memset(p_demux_data, 0, sizeof(OMX_U32));
8872
8873 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8874 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size);
8875 }
8876 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8877 m_demux_entries = 0;
8878 DEBUG_PRINT_LOW("Demux table complete!");
8879 return OMX_ErrorNone;
8880}
8881
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008882OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008883{
8884 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008885 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008886 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008887 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8888 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008889 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008890 delete iDivXDrmDecrypt;
8891 iDivXDrmDecrypt = NULL;
8892 }
8893 }
8894 else {
8895 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008896 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008897 }
8898 return err;
8899}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008900
Vinay Kaliada4f4422013-01-09 10:45:03 -08008901omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8902{
8903 enabled = false;
8904 omx = NULL;
8905 init_members();
8906 ColorFormat = OMX_COLOR_FormatMax;
8907}
8908
8909void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8910{
8911 omx = reinterpret_cast<omx_vdec*>(client);
8912}
8913
8914void omx_vdec::allocate_color_convert_buf::init_members() {
8915 allocated_count = 0;
8916 buffer_size_req = 0;
8917 buffer_alignment_req = 0;
8918 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8919 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8920 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8921 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
8922#ifdef USE_ION
8923 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
8924#endif
8925 for (int i = 0; i < MAX_COUNT;i++)
8926 pmem_fd[i] = -1;
8927}
8928
8929omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
8930 c2d.destroy();
8931}
8932
8933bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8934{
8935 bool status = true;
8936 unsigned int src_size = 0, destination_size = 0;
8937 OMX_COLOR_FORMATTYPE drv_color_format;
8938 if (!omx){
8939 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8940 return false;
8941 }
8942 if (!enabled){
8943 DEBUG_PRINT_ERROR("\n No color conversion required");
8944 return status;
8945 }
8946 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8947 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8948 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8949 return false;
8950 }
8951 c2d.close();
8952 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8953 omx->drv_ctx.video_resolution.frame_width,
8954 NV12_128m,YCbCr420P);
8955 if (status) {
8956 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8957 if (status)
8958 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8959 }
8960 if (status) {
8961 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8962 !destination_size) {
8963 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8964 "driver size %d destination size %d",
8965 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8966 status = false;
8967 c2d.close();
8968 buffer_size_req = 0;
8969 } else {
8970 buffer_size_req = destination_size;
8971 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8972 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8973 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8974 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8975 }
8976 }
8977 return status;
8978}
8979
8980bool omx_vdec::allocate_color_convert_buf::set_color_format(
8981 OMX_COLOR_FORMATTYPE dest_color_format)
8982{
8983 bool status = true;
8984 OMX_COLOR_FORMATTYPE drv_color_format;
8985 if (!omx){
8986 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8987 return false;
8988 }
8989 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8990 drv_color_format = (OMX_COLOR_FORMATTYPE)
8991 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8992 else {
8993 DEBUG_PRINT_ERROR("\n Incorrect color format");
8994 status = false;
8995 }
8996 if (status && (drv_color_format != dest_color_format)) {
8997 DEBUG_PRINT_LOW("Enabling C2D\n");
8998 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8999 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9000 status = false;
9001 } else {
9002 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9003 if (enabled)
9004 c2d.destroy();
9005 enabled = false;
9006 if (!c2d.init()) {
9007 DEBUG_PRINT_ERROR("\n open failed for c2d");
9008 status = false;
9009 } else
9010 enabled = true;
9011 }
9012 } else {
9013 if (enabled)
9014 c2d.destroy();
9015 enabled = false;
9016 }
9017 return status;
9018}
9019
9020OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9021{
9022 if (!omx){
9023 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9024 return NULL;
9025 }
9026 if (!enabled)
9027 return omx->m_out_mem_ptr;
9028 return m_out_mem_ptr_client;
9029}
9030
9031OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9032 (OMX_BUFFERHEADERTYPE *bufadd)
9033{
9034 if (!omx){
9035 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9036 return NULL;
9037 }
9038 if (!enabled)
9039 return bufadd;
9040
9041 unsigned index = 0;
9042 index = bufadd - omx->m_out_mem_ptr;
9043 if (index < omx->drv_ctx.op_buf.actualcount) {
9044 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9045 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9046 bool status;
9047 if (!omx->in_reconfig && !omx->output_flush_progress) {
9048 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9049 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
9050 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9051 if (!status){
9052 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
9053 return NULL;
9054 }
9055 } else
9056 m_out_mem_ptr_client[index].nFilledLen = 0;
9057 return &m_out_mem_ptr_client[index];
9058 }
9059 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9060 return NULL;
9061}
9062
9063OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9064 (OMX_BUFFERHEADERTYPE *bufadd)
9065{
9066 if (!omx){
9067 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9068 return NULL;
9069 }
9070 if (!enabled)
9071 return bufadd;
9072 unsigned index = 0;
9073 index = bufadd - m_out_mem_ptr_client;
9074 if (index < omx->drv_ctx.op_buf.actualcount) {
9075 return &omx->m_out_mem_ptr[index];
9076 }
9077 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9078 return NULL;
9079}
9080bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9081 (unsigned int &buffer_size)
9082{
9083 if (!enabled)
9084 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9085 else
9086 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9087 DEBUG_PRINT_ERROR("\n Get buffer size failed");
9088 return false;
9089 }
9090 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9091 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9092 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9093 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9094 return true;
9095}
9096OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9097 OMX_BUFFERHEADERTYPE *bufhdr) {
9098 unsigned int index = 0;
9099
9100 if (!enabled)
9101 return omx->free_output_buffer(bufhdr);
9102 if (enabled && omx->is_component_secure())
9103 return OMX_ErrorNone;
9104 if (!allocated_count || !bufhdr) {
9105 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9106 return OMX_ErrorBadParameter;
9107 }
9108 index = bufhdr - m_out_mem_ptr_client;
9109 if (index >= omx->drv_ctx.op_buf.actualcount){
9110 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9111 return OMX_ErrorBadParameter;
9112 }
9113 if (pmem_fd[index] > 0) {
9114 munmap(pmem_baseaddress[index], buffer_size_req);
9115 close(pmem_fd[index]);
9116 }
9117 pmem_fd[index] = -1;
9118#ifdef USE_ION
9119 omx->free_ion_memory(&op_buf_ion_info[index]);
9120#endif
9121 m_heap_ptr[index].video_heap_ptr = NULL;
9122 if (allocated_count > 0)
9123 allocated_count--;
9124 else
9125 allocated_count = 0;
9126 if (!allocated_count) {
9127 c2d.close();
9128 init_members();
9129 }
9130 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9131}
9132
9133OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9134 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9135{
9136 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9137 if (!enabled){
9138 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9139 return eRet;
9140 }
9141 if (enabled && omx->is_component_secure()) {
9142 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9143 omx->is_component_secure());
9144 return OMX_ErrorUnsupportedSetting;
9145 }
9146 if (!bufferHdr || bytes > buffer_size_req) {
9147 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
9148 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d",
9149 buffer_size_req,bytes);
9150 return OMX_ErrorBadParameter;
9151 }
9152 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9153 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9154 return OMX_ErrorInsufficientResources;
9155 }
9156 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9157 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9158 port,appData,omx->drv_ctx.op_buf.buffer_size);
9159 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9160 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9161 return eRet;
9162 }
9163 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9164 omx->drv_ctx.op_buf.actualcount) {
9165 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9166 (temp_bufferHdr - omx->m_out_mem_ptr));
9167 return OMX_ErrorUndefined;
9168 }
9169 unsigned int i = allocated_count;
9170#ifdef USE_ION
9171 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9172 buffer_size_req,buffer_alignment_req,
9173 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9174 ION_FLAG_CACHED);
9175 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9176 if (op_buf_ion_info[i].ion_device_fd < 0) {
9177 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9178 return OMX_ErrorInsufficientResources;
9179 }
9180 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9181 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9182
9183 if (pmem_baseaddress[i] == MAP_FAILED) {
9184 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9185 close(pmem_fd[i]);
9186 omx->free_ion_memory(&op_buf_ion_info[i]);
9187 return OMX_ErrorInsufficientResources;
9188 }
9189 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9190 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9191 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9192#endif
9193 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9194 m_pmem_info_client[i].offset = 0;
9195 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9196 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9197 m_platform_list_client[i].nEntries = 1;
9198 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9199 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9200 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9201 m_out_mem_ptr_client[i].nFilledLen = 0;
9202 m_out_mem_ptr_client[i].nFlags = 0;
9203 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9204 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9205 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9206 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9207 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9208 m_out_mem_ptr_client[i].pAppPrivate = appData;
9209 *bufferHdr = &m_out_mem_ptr_client[i];
9210 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9211 allocated_count++;
9212 return eRet;
9213}
9214
9215bool omx_vdec::is_component_secure()
9216{
9217 return secure_mode;
9218}
9219
9220bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9221{
9222 bool status = true;
9223 if (!enabled) {
9224 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9225 dest_color_format = (OMX_COLOR_FORMATTYPE)
9226 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9227 else
9228 status = false;
9229 } else {
9230 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9231 status = false;
9232 } else
9233 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9234 }
9235 return status;
9236}