blob: 1f4e3a59e5754d061a6fd261c6268f8d60781a1c [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
2Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3
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.
11 * Neither the name of Code Aurora nor
12 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>
51
52#ifndef _ANDROID_
53#include <sys/ioctl.h>
54#include <sys/mman.h>
55#endif //_ANDROID_
56
57#ifdef _ANDROID_
58#include <cutils/properties.h>
59#undef USE_EGL_IMAGE_GPU
60#endif
61
62#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
63#include <gralloc_priv.h>
64#endif
65
66#if defined (_ANDROID_ICS_)
67#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070068#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070069#endif
70
71#ifdef _ANDROID_
72#include "DivXDrmDecrypt.h"
73#endif //_ANDROID_
74
75#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
81
82#ifdef INPUT_BUFFER_LOG
83#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
84#define INPUT_BUFFER_FILE_NAME_LEN 30
85FILE *inputBufferFile1;
86char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
87#endif
88#ifdef OUTPUT_BUFFER_LOG
89FILE *outputBufferFile1;
90char outputfilename [] = "/data/output.yuv";
91#endif
92#ifdef OUTPUT_EXTRADATA_LOG
93FILE *outputExtradataFile;
94char ouputextradatafilename [] = "/data/extradata";
95#endif
96
97#define DEFAULT_FPS 30
98#define MAX_INPUT_ERROR DEFAULT_FPS
99#define MAX_SUPPORTED_FPS 120
100
101#define VC1_SP_MP_START_CODE 0xC5000000
102#define VC1_SP_MP_START_CODE_MASK 0xFF000000
103#define VC1_AP_SEQ_START_CODE 0x0F010000
104#define VC1_STRUCT_C_PROFILE_MASK 0xF0
105#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
106#define VC1_SIMPLE_PROFILE 0
107#define VC1_MAIN_PROFILE 1
108#define VC1_ADVANCE_PROFILE 3
109#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
110#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
111#define VC1_STRUCT_C_LEN 4
112#define VC1_STRUCT_C_POS 8
113#define VC1_STRUCT_A_POS 12
114#define VC1_STRUCT_B_POS 24
115#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700116#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700117
118#define MEM_DEVICE "/dev/ion"
119#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
120
121#ifdef _ANDROID_
122 extern "C"{
123 #include<utils/Log.h>
124 }
125#endif//_ANDROID_
126
Vinay Kalia53fa6832012-10-11 17:55:30 -0700127#define SZ_4K 0x1000
128#define SZ_1M 0x100000
129
Shalaj Jain273b3e02012-06-22 19:08:03 -0700130#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
131#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 -0700132#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
133
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800134#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700135void* async_message_thread (void *input)
136{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700137 struct vdec_ioctl_msg ioctl_msg;
138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
141 struct v4l2_buffer v4l2_buf ={0};
142 struct v4l2_event dqevent;
143 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
144 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
145 pfd.fd = omx->drv_ctx.video_driver_fd;
146 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
147 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
148 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
149 while (1)
150 {
151 rc = poll(&pfd, 1, POLL_TIMEOUT);
152 if (!rc) {
153 DEBUG_PRINT_ERROR("Poll timedout\n");
154 break;
155 } else if (rc < 0) {
156 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
157 break;
158 }
159 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
160 struct vdec_msginfo vdec_msg;
161 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
162 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
163 v4l2_buf.length = omx->drv_ctx.num_planes;
164 v4l2_buf.m.planes = plane;
165 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
166 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
167 vdec_msg.status_code=VDEC_S_SUCCESS;
168 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
169 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
170 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
171 vdec_msg.msgdata.output_frame.time_stamp= (v4l2_buf.timestamp.tv_sec * 1000000) +
172 v4l2_buf.timestamp.tv_usec;
173 if (omx->async_message_process(input,&vdec_msg) < 0) {
174 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
175 break;
176 }
177 }
178 }
179 if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
180 struct vdec_msginfo vdec_msg;
181 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
182 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
183 v4l2_buf.length = 1;
184 v4l2_buf.m.planes = plane;
185 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
186 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
187 vdec_msg.status_code=VDEC_S_SUCCESS;
188 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
189 if (omx->async_message_process(input,&vdec_msg) < 0) {
190 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
191 break;
192 }
193 }
194 }
195 if (pfd.revents & POLLPRI){
196 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700197 if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700198 struct vdec_msginfo vdec_msg;
199 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
200 vdec_msg.status_code=VDEC_S_SUCCESS;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700201 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
202 if (omx->async_message_process(input,&vdec_msg) < 0) {
203 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
204 break;
205 }
206 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) {
207 struct vdec_msginfo vdec_msg;
208 vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
209 vdec_msg.status_code=VDEC_S_SUCCESS;
210 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700211 if (omx->async_message_process(input,&vdec_msg) < 0) {
212 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
213 break;
214 }
215 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
216 struct vdec_msginfo vdec_msg;
217 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
218 vdec_msg.status_code=VDEC_S_SUCCESS;
219 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
220 if (omx->async_message_process(input,&vdec_msg) < 0) {
221 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
222 break;
223 }
224 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_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 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
232 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
233 break;
234 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
235 struct vdec_msginfo vdec_msg;
236 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
237 vdec_msg.status_code=VDEC_S_SUCCESS;
238 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
239 if (omx->async_message_process(input,&vdec_msg) < 0) {
240 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
241 break;
242 }
243 } else {
244 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
245 continue;
246 }
247 }
248 }
249 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
250 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700251}
252
253void* message_thread(void *input)
254{
255 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
256 unsigned char id;
257 int n;
258
259 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
260 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
261 while (1)
262 {
263
264 n = read(omx->m_pipe_in, &id, 1);
265
266 if(0 == n)
267 {
268 break;
269 }
270
271 if (1 == n)
272 {
273 omx->process_event_cb(omx, id);
274 }
275 if ((n < 0) && (errno != EINTR))
276 {
277 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
278 break;
279 }
280 }
281 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
282 return 0;
283}
284
285void post_message(omx_vdec *omx, unsigned char id)
286{
287 int ret_value;
288 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
289 ret_value = write(omx->m_pipe_out, &id, 1);
290 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
291}
292
293// omx_cmd_queue destructor
294omx_vdec::omx_cmd_queue::~omx_cmd_queue()
295{
296 // Nothing to do
297}
298
299// omx cmd queue constructor
300omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
301{
302 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
303}
304
305// omx cmd queue insert
306bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
307{
308 bool ret = true;
309 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
310 {
311 m_q[m_write].id = id;
312 m_q[m_write].param1 = p1;
313 m_q[m_write].param2 = p2;
314 m_write++;
315 m_size ++;
316 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
317 {
318 m_write = 0;
319 }
320 }
321 else
322 {
323 ret = false;
324 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
325 }
326 return ret;
327}
328
329// omx cmd queue pop
330bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
331{
332 bool ret = true;
333 if (m_size > 0)
334 {
335 *id = m_q[m_read].id;
336 *p1 = m_q[m_read].param1;
337 *p2 = m_q[m_read].param2;
338 // Move the read pointer ahead
339 ++m_read;
340 --m_size;
341 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
342 {
343 m_read = 0;
344 }
345 }
346 else
347 {
348 ret = false;
349 }
350 return ret;
351}
352
353// Retrieve the first mesg type in the queue
354unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
355{
356 return m_q[m_read].id;
357}
358
359#ifdef _ANDROID_
360omx_vdec::ts_arr_list::ts_arr_list()
361{
362 //initialize timestamps array
363 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
364}
365omx_vdec::ts_arr_list::~ts_arr_list()
366{
367 //free m_ts_arr_list?
368}
369
370bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
371{
372 bool ret = true;
373 bool duplicate_ts = false;
374 int idx = 0;
375
376 //insert at the first available empty location
377 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
378 {
379 if (!m_ts_arr_list[idx].valid)
380 {
381 //found invalid or empty entry, save timestamp
382 m_ts_arr_list[idx].valid = true;
383 m_ts_arr_list[idx].timestamp = ts;
384 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
385 ts, idx);
386 break;
387 }
388 }
389
390 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
391 {
392 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
393 ret = false;
394 }
395 return ret;
396}
397
398bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
399{
400 bool ret = true;
401 int min_idx = -1;
402 OMX_TICKS min_ts = 0;
403 int idx = 0;
404
405 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
406 {
407
408 if (m_ts_arr_list[idx].valid)
409 {
410 //found valid entry, save index
411 if (min_idx < 0)
412 {
413 //first valid entry
414 min_ts = m_ts_arr_list[idx].timestamp;
415 min_idx = idx;
416 }
417 else if (m_ts_arr_list[idx].timestamp < min_ts)
418 {
419 min_ts = m_ts_arr_list[idx].timestamp;
420 min_idx = idx;
421 }
422 }
423
424 }
425
426 if (min_idx < 0)
427 {
428 //no valid entries found
429 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
430 ts = 0;
431 ret = false;
432 }
433 else
434 {
435 ts = m_ts_arr_list[min_idx].timestamp;
436 m_ts_arr_list[min_idx].valid = false;
437 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
438 ts, min_idx);
439 }
440
441 return ret;
442
443}
444
445
446bool omx_vdec::ts_arr_list::reset_ts_list()
447{
448 bool ret = true;
449 int idx = 0;
450
451 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
452 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
453 {
454 m_ts_arr_list[idx].valid = false;
455 }
456 return ret;
457}
458#endif
459
460// factory function executed by the core to create instances
461void *get_omx_component_factory_fn(void)
462{
463 return (new omx_vdec);
464}
465
466#ifdef _ANDROID_
467#ifdef USE_ION
468VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
469 struct ion_handle *handle, int ionMapfd)
470{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700471// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700472}
473#else
474VideoHeap::VideoHeap(int fd, size_t size, void* base)
475{
476 // dup file descriptor, map once, use pmem
477 init(dup(fd), base, size, 0 , MEM_DEVICE);
478}
479#endif
480#endif // _ANDROID_
481/* ======================================================================
482FUNCTION
483 omx_vdec::omx_vdec
484
485DESCRIPTION
486 Constructor
487
488PARAMETERS
489 None
490
491RETURN VALUE
492 None.
493========================================================================== */
494omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
495 m_app_data(NULL),
496 m_inp_mem_ptr(NULL),
497 m_out_mem_ptr(NULL),
498 m_phdr_pmem_ptr(NULL),
499 pending_input_buffers(0),
500 pending_output_buffers(0),
501 m_out_bm_count(0),
502 m_inp_bm_count(0),
503 m_inp_bPopulated(OMX_FALSE),
504 m_out_bPopulated(OMX_FALSE),
505 m_flags(0),
506 m_inp_bEnabled(OMX_TRUE),
507 m_out_bEnabled(OMX_TRUE),
508 m_platform_list(NULL),
509 m_platform_entry(NULL),
510 m_pmem_info(NULL),
511 output_flush_progress (false),
512 input_flush_progress (false),
513 input_use_buffer (false),
514 output_use_buffer (false),
515 arbitrary_bytes (true),
516 psource_frame (NULL),
517 pdest_frame (NULL),
518 m_inp_heap_ptr (NULL),
519 m_heap_inp_bm_count (0),
520 codec_type_parse ((codec_type)0),
521 first_frame_meta (true),
522 frame_count (0),
523 nal_length(0),
524 nal_count (0),
525 look_ahead_nal (false),
526 first_frame(0),
527 first_buffer(NULL),
528 first_frame_size (0),
529 m_error_propogated(false),
530 m_device_file_ptr(NULL),
531 m_vc1_profile((vc1_profile_type)0),
532 prev_ts(LLONG_MAX),
533 rst_prev_ts(true),
534 frm_int(0),
535 m_in_alloc_cnt(0),
536 m_display_id(NULL),
537 ouput_egl_buffers(false),
538 h264_parser(NULL),
539 client_extradata(0),
540 h264_last_au_ts(LLONG_MAX),
541 h264_last_au_flags(0),
542 m_inp_err_count(0),
543#ifdef _ANDROID_
544 m_heap_ptr(NULL),
545 m_enable_android_native_buffers(OMX_FALSE),
546 m_use_android_native_buffers(OMX_FALSE),
547#endif
548 in_reconfig(false),
549 m_use_output_pmem(OMX_FALSE),
550 m_out_mem_region_smi(OMX_FALSE),
551 m_out_pvt_entry_pmem(OMX_FALSE),
552 secure_mode(false)
553#ifdef _ANDROID_
554 ,iDivXDrmDecrypt(NULL)
555#endif
556 ,m_desc_buffer_ptr(NULL)
557 ,streaming({false, false})
558{
559 /* Assumption is that , to begin with , we have all the frames with decoder */
560 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
561#ifdef _ANDROID_
562 char property_value[PROPERTY_VALUE_MAX] = {0};
563 property_get("vidc.dec.debug.perf", property_value, "0");
564 perf_flag = atoi(property_value);
565 if (perf_flag)
566 {
567 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
568 dec_time.start();
569 proc_frms = latency = 0;
570 }
571 property_value[0] = NULL;
572 property_get("vidc.dec.debug.ts", property_value, "0");
573 m_debug_timestamp = atoi(property_value);
574 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
575 if (m_debug_timestamp)
576 {
577 time_stamp_dts.set_timestamp_reorder_mode(true);
578 }
579
580 property_value[0] = NULL;
581 property_get("vidc.dec.debug.concealedmb", property_value, "0");
582 m_debug_concealedmb = atoi(property_value);
583 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
584
585#endif
586 memset(&m_cmp,0,sizeof(m_cmp));
587 memset(&m_cb,0,sizeof(m_cb));
588 memset (&drv_ctx,0,sizeof(drv_ctx));
589 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
590 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700591 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
592 m_demux_entries = 0;
593#ifdef _ANDROID_ICS_
594 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
595#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700596 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700597 drv_ctx.timestamp_adjust = false;
598 drv_ctx.video_driver_fd = -1;
599 m_vendor_config.pData = NULL;
600 pthread_mutex_init(&m_lock, NULL);
601 sem_init(&m_cmd_lock,0,0);
602#ifdef _ANDROID_
603 char extradata_value[PROPERTY_VALUE_MAX] = {0};
604 property_get("vidc.dec.debug.extradata", extradata_value, "0");
605 m_debug_extradata = atoi(extradata_value);
606 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
607#endif
608
609}
610
Vinay Kalia85793762012-06-14 19:12:34 -0700611static const int event_type[] = {
612 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
613 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
614 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700615 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
616 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700617};
618
619static OMX_ERRORTYPE subscribe_to_events(int fd)
620{
621 OMX_ERRORTYPE eRet = OMX_ErrorNone;
622 struct v4l2_event_subscription sub;
623 int array_sz = sizeof(event_type)/sizeof(int);
624 int i,rc;
625 if (fd < 0) {
626 printf("Invalid input: %d\n", fd);
627 return OMX_ErrorBadParameter;
628 }
629
630 for (i = 0; i < array_sz; ++i) {
631 memset(&sub, 0, sizeof(sub));
632 sub.type = event_type[i];
633 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
634 if (rc) {
635 printf("Failed to subscribe event: 0x%x\n", sub.type);
636 break;
637 }
638 }
639 if (i < array_sz) {
640 for (--i; i >=0 ; i--) {
641 memset(&sub, 0, sizeof(sub));
642 sub.type = event_type[i];
643 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
644 if (rc)
645 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
646 }
647 eRet = OMX_ErrorNotImplemented;
648 }
649 return eRet;
650}
651
652
653static OMX_ERRORTYPE unsubscribe_to_events(int fd)
654{
655 OMX_ERRORTYPE eRet = OMX_ErrorNone;
656 struct v4l2_event_subscription sub;
657 int array_sz = sizeof(event_type)/sizeof(int);
658 int i,rc;
659 if (fd < 0) {
660 printf("Invalid input: %d\n", fd);
661 return OMX_ErrorBadParameter;
662 }
663
664 for (i = 0; i < array_sz; ++i) {
665 memset(&sub, 0, sizeof(sub));
666 sub.type = event_type[i];
667 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
668 if (rc) {
669 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
670 break;
671 }
672 }
673 return eRet;
674}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700675
676/* ======================================================================
677FUNCTION
678 omx_vdec::~omx_vdec
679
680DESCRIPTION
681 Destructor
682
683PARAMETERS
684 None
685
686RETURN VALUE
687 None.
688========================================================================== */
689omx_vdec::~omx_vdec()
690{
691 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700692 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700693 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
694 if(m_pipe_in) close(m_pipe_in);
695 if(m_pipe_out) close(m_pipe_out);
696 m_pipe_in = -1;
697 m_pipe_out = -1;
698 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
699 pthread_join(msg_thread_id,NULL);
700 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700701 dec.cmd = V4L2_DEC_CMD_STOP;
702 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
703 {
704 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
705 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700706 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700707 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700708 close(drv_ctx.video_driver_fd);
709 pthread_mutex_destroy(&m_lock);
710 sem_destroy(&m_cmd_lock);
711 if (perf_flag)
712 {
713 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
714 dec_time.end();
715 }
716 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
717}
718
Vinay Kaliafeef7032012-09-25 19:23:33 -0700719int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
720 struct v4l2_requestbuffers bufreq;
721 int rc = 0;
722 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
723 bufreq.memory = V4L2_MEMORY_USERPTR;
724 bufreq.count = 0;
725 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
726 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
727 }
728 return rc;
729}
730
Shalaj Jain273b3e02012-06-22 19:08:03 -0700731/* ======================================================================
732FUNCTION
733 omx_vdec::OMXCntrlProcessMsgCb
734
735DESCRIPTION
736 IL Client callbacks are generated through this routine. The decoder
737 provides the thread context for this routine.
738
739PARAMETERS
740 ctxt -- Context information related to the self.
741 id -- Event identifier. This could be any of the following:
742 1. Command completion event
743 2. Buffer done callback event
744 3. Frame done callback event
745
746RETURN VALUE
747 None.
748
749========================================================================== */
750void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
751{
752 unsigned p1; // Parameter - 1
753 unsigned p2; // Parameter - 2
754 unsigned ident;
755 unsigned qsize=0; // qsize
756 omx_vdec *pThis = (omx_vdec *) ctxt;
757
758 if(!pThis)
759 {
760 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
761 __func__);
762 return;
763 }
764
765 // Protect the shared queue data structure
766 do
767 {
768 /*Read the message id's from the queue*/
769 pthread_mutex_lock(&pThis->m_lock);
770 qsize = pThis->m_cmd_q.m_size;
771 if(qsize)
772 {
773 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
774 }
775
776 if (qsize == 0 && pThis->m_state != OMX_StatePause)
777 {
778 qsize = pThis->m_ftb_q.m_size;
779 if (qsize)
780 {
781 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
782 }
783 }
784
785 if (qsize == 0 && pThis->m_state != OMX_StatePause)
786 {
787 qsize = pThis->m_etb_q.m_size;
788 if (qsize)
789 {
790 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
791 }
792 }
793 pthread_mutex_unlock(&pThis->m_lock);
794
795 /*process message if we have one*/
796 if(qsize > 0)
797 {
798 id = ident;
799 switch (id)
800 {
801 case OMX_COMPONENT_GENERATE_EVENT:
802 if (pThis->m_cb.EventHandler)
803 {
804 switch (p1)
805 {
806 case OMX_CommandStateSet:
807 pThis->m_state = (OMX_STATETYPE) p2;
808 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
809 pThis->m_state);
810 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
811 OMX_EventCmdComplete, p1, p2, NULL);
812 break;
813
814 case OMX_EventError:
815 if(p2 == OMX_StateInvalid)
816 {
817 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
818 pThis->m_state = (OMX_STATETYPE) p2;
819 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
820 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
821 }
822 else if (p2 == OMX_ErrorHardware)
823 {
824 pThis->omx_report_error();
825 }
826 else
827 {
828 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
829 OMX_EventError, p2, NULL, NULL );
830 }
831 break;
832
833 case OMX_CommandPortDisable:
834 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
835 if (BITMASK_PRESENT(&pThis->m_flags,
836 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
837 {
838 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
839 break;
840 }
841 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
842 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700843 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700844 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700845 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
846 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
847 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700848 pThis->in_reconfig = false;
849 if(eRet != OMX_ErrorNone)
850 {
851 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
852 pThis->omx_report_error();
853 break;
854 }
855 }
856 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
857 OMX_EventCmdComplete, p1, p2, NULL );
858 break;
859 case OMX_CommandPortEnable:
860 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
861 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
862 OMX_EventCmdComplete, p1, p2, NULL );
863 break;
864
865 default:
866 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
867 OMX_EventCmdComplete, p1, p2, NULL );
868 break;
869
870 }
871 }
872 else
873 {
874 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
875 }
876 break;
877 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
878 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
879 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
880 {
881 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
882 pThis->omx_report_error ();
883 }
884 break;
885 case OMX_COMPONENT_GENERATE_ETB:
886 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
887 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
888 {
889 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
890 pThis->omx_report_error ();
891 }
892 break;
893
894 case OMX_COMPONENT_GENERATE_FTB:
895 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
896 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
897 {
898 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
899 pThis->omx_report_error ();
900 }
901 break;
902
903 case OMX_COMPONENT_GENERATE_COMMAND:
904 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
905 (OMX_U32)p2,(OMX_PTR)NULL);
906 break;
907
908 case OMX_COMPONENT_GENERATE_EBD:
909
910 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
911 {
912 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
913 pThis->omx_report_error ();
914 }
915 else
916 {
917 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
918 {
919 pThis->m_inp_err_count++;
920 pThis->time_stamp_dts.remove_time_stamp(
921 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
922 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
923 ?true:false);
924 }
925 else
926 {
927 pThis->m_inp_err_count = 0;
928 }
929 if ( pThis->empty_buffer_done(&pThis->m_cmp,
930 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
931 {
932 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
933 pThis->omx_report_error ();
934 }
935 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
936 {
937 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
938 pThis->omx_report_error ();
939 }
940 }
941 break;
942 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
943 {
944 int64_t *timestamp = (int64_t *)p1;
945 if (p1)
946 {
947 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
948 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
949 ?true:false);
950 free(timestamp);
951 }
952 }
953 break;
954 case OMX_COMPONENT_GENERATE_FBD:
955 if (p2 != VDEC_S_SUCCESS)
956 {
957 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
958 pThis->omx_report_error ();
959 }
960 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
961 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
962 {
963 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
964 pThis->omx_report_error ();
965 }
966 break;
967
968 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
969 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
970 if (!pThis->input_flush_progress)
971 {
972 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
973 }
974 else
975 {
976 pThis->execute_input_flush();
977 if (pThis->m_cb.EventHandler)
978 {
979 if (p2 != VDEC_S_SUCCESS)
980 {
981 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
982 pThis->omx_report_error ();
983 }
984 else
985 {
986 /*Check if we need generate event for Flush done*/
987 if(BITMASK_PRESENT(&pThis->m_flags,
988 OMX_COMPONENT_INPUT_FLUSH_PENDING))
989 {
990 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
991 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
992 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
993 OMX_EventCmdComplete,OMX_CommandFlush,
994 OMX_CORE_INPUT_PORT_INDEX,NULL );
995 }
996 if (BITMASK_PRESENT(&pThis->m_flags,
997 OMX_COMPONENT_IDLE_PENDING))
998 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700999 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001000 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1001 pThis->omx_report_error ();
1002 } else {
1003 pThis->streaming[OUTPUT_PORT] = false;
1004 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001005 if (!pThis->output_flush_progress)
1006 {
Vinay Kalia22046272012-09-28 20:16:05 -07001007 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
1008 pThis->post_event (NULL, VDEC_S_SUCCESS,\
1009 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001010 }
1011 }
1012 }
1013 }
1014 else
1015 {
1016 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1017 }
1018 }
1019 break;
1020
1021 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1022 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1023 if (!pThis->output_flush_progress)
1024 {
1025 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1026 }
1027 else
1028 {
1029 pThis->execute_output_flush();
1030 if (pThis->m_cb.EventHandler)
1031 {
1032 if (p2 != VDEC_S_SUCCESS)
1033 {
1034 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1035 pThis->omx_report_error ();
1036 }
1037 else
1038 {
1039 /*Check if we need generate event for Flush done*/
1040 if(BITMASK_PRESENT(&pThis->m_flags,
1041 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1042 {
1043 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1044 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1045 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1046 OMX_EventCmdComplete,OMX_CommandFlush,
1047 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1048 }
1049 if(BITMASK_PRESENT(&pThis->m_flags,
1050 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1051 {
1052 DEBUG_PRINT_LOW("\n Internal flush complete");
1053 BITMASK_CLEAR (&pThis->m_flags,
1054 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1055 if (BITMASK_PRESENT(&pThis->m_flags,
1056 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1057 {
1058 pThis->post_event(OMX_CommandPortDisable,
1059 OMX_CORE_OUTPUT_PORT_INDEX,
1060 OMX_COMPONENT_GENERATE_EVENT);
1061 BITMASK_CLEAR (&pThis->m_flags,
1062 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1063
1064 }
1065 }
1066
1067 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1068 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001069 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001070 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1071 pThis->omx_report_error ();
1072 break;
1073 }
1074 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001075 if (!pThis->input_flush_progress)
1076 {
Vinay Kalia22046272012-09-28 20:16:05 -07001077 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1078 pThis->post_event (NULL, VDEC_S_SUCCESS,\
1079 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001080 }
1081 }
1082 }
1083 }
1084 else
1085 {
1086 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1087 }
1088 }
1089 break;
1090
1091 case OMX_COMPONENT_GENERATE_START_DONE:
1092 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1093
1094 if (pThis->m_cb.EventHandler)
1095 {
1096 if (p2 != VDEC_S_SUCCESS)
1097 {
1098 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1099 pThis->omx_report_error ();
1100 }
1101 else
1102 {
1103 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1104 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1105 {
1106 DEBUG_PRINT_LOW("\n Move to executing");
1107 // Send the callback now
1108 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1109 pThis->m_state = OMX_StateExecuting;
1110 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1111 OMX_EventCmdComplete,OMX_CommandStateSet,
1112 OMX_StateExecuting, NULL);
1113 }
1114 else if (BITMASK_PRESENT(&pThis->m_flags,
1115 OMX_COMPONENT_PAUSE_PENDING))
1116 {
1117 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1118 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1119 {
1120 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1121 pThis->omx_report_error ();
1122 }
1123 }
1124 }
1125 }
1126 else
1127 {
1128 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1129 }
1130 break;
1131
1132 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1133 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1134 if (pThis->m_cb.EventHandler)
1135 {
1136 if (p2 != VDEC_S_SUCCESS)
1137 {
1138 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1139 pThis->omx_report_error ();
1140 }
1141 else
1142 {
1143 pThis->complete_pending_buffer_done_cbs();
1144 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1145 {
1146 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1147 //Send the callback now
1148 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1149 pThis->m_state = OMX_StatePause;
1150 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1151 OMX_EventCmdComplete,OMX_CommandStateSet,
1152 OMX_StatePause, NULL);
1153 }
1154 }
1155 }
1156 else
1157 {
1158 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1159 }
1160
1161 break;
1162
1163 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1164 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1165 if (pThis->m_cb.EventHandler)
1166 {
1167 if (p2 != VDEC_S_SUCCESS)
1168 {
1169 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1170 pThis->omx_report_error ();
1171 }
1172 else
1173 {
1174 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1175 {
1176 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1177 // Send the callback now
1178 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1179 pThis->m_state = OMX_StateExecuting;
1180 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1181 OMX_EventCmdComplete,OMX_CommandStateSet,
1182 OMX_StateExecuting,NULL);
1183 }
1184 }
1185 }
1186 else
1187 {
1188 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1189 }
1190
1191 break;
1192
1193 case OMX_COMPONENT_GENERATE_STOP_DONE:
1194 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1195 if (pThis->m_cb.EventHandler)
1196 {
1197 if (p2 != VDEC_S_SUCCESS)
1198 {
1199 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1200 pThis->omx_report_error ();
1201 }
1202 else
1203 {
1204 pThis->complete_pending_buffer_done_cbs();
1205 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1206 {
1207 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1208 // Send the callback now
1209 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1210 pThis->m_state = OMX_StateIdle;
1211 DEBUG_PRINT_LOW("\n Move to Idle State");
1212 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1213 OMX_EventCmdComplete,OMX_CommandStateSet,
1214 OMX_StateIdle,NULL);
1215 }
1216 }
1217 }
1218 else
1219 {
1220 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1221 }
1222
1223 break;
1224
1225 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1226 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001227 pThis->in_reconfig = true;
1228
1229 if (pThis->m_cb.EventHandler) {
1230 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1231 OMX_EventPortSettingsChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1232 } else {
1233 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1234 }
1235
1236 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001237 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001238 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1239 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1240 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1241 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1242 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1243 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1244 else //unsupported interlace format; raise a error
1245 event = OMX_EventError;
1246 if (pThis->m_cb.EventHandler) {
1247 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1248 event, format, 0, NULL );
1249 } else {
1250 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001251 }
1252 }
1253 break;
1254
1255 case OMX_COMPONENT_GENERATE_EOS_DONE:
1256 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1257 if (pThis->m_cb.EventHandler) {
1258 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1259 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1260 } else {
1261 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1262 }
1263 pThis->prev_ts = LLONG_MAX;
1264 pThis->rst_prev_ts = true;
1265 break;
1266
1267 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1268 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1269 pThis->omx_report_error ();
1270 break;
1271 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1272 {
1273 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1274 if (pThis->m_cb.EventHandler) {
1275 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1276 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1277 } else {
1278 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1279 }
1280 }
1281 default:
1282 break;
1283 }
1284 }
1285 pthread_mutex_lock(&pThis->m_lock);
1286 qsize = pThis->m_cmd_q.m_size;
1287 if (pThis->m_state != OMX_StatePause)
1288 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1289 pthread_mutex_unlock(&pThis->m_lock);
1290 }
1291 while(qsize>0);
1292
1293}
1294
Shalaj Jain273b3e02012-06-22 19:08:03 -07001295/* ======================================================================
1296FUNCTION
1297 omx_vdec::ComponentInit
1298
1299DESCRIPTION
1300 Initialize the component.
1301
1302PARAMETERS
1303 ctxt -- Context information related to the self.
1304 id -- Event identifier. This could be any of the following:
1305 1. Command completion event
1306 2. Buffer done callback event
1307 3. Frame done callback event
1308
1309RETURN VALUE
1310 None.
1311
1312========================================================================== */
1313OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1314{
1315
1316 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1317 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1318 struct v4l2_fmtdesc fdesc;
1319 struct v4l2_format fmt;
1320 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001321 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001322 unsigned int alignment = 0,buffer_size = 0;
1323 int fds[2];
1324 int r,ret=0;
1325 bool codec_ambiguous = false;
1326 OMX_STRING device_name = "/dev/video32";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001327 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1328 struct v4l2_control control;
1329 secure_mode = true;
1330 arbitrary_bytes = false;
1331 role = "OMX.qcom.video.decoder.avc";
1332 }
1333
Shalaj Jain273b3e02012-06-22 19:08:03 -07001334 drv_ctx.video_driver_fd = open("/dev/video32", O_RDWR);
1335
1336 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1337 drv_ctx.video_driver_fd, errno);
1338
1339 if(drv_ctx.video_driver_fd == 0){
1340 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1341 }
1342
1343 if(drv_ctx.video_driver_fd < 0)
1344 {
1345 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1346 return OMX_ErrorInsufficientResources;
1347 }
1348 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1349 drv_ctx.frame_rate.fps_denominator = 1;
1350
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001351 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1352 if(ret < 0) {
1353 close(drv_ctx.video_driver_fd);
1354 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1355 return OMX_ErrorInsufficientResources;
1356 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001357
1358#ifdef INPUT_BUFFER_LOG
1359 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1360#endif
1361#ifdef OUTPUT_BUFFER_LOG
1362 outputBufferFile1 = fopen (outputfilename, "ab");
1363#endif
1364#ifdef OUTPUT_EXTRADATA_LOG
1365 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1366#endif
1367
1368 // Copy the role information which provides the decoder kind
1369 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001370
Shalaj Jain273b3e02012-06-22 19:08:03 -07001371 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1372 OMX_MAX_STRINGNAME_SIZE))
1373 {
1374 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1375 OMX_MAX_STRINGNAME_SIZE);
1376 drv_ctx.timestamp_adjust = true;
1377 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1378 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001379 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001380 /*Initialize Start Code for MPEG4*/
1381 codec_type_parse = CODEC_TYPE_MPEG4;
1382 m_frame_parser.init_start_codes (codec_type_parse);
1383#ifdef INPUT_BUFFER_LOG
1384 strcat(inputfilename, "m4v");
1385#endif
1386 }
1387 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1388 OMX_MAX_STRINGNAME_SIZE))
1389 {
1390 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1391 OMX_MAX_STRINGNAME_SIZE);
1392 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001393 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001394 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1395 /*Initialize Start Code for MPEG2*/
1396 codec_type_parse = CODEC_TYPE_MPEG2;
1397 m_frame_parser.init_start_codes (codec_type_parse);
1398#ifdef INPUT_BUFFER_LOG
1399 strcat(inputfilename, "mpg");
1400#endif
1401 }
1402 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1403 OMX_MAX_STRINGNAME_SIZE))
1404 {
1405 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1406 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1407 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1408 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001409 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001410 codec_type_parse = CODEC_TYPE_H263;
1411 m_frame_parser.init_start_codes (codec_type_parse);
1412#ifdef INPUT_BUFFER_LOG
1413 strcat(inputfilename, "263");
1414#endif
1415 }
1416 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1417 OMX_MAX_STRINGNAME_SIZE))
1418 {
1419 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1420 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1421 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1422 output_capability = V4L2_PIX_FMT_DIVX_311;
1423 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1424 codec_type_parse = CODEC_TYPE_DIVX;
1425 m_frame_parser.init_start_codes (codec_type_parse);
1426
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001427 eRet = createDivxDrmContext();
1428 if (eRet != OMX_ErrorNone) {
1429 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1430 return eRet;
1431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001432 }
1433 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1434 OMX_MAX_STRINGNAME_SIZE))
1435 {
1436 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1437 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1438 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1439 output_capability = V4L2_PIX_FMT_DIVX;
1440 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1441 codec_type_parse = CODEC_TYPE_DIVX;
1442 codec_ambiguous = true;
1443 m_frame_parser.init_start_codes (codec_type_parse);
1444
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001445 eRet = createDivxDrmContext();
1446 if (eRet != OMX_ErrorNone) {
1447 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1448 return eRet;
1449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001450 }
1451 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1452 OMX_MAX_STRINGNAME_SIZE))
1453 {
1454 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1455 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1456 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1457 output_capability = V4L2_PIX_FMT_DIVX;
1458 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1459 codec_type_parse = CODEC_TYPE_DIVX;
1460 codec_ambiguous = true;
1461 m_frame_parser.init_start_codes (codec_type_parse);
1462
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001463 eRet = createDivxDrmContext();
1464 if (eRet != OMX_ErrorNone) {
1465 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1466 return eRet;
1467 }
1468
Shalaj Jain273b3e02012-06-22 19:08:03 -07001469 }
1470 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1471 OMX_MAX_STRINGNAME_SIZE))
1472 {
1473 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1474 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1475 output_capability=V4L2_PIX_FMT_H264;
1476 eCompressionFormat = OMX_VIDEO_CodingAVC;
1477 codec_type_parse = CODEC_TYPE_H264;
1478 m_frame_parser.init_start_codes (codec_type_parse);
1479 m_frame_parser.init_nal_length(nal_length);
1480#ifdef INPUT_BUFFER_LOG
1481 strcat(inputfilename, "264");
1482#endif
1483 }
1484 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1485 OMX_MAX_STRINGNAME_SIZE))
1486 {
1487 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1488 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1489 eCompressionFormat = OMX_VIDEO_CodingWMV;
1490 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001491 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001492 m_frame_parser.init_start_codes (codec_type_parse);
1493#ifdef INPUT_BUFFER_LOG
1494 strcat(inputfilename, "vc1");
1495#endif
1496 }
1497 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1498 OMX_MAX_STRINGNAME_SIZE))
1499 {
1500 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1501 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1502 eCompressionFormat = OMX_VIDEO_CodingWMV;
1503 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001504 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001505 m_frame_parser.init_start_codes (codec_type_parse);
1506#ifdef INPUT_BUFFER_LOG
1507 strcat(inputfilename, "vc1");
1508#endif
1509 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001510 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1511 OMX_MAX_STRINGNAME_SIZE))
1512 {
1513 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1514 output_capability=V4L2_PIX_FMT_VP8;
1515 eCompressionFormat = OMX_VIDEO_CodingVPX;
1516 codec_type_parse = CODEC_TYPE_VP8;
1517 arbitrary_bytes = false;
1518 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001519 else
1520 {
1521 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1522 eRet = OMX_ErrorInvalidComponentName;
1523 }
1524#ifdef INPUT_BUFFER_LOG
1525 inputBufferFile1 = fopen (inputfilename, "ab");
1526#endif
1527 if (eRet == OMX_ErrorNone)
1528 {
1529
1530 drv_ctx.output_format = VDEC_YUV_FORMAT_TILE_4x2;
1531 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001532 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001533 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001534 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1535 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001536 }
1537
1538 struct v4l2_capability cap;
1539 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1540 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001541 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001542 /*TODO: How to handle this case */
1543 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001544 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001545 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1546 cap.bus_info, cap.version, cap.capabilities);
1547 }
1548 ret=0;
1549 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1550 fdesc.index=0;
1551 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001552 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001553 fdesc.pixelformat, fdesc.flags);
1554 fdesc.index++;
1555 }
1556 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1557 fdesc.index=0;
1558 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1559
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001560 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001561 fdesc.pixelformat, fdesc.flags);
1562 fdesc.index++;
1563 }
1564
1565 drv_ctx.video_resolution.frame_height=drv_ctx.video_resolution.scan_lines=240;
1566 drv_ctx.video_resolution.frame_width=drv_ctx.video_resolution.stride=320;
1567 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1568 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1569 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1570 fmt.fmt.pix_mp.pixelformat = output_capability;
1571 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1572 if (ret) {
1573 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001574 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001575 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001576 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001577 if (codec_ambiguous) {
1578 if (output_capability == V4L2_PIX_FMT_DIVX) {
1579 struct v4l2_control divx_ctrl;
1580
1581 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001582 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001583 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001584 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001585 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001586 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001587 }
1588
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001589 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001590 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001591 if (ret) {
1592 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1593 }
1594 } else {
1595 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1596 }
1597 }
1598
1599 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1600 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1601 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001602 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001603 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1604 if (ret) {
1605 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001606 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001607 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001608 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001609 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001610 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1611 control.value = 1;
1612 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1613 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1614 if (ret) {
1615 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1616 close(drv_ctx.video_driver_fd);
1617 return OMX_ErrorInsufficientResources;
1618 }
1619 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001620
1621 /*Get the Buffer requirements for input and output ports*/
1622 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1623 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001624 if (secure_mode) {
1625 drv_ctx.op_buf.alignment=SZ_1M;
1626 drv_ctx.ip_buf.alignment=SZ_1M;
1627 } else {
1628 drv_ctx.op_buf.alignment=SZ_4K;
1629 drv_ctx.ip_buf.alignment=SZ_4K;
1630 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001631 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1632 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001633 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1634 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1635 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1636 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637 drv_ctx.idr_only_decoding = 0;
1638
1639 m_state = OMX_StateLoaded;
1640 eRet=get_buffer_req(&drv_ctx.ip_buf);
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001641 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001642#ifdef DEFAULT_EXTRADATA
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08001643 if (eRet == OMX_ErrorNone && !secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08001644 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645#endif
1646 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1647 {
1648 if (m_frame_parser.mutils == NULL)
1649 {
1650 m_frame_parser.mutils = new H264_Utils();
1651
1652 if (m_frame_parser.mutils == NULL)
1653 {
1654 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1655 eRet = OMX_ErrorInsufficientResources;
1656 }
1657 else
1658 {
1659 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1660 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1661 h264_scratch.nFilledLen = 0;
1662 h264_scratch.nOffset = 0;
1663
1664 if (h264_scratch.pBuffer == NULL)
1665 {
1666 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1667 return OMX_ErrorInsufficientResources;
1668 }
1669 m_frame_parser.mutils->initialize_frame_checking_environment();
1670 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1671 }
1672 }
1673
1674 h264_parser = new h264_stream_parser();
1675 if (!h264_parser)
1676 {
1677 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1678 eRet = OMX_ErrorInsufficientResources;
1679 }
1680 }
1681
1682 if(pipe(fds))
1683 {
1684 DEBUG_PRINT_ERROR("pipe creation failed\n");
1685 eRet = OMX_ErrorInsufficientResources;
1686 }
1687 else
1688 {
1689 int temp1[2];
1690 if(fds[0] == 0 || fds[1] == 0)
1691 {
1692 if (pipe (temp1))
1693 {
1694 DEBUG_PRINT_ERROR("pipe creation failed\n");
1695 return OMX_ErrorInsufficientResources;
1696 }
1697 //close (fds[0]);
1698 //close (fds[1]);
1699 fds[0] = temp1 [0];
1700 fds[1] = temp1 [1];
1701 }
1702 m_pipe_in = fds[0];
1703 m_pipe_out = fds[1];
1704 r = pthread_create(&msg_thread_id,0,message_thread,this);
1705
1706 if(r < 0)
1707 {
1708 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1709 eRet = OMX_ErrorInsufficientResources;
1710 }
1711 }
1712 }
1713
1714 if (eRet != OMX_ErrorNone)
1715 {
1716 DEBUG_PRINT_ERROR("\n Component Init Failed");
1717 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1718 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1719 NULL);
1720 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1721 close (drv_ctx.video_driver_fd);
1722 drv_ctx.video_driver_fd = -1;
1723 }
1724 else
1725 {
1726 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1727 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001728 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1729 return eRet;
1730}
1731
1732/* ======================================================================
1733FUNCTION
1734 omx_vdec::GetComponentVersion
1735
1736DESCRIPTION
1737 Returns the component version.
1738
1739PARAMETERS
1740 TBD.
1741
1742RETURN VALUE
1743 OMX_ErrorNone.
1744
1745========================================================================== */
1746OMX_ERRORTYPE omx_vdec::get_component_version
1747 (
1748 OMX_IN OMX_HANDLETYPE hComp,
1749 OMX_OUT OMX_STRING componentName,
1750 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1751 OMX_OUT OMX_VERSIONTYPE* specVersion,
1752 OMX_OUT OMX_UUIDTYPE* componentUUID
1753 )
1754{
1755 if(m_state == OMX_StateInvalid)
1756 {
1757 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1758 return OMX_ErrorInvalidState;
1759 }
1760 /* TBD -- Return the proper version */
1761 if (specVersion)
1762 {
1763 specVersion->nVersion = OMX_SPEC_VERSION;
1764 }
1765 return OMX_ErrorNone;
1766}
1767/* ======================================================================
1768FUNCTION
1769 omx_vdec::SendCommand
1770
1771DESCRIPTION
1772 Returns zero if all the buffers released..
1773
1774PARAMETERS
1775 None.
1776
1777RETURN VALUE
1778 true/false
1779
1780========================================================================== */
1781OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1782 OMX_IN OMX_COMMANDTYPE cmd,
1783 OMX_IN OMX_U32 param1,
1784 OMX_IN OMX_PTR cmdData
1785 )
1786{
1787 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1788 if(m_state == OMX_StateInvalid)
1789 {
1790 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1791 return OMX_ErrorInvalidState;
1792 }
1793 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1794 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1795 {
1796 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1797 "to invalid port: %d", param1);
1798 return OMX_ErrorBadPortIndex;
1799 }
1800 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1801 sem_wait(&m_cmd_lock);
1802 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1803 return OMX_ErrorNone;
1804}
1805
1806/* ======================================================================
1807FUNCTION
1808 omx_vdec::SendCommand
1809
1810DESCRIPTION
1811 Returns zero if all the buffers released..
1812
1813PARAMETERS
1814 None.
1815
1816RETURN VALUE
1817 true/false
1818
1819========================================================================== */
1820OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1821 OMX_IN OMX_COMMANDTYPE cmd,
1822 OMX_IN OMX_U32 param1,
1823 OMX_IN OMX_PTR cmdData
1824 )
1825{
1826 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1827 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1828 int bFlag = 1,sem_posted = 0,ret=0;
1829
1830 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1831 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1832 m_state, eState);
1833
1834 if(cmd == OMX_CommandStateSet)
1835 {
1836 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1837 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1838 /***************************/
1839 /* Current State is Loaded */
1840 /***************************/
1841 if(m_state == OMX_StateLoaded)
1842 {
1843 if(eState == OMX_StateIdle)
1844 {
1845 //if all buffers are allocated or all ports disabled
1846 if(allocate_done() ||
1847 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1848 {
1849 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1850 }
1851 else
1852 {
1853 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1854 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1855 // Skip the event notification
1856 bFlag = 0;
1857 }
1858 }
1859 /* Requesting transition from Loaded to Loaded */
1860 else if(eState == OMX_StateLoaded)
1861 {
1862 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1863 post_event(OMX_EventError,OMX_ErrorSameState,\
1864 OMX_COMPONENT_GENERATE_EVENT);
1865 eRet = OMX_ErrorSameState;
1866 }
1867 /* Requesting transition from Loaded to WaitForResources */
1868 else if(eState == OMX_StateWaitForResources)
1869 {
1870 /* Since error is None , we will post an event
1871 at the end of this function definition */
1872 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1873 }
1874 /* Requesting transition from Loaded to Executing */
1875 else if(eState == OMX_StateExecuting)
1876 {
1877 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1878 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1879 OMX_COMPONENT_GENERATE_EVENT);
1880 eRet = OMX_ErrorIncorrectStateTransition;
1881 }
1882 /* Requesting transition from Loaded to Pause */
1883 else if(eState == OMX_StatePause)
1884 {
1885 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1886 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1887 OMX_COMPONENT_GENERATE_EVENT);
1888 eRet = OMX_ErrorIncorrectStateTransition;
1889 }
1890 /* Requesting transition from Loaded to Invalid */
1891 else if(eState == OMX_StateInvalid)
1892 {
1893 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1894 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1895 eRet = OMX_ErrorInvalidState;
1896 }
1897 else
1898 {
1899 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1900 eState);
1901 eRet = OMX_ErrorBadParameter;
1902 }
1903 }
1904
1905 /***************************/
1906 /* Current State is IDLE */
1907 /***************************/
1908 else if(m_state == OMX_StateIdle)
1909 {
1910 if(eState == OMX_StateLoaded)
1911 {
1912 if(release_done())
1913 {
1914 /*
1915 Since error is None , we will post an event at the end
1916 of this function definition
1917 */
1918 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1919 }
1920 else
1921 {
1922 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1923 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1924 // Skip the event notification
1925 bFlag = 0;
1926 }
1927 }
1928 /* Requesting transition from Idle to Executing */
1929 else if(eState == OMX_StateExecuting)
1930 {
1931 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1932 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1933 bFlag = 1;
1934 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1935 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001936 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001937 }
1938 /* Requesting transition from Idle to Idle */
1939 else if(eState == OMX_StateIdle)
1940 {
1941 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1942 post_event(OMX_EventError,OMX_ErrorSameState,\
1943 OMX_COMPONENT_GENERATE_EVENT);
1944 eRet = OMX_ErrorSameState;
1945 }
1946 /* Requesting transition from Idle to WaitForResources */
1947 else if(eState == OMX_StateWaitForResources)
1948 {
1949 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1950 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1951 OMX_COMPONENT_GENERATE_EVENT);
1952 eRet = OMX_ErrorIncorrectStateTransition;
1953 }
1954 /* Requesting transition from Idle to Pause */
1955 else if(eState == OMX_StatePause)
1956 {
1957 /*To pause the Video core we need to start the driver*/
1958 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1959 NULL) < */0)
1960 {
1961 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1962 omx_report_error ();
1963 eRet = OMX_ErrorHardware;
1964 }
1965 else
1966 {
1967 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1968 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1969 bFlag = 0;
1970 }
1971 }
1972 /* Requesting transition from Idle to Invalid */
1973 else if(eState == OMX_StateInvalid)
1974 {
1975 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1976 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1977 eRet = OMX_ErrorInvalidState;
1978 }
1979 else
1980 {
1981 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1982 eRet = OMX_ErrorBadParameter;
1983 }
1984 }
1985
1986 /******************************/
1987 /* Current State is Executing */
1988 /******************************/
1989 else if(m_state == OMX_StateExecuting)
1990 {
1991 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1992 /* Requesting transition from Executing to Idle */
1993 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07001994 {
1995 /* Since error is None , we will post an event
1996 at the end of this function definition
1997 */
1998 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07001999 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002000 if(!sem_posted)
2001 {
2002 sem_posted = 1;
2003 sem_post (&m_cmd_lock);
2004 execute_omx_flush(OMX_ALL);
2005 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002006 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002007 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002008 /* Requesting transition from Executing to Paused */
2009 else if(eState == OMX_StatePause)
2010 {
2011 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
2012 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
2013 NULL) < */0)
2014 {
2015 DEBUG_PRINT_ERROR("\n Error In Pause State");
2016 post_event(OMX_EventError,OMX_ErrorHardware,\
2017 OMX_COMPONENT_GENERATE_EVENT);
2018 eRet = OMX_ErrorHardware;
2019 }
2020 else
2021 {
2022 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2023 DEBUG_PRINT_LOW("send_command_proxy(): Executing-->Pause\n");
2024 bFlag = 0;
2025 }
2026 }
2027 /* Requesting transition from Executing to Loaded */
2028 else if(eState == OMX_StateLoaded)
2029 {
2030 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2031 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2032 OMX_COMPONENT_GENERATE_EVENT);
2033 eRet = OMX_ErrorIncorrectStateTransition;
2034 }
2035 /* Requesting transition from Executing to WaitForResources */
2036 else if(eState == OMX_StateWaitForResources)
2037 {
2038 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2039 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2040 OMX_COMPONENT_GENERATE_EVENT);
2041 eRet = OMX_ErrorIncorrectStateTransition;
2042 }
2043 /* Requesting transition from Executing to Executing */
2044 else if(eState == OMX_StateExecuting)
2045 {
2046 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2047 post_event(OMX_EventError,OMX_ErrorSameState,\
2048 OMX_COMPONENT_GENERATE_EVENT);
2049 eRet = OMX_ErrorSameState;
2050 }
2051 /* Requesting transition from Executing to Invalid */
2052 else if(eState == OMX_StateInvalid)
2053 {
2054 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2055 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2056 eRet = OMX_ErrorInvalidState;
2057 }
2058 else
2059 {
2060 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2061 eRet = OMX_ErrorBadParameter;
2062 }
2063 }
2064 /***************************/
2065 /* Current State is Pause */
2066 /***************************/
2067 else if(m_state == OMX_StatePause)
2068 {
2069 /* Requesting transition from Pause to Executing */
2070 if(eState == OMX_StateExecuting)
2071 {
2072 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
2073 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
2074 NULL) < */0)
2075 {
2076 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed");
2077 post_event(OMX_EventError,OMX_ErrorHardware,\
2078 OMX_COMPONENT_GENERATE_EVENT);
2079 eRet = OMX_ErrorHardware;
2080 }
2081 else
2082 {
2083 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
2084 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2085 post_event (NULL,VDEC_S_SUCCESS,\
2086 OMX_COMPONENT_GENERATE_RESUME_DONE);
2087 bFlag = 0;
2088 }
2089 }
2090 /* Requesting transition from Pause to Idle */
2091 else if(eState == OMX_StateIdle)
2092 {
2093 /* Since error is None , we will post an event
2094 at the end of this function definition */
2095 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2096 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2097 if(!sem_posted)
2098 {
2099 sem_posted = 1;
2100 sem_post (&m_cmd_lock);
2101 execute_omx_flush(OMX_ALL);
2102 }
2103 bFlag = 0;
2104 }
2105 /* Requesting transition from Pause to loaded */
2106 else if(eState == OMX_StateLoaded)
2107 {
2108 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2109 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2110 OMX_COMPONENT_GENERATE_EVENT);
2111 eRet = OMX_ErrorIncorrectStateTransition;
2112 }
2113 /* Requesting transition from Pause to WaitForResources */
2114 else if(eState == OMX_StateWaitForResources)
2115 {
2116 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2117 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2118 OMX_COMPONENT_GENERATE_EVENT);
2119 eRet = OMX_ErrorIncorrectStateTransition;
2120 }
2121 /* Requesting transition from Pause to Pause */
2122 else if(eState == OMX_StatePause)
2123 {
2124 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2125 post_event(OMX_EventError,OMX_ErrorSameState,\
2126 OMX_COMPONENT_GENERATE_EVENT);
2127 eRet = OMX_ErrorSameState;
2128 }
2129 /* Requesting transition from Pause to Invalid */
2130 else if(eState == OMX_StateInvalid)
2131 {
2132 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2133 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2134 eRet = OMX_ErrorInvalidState;
2135 }
2136 else
2137 {
2138 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2139 eRet = OMX_ErrorBadParameter;
2140 }
2141 }
2142 /***************************/
2143 /* Current State is WaitForResources */
2144 /***************************/
2145 else if(m_state == OMX_StateWaitForResources)
2146 {
2147 /* Requesting transition from WaitForResources to Loaded */
2148 if(eState == OMX_StateLoaded)
2149 {
2150 /* Since error is None , we will post an event
2151 at the end of this function definition */
2152 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2153 }
2154 /* Requesting transition from WaitForResources to WaitForResources */
2155 else if (eState == OMX_StateWaitForResources)
2156 {
2157 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2158 post_event(OMX_EventError,OMX_ErrorSameState,
2159 OMX_COMPONENT_GENERATE_EVENT);
2160 eRet = OMX_ErrorSameState;
2161 }
2162 /* Requesting transition from WaitForResources to Executing */
2163 else if(eState == OMX_StateExecuting)
2164 {
2165 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2166 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2167 OMX_COMPONENT_GENERATE_EVENT);
2168 eRet = OMX_ErrorIncorrectStateTransition;
2169 }
2170 /* Requesting transition from WaitForResources to Pause */
2171 else if(eState == OMX_StatePause)
2172 {
2173 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2174 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2175 OMX_COMPONENT_GENERATE_EVENT);
2176 eRet = OMX_ErrorIncorrectStateTransition;
2177 }
2178 /* Requesting transition from WaitForResources to Invalid */
2179 else if(eState == OMX_StateInvalid)
2180 {
2181 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2182 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2183 eRet = OMX_ErrorInvalidState;
2184 }
2185 /* Requesting transition from WaitForResources to Loaded -
2186 is NOT tested by Khronos TS */
2187
2188 }
2189 else
2190 {
2191 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2192 eRet = OMX_ErrorBadParameter;
2193 }
2194 }
2195 /********************************/
2196 /* Current State is Invalid */
2197 /*******************************/
2198 else if(m_state == OMX_StateInvalid)
2199 {
2200 /* State Transition from Inavlid to any state */
2201 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2202 || OMX_StateIdle || OMX_StateExecuting
2203 || OMX_StatePause || OMX_StateInvalid))
2204 {
2205 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2206 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2207 OMX_COMPONENT_GENERATE_EVENT);
2208 eRet = OMX_ErrorInvalidState;
2209 }
2210 }
2211 else if (cmd == OMX_CommandFlush)
2212 {
2213 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2214 "with param1: %d", param1);
2215 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2216 {
2217 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2218 }
2219 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2220 {
2221 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2222 }
2223 if (!sem_posted){
2224 sem_posted = 1;
2225 DEBUG_PRINT_LOW("\n Set the Semaphore");
2226 sem_post (&m_cmd_lock);
2227 execute_omx_flush(param1);
2228 }
2229 bFlag = 0;
2230 }
2231 else if ( cmd == OMX_CommandPortEnable)
2232 {
2233 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2234 "with param1: %d", param1);
2235 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2236 {
2237 m_inp_bEnabled = OMX_TRUE;
2238
2239 if( (m_state == OMX_StateLoaded &&
2240 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2241 || allocate_input_done())
2242 {
2243 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2244 OMX_COMPONENT_GENERATE_EVENT);
2245 }
2246 else
2247 {
2248 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2249 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2250 // Skip the event notification
2251 bFlag = 0;
2252 }
2253 }
2254 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2255 {
2256 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2257 m_out_bEnabled = OMX_TRUE;
2258
2259 if( (m_state == OMX_StateLoaded &&
2260 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2261 || (allocate_output_done()))
2262 {
2263 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2264 OMX_COMPONENT_GENERATE_EVENT);
2265
2266 }
2267 else
2268 {
2269 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2270 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2271 // Skip the event notification
2272 bFlag = 0;
2273 }
2274 }
2275 }
2276 else if (cmd == OMX_CommandPortDisable)
2277 {
2278 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2279 "with param1: %d", param1);
2280 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2281 {
2282 m_inp_bEnabled = OMX_FALSE;
2283 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2284 && release_input_done())
2285 {
2286 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2287 OMX_COMPONENT_GENERATE_EVENT);
2288 }
2289 else
2290 {
2291 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2292 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2293 {
2294 if(!sem_posted)
2295 {
2296 sem_posted = 1;
2297 sem_post (&m_cmd_lock);
2298 }
2299 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2300 }
2301
2302 // Skip the event notification
2303 bFlag = 0;
2304 }
2305 }
2306 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2307 {
2308 m_out_bEnabled = OMX_FALSE;
2309 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2310 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2311 && release_output_done())
2312 {
2313 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2314 OMX_COMPONENT_GENERATE_EVENT);
2315 }
2316 else
2317 {
2318 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2319 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2320 {
2321 if (!sem_posted)
2322 {
2323 sem_posted = 1;
2324 sem_post (&m_cmd_lock);
2325 }
2326 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2327 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2328 }
2329 // Skip the event notification
2330 bFlag = 0;
2331
2332 }
2333 }
2334 }
2335 else
2336 {
2337 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2338 eRet = OMX_ErrorNotImplemented;
2339 }
2340 if(eRet == OMX_ErrorNone && bFlag)
2341 {
2342 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2343 }
2344 if(!sem_posted)
2345 {
2346 sem_post(&m_cmd_lock);
2347 }
2348
2349 return eRet;
2350}
2351
2352/* ======================================================================
2353FUNCTION
2354 omx_vdec::ExecuteOmxFlush
2355
2356DESCRIPTION
2357 Executes the OMX flush.
2358
2359PARAMETERS
2360 flushtype - input flush(1)/output flush(0)/ both.
2361
2362RETURN VALUE
2363 true/false
2364
2365========================================================================== */
2366bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2367{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002368 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002369 struct v4l2_plane plane;
2370 struct v4l2_buffer v4l2_buf ={0};
2371 struct v4l2_decoder_cmd dec;
2372 DEBUG_PRINT_LOW("in %s", __func__);
2373 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002374 switch (flushType)
2375 {
2376 case OMX_CORE_INPUT_PORT_INDEX:
2377 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002378 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002379 break;
2380 case OMX_CORE_OUTPUT_PORT_INDEX:
2381 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002382 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002383 break;
2384 default:
2385 input_flush_progress = true;
2386 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002387 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2388 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002389 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002390
2391 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002392 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002393 DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002394 bRet = false;
2395 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002396
Shalaj Jain273b3e02012-06-22 19:08:03 -07002397 return bRet;
2398}
2399/*=========================================================================
2400FUNCTION : execute_output_flush
2401
2402DESCRIPTION
2403 Executes the OMX flush at OUTPUT PORT.
2404
2405PARAMETERS
2406 None.
2407
2408RETURN VALUE
2409 true/false
2410==========================================================================*/
2411bool omx_vdec::execute_output_flush()
2412{
2413 unsigned p1 = 0; // Parameter - 1
2414 unsigned p2 = 0; // Parameter - 2
2415 unsigned ident = 0;
2416 bool bRet = true;
2417
2418 /*Generate FBD for all Buffers in the FTBq*/
2419 pthread_mutex_lock(&m_lock);
2420 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2421 while (m_ftb_q.m_size)
2422 {
2423 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2424 m_ftb_q.m_size,pending_output_buffers);
2425 m_ftb_q.pop_entry(&p1,&p2,&ident);
2426 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2427 if(ident == OMX_COMPONENT_GENERATE_FTB )
2428 {
2429 pending_output_buffers++;
2430 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2431 }
2432 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2433 {
2434 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2435 }
2436 }
2437 pthread_mutex_unlock(&m_lock);
2438 output_flush_progress = false;
2439
2440 if (arbitrary_bytes)
2441 {
2442 prev_ts = LLONG_MAX;
2443 rst_prev_ts = true;
2444 }
2445 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2446 return bRet;
2447}
2448/*=========================================================================
2449FUNCTION : execute_input_flush
2450
2451DESCRIPTION
2452 Executes the OMX flush at INPUT PORT.
2453
2454PARAMETERS
2455 None.
2456
2457RETURN VALUE
2458 true/false
2459==========================================================================*/
2460bool omx_vdec::execute_input_flush()
2461{
2462 unsigned i =0;
2463 unsigned p1 = 0; // Parameter - 1
2464 unsigned p2 = 0; // Parameter - 2
2465 unsigned ident = 0;
2466 bool bRet = true;
2467
2468 /*Generate EBD for all Buffers in the ETBq*/
2469 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2470
2471 pthread_mutex_lock(&m_lock);
2472 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2473 while (m_etb_q.m_size)
2474 {
2475 m_etb_q.pop_entry(&p1,&p2,&ident);
2476
2477 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2478 {
2479 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2480 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2481 }
2482 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2483 {
2484 pending_input_buffers++;
2485 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2486 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2487 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2488 }
2489 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2490 {
2491 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2492 (OMX_BUFFERHEADERTYPE *)p1);
2493 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2494 }
2495 }
2496 time_stamp_dts.flush_timestamp();
2497 /*Check if Heap Buffers are to be flushed*/
2498 if (arbitrary_bytes)
2499 {
2500 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2501 h264_scratch.nFilledLen = 0;
2502 nal_count = 0;
2503 look_ahead_nal = false;
2504 frame_count = 0;
2505 h264_last_au_ts = LLONG_MAX;
2506 h264_last_au_flags = 0;
2507 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2508 m_demux_entries = 0;
2509 DEBUG_PRINT_LOW("\n Initialize parser");
2510 if (m_frame_parser.mutils)
2511 {
2512 m_frame_parser.mutils->initialize_frame_checking_environment();
2513 }
2514
2515 while (m_input_pending_q.m_size)
2516 {
2517 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2518 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2519 }
2520
2521 if (psource_frame)
2522 {
2523 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2524 psource_frame = NULL;
2525 }
2526
2527 if (pdest_frame)
2528 {
2529 pdest_frame->nFilledLen = 0;
2530 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
2531 pdest_frame = NULL;
2532 }
2533 m_frame_parser.flush();
2534 }
2535 pthread_mutex_unlock(&m_lock);
2536 input_flush_progress = false;
2537 if (!arbitrary_bytes)
2538 {
2539 prev_ts = LLONG_MAX;
2540 rst_prev_ts = true;
2541 }
2542#ifdef _ANDROID_
2543 if (m_debug_timestamp)
2544 {
2545 m_timestamp_list.reset_ts_list();
2546 }
2547#endif
2548 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2549 return bRet;
2550}
2551
2552
2553/* ======================================================================
2554FUNCTION
2555 omx_vdec::SendCommandEvent
2556
2557DESCRIPTION
2558 Send the event to decoder pipe. This is needed to generate the callbacks
2559 in decoder thread context.
2560
2561PARAMETERS
2562 None.
2563
2564RETURN VALUE
2565 true/false
2566
2567========================================================================== */
2568bool omx_vdec::post_event(unsigned int p1,
2569 unsigned int p2,
2570 unsigned int id)
2571{
2572 bool bRet = false;
2573
2574
2575 pthread_mutex_lock(&m_lock);
2576
2577 if (id == OMX_COMPONENT_GENERATE_FTB ||
2578 id == OMX_COMPONENT_GENERATE_FBD)
2579 {
2580 m_ftb_q.insert_entry(p1,p2,id);
2581 }
2582 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2583 id == OMX_COMPONENT_GENERATE_EBD ||
2584 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2585 {
2586 m_etb_q.insert_entry(p1,p2,id);
2587 }
2588 else
2589 {
2590 m_cmd_q.insert_entry(p1,p2,id);
2591 }
2592
2593 bRet = true;
2594 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2595 post_message(this, id);
2596
2597 pthread_mutex_unlock(&m_lock);
2598
2599 return bRet;
2600}
2601
2602OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2603{
2604 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2605 if(!profileLevelType)
2606 return OMX_ErrorBadParameter;
2607
2608 if(profileLevelType->nPortIndex == 0) {
2609 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2610 {
2611 if (profileLevelType->nProfileIndex == 0)
2612 {
2613 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2614 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2615
2616 }
2617 else if (profileLevelType->nProfileIndex == 1)
2618 {
2619 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2620 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2621 }
2622 else if(profileLevelType->nProfileIndex == 2)
2623 {
2624 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2625 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2626 }
2627 else
2628 {
2629 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
2630 profileLevelType->nProfileIndex);
2631 eRet = OMX_ErrorNoMore;
2632 }
2633 }
2634 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2635 {
2636 if (profileLevelType->nProfileIndex == 0)
2637 {
2638 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2639 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2640 }
2641 else
2642 {
2643 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2644 eRet = OMX_ErrorNoMore;
2645 }
2646 }
2647 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2648 {
2649 if (profileLevelType->nProfileIndex == 0)
2650 {
2651 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2652 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2653 }
2654 else if(profileLevelType->nProfileIndex == 1)
2655 {
2656 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2657 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2658 }
2659 else
2660 {
2661 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2662 eRet = OMX_ErrorNoMore;
2663 }
2664 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002665 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2666 {
2667 eRet = OMX_ErrorNoMore;
2668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002669 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2670 {
2671 if (profileLevelType->nProfileIndex == 0)
2672 {
2673 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2674 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2675 }
2676 else if(profileLevelType->nProfileIndex == 1)
2677 {
2678 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2679 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2680 }
2681 else
2682 {
2683 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2684 eRet = OMX_ErrorNoMore;
2685 }
2686 }
2687 }
2688 else
2689 {
2690 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
2691 eRet = OMX_ErrorBadPortIndex;
2692 }
2693 return eRet;
2694}
2695
2696/* ======================================================================
2697FUNCTION
2698 omx_vdec::GetParameter
2699
2700DESCRIPTION
2701 OMX Get Parameter method implementation
2702
2703PARAMETERS
2704 <TBD>.
2705
2706RETURN VALUE
2707 Error None if successful.
2708
2709========================================================================== */
2710OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2711 OMX_IN OMX_INDEXTYPE paramIndex,
2712 OMX_INOUT OMX_PTR paramData)
2713{
2714 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2715
2716 DEBUG_PRINT_LOW("get_parameter: \n");
2717 if(m_state == OMX_StateInvalid)
2718 {
2719 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2720 return OMX_ErrorInvalidState;
2721 }
2722 if(paramData == NULL)
2723 {
2724 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2725 return OMX_ErrorBadParameter;
2726 }
2727 switch(paramIndex)
2728 {
2729 case OMX_IndexParamPortDefinition:
2730 {
2731 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2732 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2733 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2734 eRet = update_portdef(portDefn);
2735 if (eRet == OMX_ErrorNone)
2736 m_port_def = *portDefn;
2737 break;
2738 }
2739 case OMX_IndexParamVideoInit:
2740 {
2741 OMX_PORT_PARAM_TYPE *portParamType =
2742 (OMX_PORT_PARAM_TYPE *) paramData;
2743 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2744
2745 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2746 portParamType->nSize = sizeof(portParamType);
2747 portParamType->nPorts = 2;
2748 portParamType->nStartPortNumber = 0;
2749 break;
2750 }
2751 case OMX_IndexParamVideoPortFormat:
2752 {
2753 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2754 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2755 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2756
2757 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2758 portFmt->nSize = sizeof(portFmt);
2759
2760 if (0 == portFmt->nPortIndex)
2761 {
2762 if (0 == portFmt->nIndex)
2763 {
2764 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2765 portFmt->eCompressionFormat = eCompressionFormat;
2766 }
2767 else
2768 {
2769 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2770 " NoMore compression formats\n");
2771 eRet = OMX_ErrorNoMore;
2772 }
2773 }
2774 else if (1 == portFmt->nPortIndex)
2775 {
2776 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2777
2778 if(0 == portFmt->nIndex)
2779 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2780 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
2781 else
2782 {
2783 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2784 " NoMore Color formats\n");
2785 eRet = OMX_ErrorNoMore;
2786 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002787 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2788 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2789 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002790 }
2791 else
2792 {
2793 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2794 (int)portFmt->nPortIndex);
2795 eRet = OMX_ErrorBadPortIndex;
2796 }
2797 break;
2798 }
2799 /*Component should support this port definition*/
2800 case OMX_IndexParamAudioInit:
2801 {
2802 OMX_PORT_PARAM_TYPE *audioPortParamType =
2803 (OMX_PORT_PARAM_TYPE *) paramData;
2804 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2805 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2806 audioPortParamType->nSize = sizeof(audioPortParamType);
2807 audioPortParamType->nPorts = 0;
2808 audioPortParamType->nStartPortNumber = 0;
2809 break;
2810 }
2811 /*Component should support this port definition*/
2812 case OMX_IndexParamImageInit:
2813 {
2814 OMX_PORT_PARAM_TYPE *imagePortParamType =
2815 (OMX_PORT_PARAM_TYPE *) paramData;
2816 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2817 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2818 imagePortParamType->nSize = sizeof(imagePortParamType);
2819 imagePortParamType->nPorts = 0;
2820 imagePortParamType->nStartPortNumber = 0;
2821 break;
2822
2823 }
2824 /*Component should support this port definition*/
2825 case OMX_IndexParamOtherInit:
2826 {
2827 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2828 paramIndex);
2829 eRet =OMX_ErrorUnsupportedIndex;
2830 break;
2831 }
2832 case OMX_IndexParamStandardComponentRole:
2833 {
2834 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2835 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2836 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2837 comp_role->nSize = sizeof(*comp_role);
2838
2839 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2840 paramIndex);
2841 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2842 OMX_MAX_STRINGNAME_SIZE);
2843 break;
2844 }
2845 /* Added for parameter test */
2846 case OMX_IndexParamPriorityMgmt:
2847 {
2848
2849 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2850 (OMX_PRIORITYMGMTTYPE *) paramData;
2851 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2852 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2853 priorityMgmType->nSize = sizeof(priorityMgmType);
2854
2855 break;
2856 }
2857 /* Added for parameter test */
2858 case OMX_IndexParamCompBufferSupplier:
2859 {
2860 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2861 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2862 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2863
2864 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2865 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2866 if(0 == bufferSupplierType->nPortIndex)
2867 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2868 else if (1 == bufferSupplierType->nPortIndex)
2869 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2870 else
2871 eRet = OMX_ErrorBadPortIndex;
2872
2873
2874 break;
2875 }
2876 case OMX_IndexParamVideoAvc:
2877 {
2878 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2879 paramIndex);
2880 break;
2881 }
2882 case OMX_IndexParamVideoH263:
2883 {
2884 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2885 paramIndex);
2886 break;
2887 }
2888 case OMX_IndexParamVideoMpeg4:
2889 {
2890 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2891 paramIndex);
2892 break;
2893 }
2894 case OMX_IndexParamVideoMpeg2:
2895 {
2896 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2897 paramIndex);
2898 break;
2899 }
2900 case OMX_IndexParamVideoProfileLevelQuerySupported:
2901 {
2902 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2903 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2904 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2905 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2906 break;
2907 }
2908#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2909 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2910 {
2911 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2912 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2913 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2914
2915 if(secure_mode) {
2916 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302917 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002918 } else {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002919 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED |
2920 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002921 }
2922 } else {
2923 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2924 eRet = OMX_ErrorBadParameter;
2925 }
2926 }
2927 break;
2928#endif
2929
2930 default:
2931 {
2932 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2933 eRet =OMX_ErrorUnsupportedIndex;
2934 }
2935
2936 }
2937
2938 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2939 drv_ctx.video_resolution.frame_width,
2940 drv_ctx.video_resolution.frame_height,
2941 drv_ctx.video_resolution.stride,
2942 drv_ctx.video_resolution.scan_lines);
2943
2944 return eRet;
2945}
2946
2947#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2948OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2949{
2950 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2951 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2952 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2953
2954 if((params == NULL) ||
2955 (params->nativeBuffer == NULL) ||
2956 (params->nativeBuffer->handle == NULL) ||
2957 !m_enable_android_native_buffers)
2958 return OMX_ErrorBadParameter;
2959 m_use_android_native_buffers = OMX_TRUE;
2960 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2961 private_handle_t *handle = (private_handle_t *)nBuf->handle;
2962 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
2963 OMX_U8 *buffer = NULL;
2964 if(!secure_mode) {
2965 buffer = (OMX_U8*)mmap(0, handle->size,
2966 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
2967 if(buffer == MAP_FAILED) {
2968 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2969 return OMX_ErrorInsufficientResources;
2970 }
2971 }
2972 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2973 } else {
2974 eRet = OMX_ErrorBadParameter;
2975 }
2976 return eRet;
2977}
2978#endif
2979/* ======================================================================
2980FUNCTION
2981 omx_vdec::Setparameter
2982
2983DESCRIPTION
2984 OMX Set Parameter method implementation.
2985
2986PARAMETERS
2987 <TBD>.
2988
2989RETURN VALUE
2990 OMX Error None if successful.
2991
2992========================================================================== */
2993OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
2994 OMX_IN OMX_INDEXTYPE paramIndex,
2995 OMX_IN OMX_PTR paramData)
2996{
2997 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2998 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002999 int ret=0;
3000 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003001 if(m_state == OMX_StateInvalid)
3002 {
3003 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3004 return OMX_ErrorInvalidState;
3005 }
3006 if(paramData == NULL)
3007 {
3008 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3009 return OMX_ErrorBadParameter;
3010 }
3011 if((m_state != OMX_StateLoaded) &&
3012 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3013 (m_out_bEnabled == OMX_TRUE) &&
3014 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3015 (m_inp_bEnabled == OMX_TRUE)) {
3016 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3017 return OMX_ErrorIncorrectStateOperation;
3018 }
3019 switch(paramIndex)
3020 {
3021 case OMX_IndexParamPortDefinition:
3022 {
3023 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3024 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3025 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3026 //been called.
3027 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3028 (int)portDefn->format.video.nFrameHeight,
3029 (int)portDefn->format.video.nFrameWidth);
3030 if(OMX_DirOutput == portDefn->eDir)
3031 {
3032 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3033 m_display_id = portDefn->format.video.pNativeWindow;
3034 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3035 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3036 {
3037 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3038 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3039 eRet = set_buffer_req(&drv_ctx.op_buf);
3040 if (eRet == OMX_ErrorNone)
3041 m_port_def = *portDefn;
3042 }
3043 else
3044 {
3045 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n",
3046 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3047 portDefn->nBufferCountActual, portDefn->nBufferSize);
3048 eRet = OMX_ErrorBadParameter;
3049 }
3050 }
3051 else if(OMX_DirInput == portDefn->eDir)
3052 {
3053 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3054 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3055 {
3056 // Frame rate only should be set if this is a "known value" or to
3057 // activate ts prediction logic (arbitrary mode only) sending input
3058 // timestamps with max value (LLONG_MAX).
3059 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %d",
3060 portDefn->format.video.xFramerate >> 16);
3061 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3062 drv_ctx.frame_rate.fps_denominator);
3063 if(!drv_ctx.frame_rate.fps_numerator)
3064 {
3065 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3066 drv_ctx.frame_rate.fps_numerator = 30;
3067 }
3068 if(drv_ctx.frame_rate.fps_denominator)
3069 drv_ctx.frame_rate.fps_numerator = (int)
3070 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3071 drv_ctx.frame_rate.fps_denominator = 1;
3072 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3073 drv_ctx.frame_rate.fps_numerator;
3074 ioctl_msg.in = &drv_ctx.frame_rate;
3075 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
3076 (void*)&ioctl_msg) < */0)
3077 {
3078 DEBUG_PRINT_ERROR("Setting frame rate to driver failed");
3079 }
3080 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
3081 frm_int, drv_ctx.frame_rate.fps_numerator /
3082 (float)drv_ctx.frame_rate.fps_denominator);
3083 }
3084 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3085 if(drv_ctx.video_resolution.frame_height !=
3086 portDefn->format.video.nFrameHeight ||
3087 drv_ctx.video_resolution.frame_width !=
3088 portDefn->format.video.nFrameWidth)
3089 {
3090 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n",
3091 portDefn->format.video.nFrameWidth,
3092 portDefn->format.video.nFrameHeight);
3093 if (portDefn->format.video.nFrameHeight != 0x0 &&
3094 portDefn->format.video.nFrameWidth != 0x0)
3095 {
3096 drv_ctx.video_resolution.frame_height =
3097 drv_ctx.video_resolution.scan_lines =
3098 portDefn->format.video.nFrameHeight;
3099 drv_ctx.video_resolution.frame_width =
3100 drv_ctx.video_resolution.stride =
3101 portDefn->format.video.nFrameWidth;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003102 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3103 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3104 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3105 fmt.fmt.pix_mp.pixelformat = output_capability;
3106 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);
3107 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003108 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES,
3109 (void*)&ioctl_msg) < */0)
3110 {
3111 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3112 eRet = OMX_ErrorUnsupportedSetting;
3113 }
3114 else
3115 eRet = get_buffer_req(&drv_ctx.op_buf);
3116 }
3117 }
3118 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003119 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003120 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003121 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003122 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003123 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3124 (~(buffer_prop->alignment - 1));
3125 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003126 }
3127 else
3128 {
3129 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n",
3130 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3131 portDefn->nBufferCountActual, portDefn->nBufferSize);
3132 eRet = OMX_ErrorBadParameter;
3133 }
3134 }
3135 else if (portDefn->eDir == OMX_DirMax)
3136 {
3137 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3138 (int)portDefn->nPortIndex);
3139 eRet = OMX_ErrorBadPortIndex;
3140 }
3141 }
3142 break;
3143 case OMX_IndexParamVideoPortFormat:
3144 {
3145 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3146 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3147 int ret=0;
3148 struct v4l2_format fmt;
3149 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3150 portFmt->eColorFormat);
3151
3152 if(1 == portFmt->nPortIndex)
3153 {
3154 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3155 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3156 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3157 fmt.fmt.pix_mp.pixelformat = capture_capability;
3158 enum vdec_output_fromat op_format;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003159 if(portFmt->eColorFormat == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003160 op_format = VDEC_YUV_FORMAT_NV12;
3161 else if(portFmt->eColorFormat ==
3162 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3163 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3164 else
3165 eRet = OMX_ErrorBadParameter;
3166
3167 if(eRet == OMX_ErrorNone)
3168 {
3169 drv_ctx.output_format = op_format;
3170 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3171 if(ret)
3172 {
3173 DEBUG_PRINT_ERROR("\n Set output format failed");
3174 eRet = OMX_ErrorUnsupportedSetting;
3175 /*TODO: How to handle this case */
3176 }
3177 else
3178 {
3179 eRet = get_buffer_req(&drv_ctx.op_buf);
3180 }
3181 }
3182 }
3183 }
3184 break;
3185
3186 case OMX_QcomIndexPortDefn:
3187 {
3188 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3189 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3190 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
3191 portFmt->nFramePackingFormat);
3192
3193 /* Input port */
3194 if (portFmt->nPortIndex == 0)
3195 {
3196 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3197 {
3198 if(secure_mode) {
3199 arbitrary_bytes = false;
3200 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3201 eRet = OMX_ErrorUnsupportedSetting;
3202 } else {
3203 arbitrary_bytes = true;
3204 }
3205 }
3206 else if (portFmt->nFramePackingFormat ==
3207 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3208 {
3209 arbitrary_bytes = false;
3210 }
3211 else
3212 {
3213 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
3214 portFmt->nFramePackingFormat);
3215 eRet = OMX_ErrorUnsupportedSetting;
3216 }
3217 }
3218 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3219 {
3220 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3221 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3222 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3223 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3224 {
3225 m_out_mem_region_smi = OMX_TRUE;
3226 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3227 {
3228 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3229 m_use_output_pmem = OMX_TRUE;
3230 }
3231 }
3232 }
3233 }
3234 break;
3235
3236 case OMX_IndexParamStandardComponentRole:
3237 {
3238 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3239 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3240 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3241 comp_role->cRole);
3242
3243 if((m_state == OMX_StateLoaded)&&
3244 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3245 {
3246 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3247 }
3248 else
3249 {
3250 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3251 return OMX_ErrorIncorrectStateOperation;
3252 }
3253
3254 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3255 {
3256 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3257 {
3258 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3259 }
3260 else
3261 {
3262 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3263 eRet =OMX_ErrorUnsupportedSetting;
3264 }
3265 }
3266 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3267 {
3268 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3269 {
3270 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3271 }
3272 else
3273 {
3274 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3275 eRet = OMX_ErrorUnsupportedSetting;
3276 }
3277 }
3278 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3279 {
3280 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3281 {
3282 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3283 }
3284 else
3285 {
3286 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3287 eRet =OMX_ErrorUnsupportedSetting;
3288 }
3289 }
3290 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3291 {
3292 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3293 {
3294 strlcpy((char*)m_cRole,"video_decoder.mpeg2",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.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3303 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3304 )
3305 {
3306 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3307 {
3308 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3309 }
3310 else
3311 {
3312 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3313 eRet =OMX_ErrorUnsupportedSetting;
3314 }
3315 }
3316 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3317 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3318 )
3319 {
3320 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3321 {
3322 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3323 }
3324 else
3325 {
3326 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3327 eRet =OMX_ErrorUnsupportedSetting;
3328 }
3329 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003330 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3331 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003332 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3333 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003334 {
3335 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3336 }
3337 else
3338 {
3339 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3340 eRet = OMX_ErrorUnsupportedSetting;
3341 }
3342 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003343 else
3344 {
3345 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3346 eRet = OMX_ErrorInvalidComponentName;
3347 }
3348 break;
3349 }
3350
3351 case OMX_IndexParamPriorityMgmt:
3352 {
3353 if(m_state != OMX_StateLoaded)
3354 {
3355 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3356 return OMX_ErrorIncorrectStateOperation;
3357 }
3358 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3359 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
3360 priorityMgmtype->nGroupID);
3361
3362 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
3363 priorityMgmtype->nGroupPriority);
3364
3365 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3366 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3367
3368 break;
3369 }
3370
3371 case OMX_IndexParamCompBufferSupplier:
3372 {
3373 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3374 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3375 bufferSupplierType->eBufferSupplier);
3376 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3377 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3378
3379 else
3380
3381 eRet = OMX_ErrorBadPortIndex;
3382
3383 break;
3384
3385 }
3386 case OMX_IndexParamVideoAvc:
3387 {
3388 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3389 paramIndex);
3390 break;
3391 }
3392 case OMX_IndexParamVideoH263:
3393 {
3394 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3395 paramIndex);
3396 break;
3397 }
3398 case OMX_IndexParamVideoMpeg4:
3399 {
3400 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3401 paramIndex);
3402 break;
3403 }
3404 case OMX_IndexParamVideoMpeg2:
3405 {
3406 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3407 paramIndex);
3408 break;
3409 }
3410 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3411 {
3412 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3413 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003414 struct v4l2_control control;
3415 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003416 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3417 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003418 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3419 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3420 }
3421 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3422 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003423 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003424 }
3425 else
3426 eRet = OMX_ErrorBadParameter;
3427 if (eRet == OMX_ErrorNone)
3428 {
3429 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3430 control.value = pic_order;
3431 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3432 if(rc)
3433 {
3434 DEBUG_PRINT_ERROR("\n Set picture order failed");
3435 eRet = OMX_ErrorUnsupportedSetting;
3436 }
3437 }
3438 break;
3439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003440 case OMX_QcomIndexParamConcealMBMapExtraData:
3441 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003442 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003443 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3444 else {
3445 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3446 eRet = OMX_ErrorUnsupportedSetting;
3447 }
3448 break;
3449 case OMX_QcomIndexParamFrameInfoExtraData:
3450 {
3451 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003452 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003453 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3454 else {
3455 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3456 eRet = OMX_ErrorUnsupportedSetting;
3457 }
3458 break;
3459 }
3460 case OMX_QcomIndexParamInterlaceExtraData:
3461 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003462 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003463 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3464 else {
3465 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3466 eRet = OMX_ErrorUnsupportedSetting;
3467 }
3468 break;
3469 case OMX_QcomIndexParamH264TimeInfo:
3470 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003471 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003472 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3473 else {
3474 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3475 eRet = OMX_ErrorUnsupportedSetting;
3476 }
3477 break;
3478 case OMX_QcomIndexParamVideoDivx:
3479 {
3480 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003481 }
3482 break;
3483 case OMX_QcomIndexPlatformPvt:
3484 {
3485 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3486 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3487 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3488 {
3489 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3490 eRet = OMX_ErrorUnsupportedSetting;
3491 }
3492 else
3493 {
3494 m_out_pvt_entry_pmem = OMX_TRUE;
3495 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3496 {
3497 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3498 m_use_output_pmem = OMX_TRUE;
3499 }
3500 }
3501
3502 }
3503 break;
3504 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3505 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003506 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3507 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3508 struct v4l2_control control;
3509 int rc;
3510 drv_ctx.idr_only_decoding = 1;
3511 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3512 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3513 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3514 if(rc)
3515 {
3516 DEBUG_PRINT_ERROR("\n Set picture order failed");
3517 eRet = OMX_ErrorUnsupportedSetting;
3518 } else {
3519 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3520 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3521 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3522 if(rc)
3523 {
3524 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3525 eRet = OMX_ErrorUnsupportedSetting;
3526 }
3527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003528 }
3529 break;
3530
3531 case OMX_QcomIndexParamIndexExtraDataType:
3532 {
3533 if(!secure_mode) {
3534 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3535 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3536 (extradataIndexType->bEnabled == OMX_TRUE) &&
3537 (extradataIndexType->nPortIndex == 1))
3538 {
3539 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003540 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003541
Shalaj Jain273b3e02012-06-22 19:08:03 -07003542 }
3543 }
3544 }
3545 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003546 case OMX_QcomIndexParamEnableSmoothStreaming:
3547 {
3548 struct v4l2_control control;
3549 struct v4l2_format fmt;
3550 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3551 control.value = 1;
3552 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3553 if(rc < 0) {
3554 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3555 eRet = OMX_ErrorHardware;
3556 }
3557 }
3558 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003559#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3560 /* Need to allow following two set_parameters even in Idle
3561 * state. This is ANDROID architecture which is not in sync
3562 * with openmax standard. */
3563 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3564 {
3565 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3566 if(enableNativeBuffers) {
3567 m_enable_android_native_buffers = enableNativeBuffers->enable;
3568 }
3569 }
3570 break;
3571 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3572 {
3573 eRet = use_android_native_buffer(hComp, paramData);
3574 }
3575 break;
3576#endif
3577 case OMX_QcomIndexParamEnableTimeStampReorder:
3578 {
3579 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3580 if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) {
3581 if (reorder->bEnable == OMX_TRUE) {
3582 frm_int =0;
3583 time_stamp_dts.set_timestamp_reorder_mode(true);
3584 }
3585 else
3586 time_stamp_dts.set_timestamp_reorder_mode(false);
3587 } else {
3588 time_stamp_dts.set_timestamp_reorder_mode(false);
3589 if (reorder->bEnable == OMX_TRUE)
3590 {
3591 eRet = OMX_ErrorUnsupportedSetting;
3592 }
3593 }
3594 }
3595 break;
3596 default:
3597 {
3598 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3599 eRet = OMX_ErrorUnsupportedIndex;
3600 }
3601 }
3602 return eRet;
3603}
3604
3605/* ======================================================================
3606FUNCTION
3607 omx_vdec::GetConfig
3608
3609DESCRIPTION
3610 OMX Get Config Method implementation.
3611
3612PARAMETERS
3613 <TBD>.
3614
3615RETURN VALUE
3616 OMX Error None if successful.
3617
3618========================================================================== */
3619OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3620 OMX_IN OMX_INDEXTYPE configIndex,
3621 OMX_INOUT OMX_PTR configData)
3622{
3623 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3624
3625 if (m_state == OMX_StateInvalid)
3626 {
3627 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3628 return OMX_ErrorInvalidState;
3629 }
3630
3631 switch (configIndex)
3632 {
3633 case OMX_QcomIndexConfigInterlaced:
3634 {
3635 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3636 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3637 if (configFmt->nPortIndex == 1)
3638 {
3639 if (configFmt->nIndex == 0)
3640 {
3641 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3642 }
3643 else if (configFmt->nIndex == 1)
3644 {
3645 configFmt->eInterlaceType =
3646 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3647 }
3648 else if (configFmt->nIndex == 2)
3649 {
3650 configFmt->eInterlaceType =
3651 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3652 }
3653 else
3654 {
3655 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3656 " NoMore Interlaced formats\n");
3657 eRet = OMX_ErrorNoMore;
3658 }
3659
3660 }
3661 else
3662 {
3663 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3664 (int)configFmt->nPortIndex);
3665 eRet = OMX_ErrorBadPortIndex;
3666 }
3667 break;
3668 }
3669 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3670 {
3671 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3672 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3673 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3674 //ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances;
3675 //(void)(ioctl(drv_ctx.video_driver_fd,
3676 //VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
3677
3678 decoderinstances->nNumOfInstances = 16;
3679 /*TODO: How to handle this case */
3680 break;
3681 }
3682 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3683 {
3684 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3685 {
3686 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3687 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3688 h264_parser->get_frame_pack_data(configFmt);
3689 }
3690 else
3691 {
3692 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3693 }
3694 break;
3695 }
3696 default:
3697 {
3698 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3699 eRet = OMX_ErrorBadParameter;
3700 }
3701
3702 }
3703
3704 return eRet;
3705}
3706
3707/* ======================================================================
3708FUNCTION
3709 omx_vdec::SetConfig
3710
3711DESCRIPTION
3712 OMX Set Config method implementation
3713
3714PARAMETERS
3715 <TBD>.
3716
3717RETURN VALUE
3718 OMX Error None if successful.
3719========================================================================== */
3720OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3721 OMX_IN OMX_INDEXTYPE configIndex,
3722 OMX_IN OMX_PTR configData)
3723{
3724 if(m_state == OMX_StateInvalid)
3725 {
3726 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3727 return OMX_ErrorInvalidState;
3728 }
3729
3730 OMX_ERRORTYPE ret = OMX_ErrorNone;
3731 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3732
3733 DEBUG_PRINT_LOW("\n Set Config Called");
3734
3735 if (m_state == OMX_StateExecuting)
3736 {
3737 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3738 return ret;
3739 }
3740
3741 if (configIndex == OMX_IndexVendorVideoExtraData)
3742 {
3743 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3744 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3745 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3746 {
3747 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3748 OMX_U32 extra_size;
3749 // Parsing done here for the AVC atom is definitely not generic
3750 // Currently this piece of code is working, but certainly
3751 // not tested with all .mp4 files.
3752 // Incase of failure, we might need to revisit this
3753 // for a generic piece of code.
3754
3755 // Retrieve size of NAL length field
3756 // byte #4 contains the size of NAL lenght field
3757 nal_length = (config->pData[4] & 0x03) + 1;
3758
3759 extra_size = 0;
3760 if (nal_length > 2)
3761 {
3762 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3763 extra_size = (nal_length - 2) * 2;
3764 }
3765
3766 // SPS starts from byte #6
3767 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3768 OMX_U8 *pDestBuf;
3769 m_vendor_config.nPortIndex = config->nPortIndex;
3770
3771 // minus 6 --> SPS starts from byte #6
3772 // minus 1 --> picture param set byte to be ignored from avcatom
3773 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3774 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3775 OMX_U32 len;
3776 OMX_U8 index = 0;
3777 // case where SPS+PPS is sent as part of set_config
3778 pDestBuf = m_vendor_config.pData;
3779
3780 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
3781 m_vendor_config.nPortIndex,
3782 m_vendor_config.nDataSize,
3783 m_vendor_config.pData);
3784 while (index < 2)
3785 {
3786 uint8 *psize;
3787 len = *pSrcBuf;
3788 len = len << 8;
3789 len |= *(pSrcBuf + 1);
3790 psize = (uint8 *) & len;
3791 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3792 for (int i = 0; i < nal_length; i++)
3793 {
3794 pDestBuf[i] = psize[nal_length - 1 - i];
3795 }
3796 //memcpy(pDestBuf,pSrcBuf,(len+2));
3797 pDestBuf += len + nal_length;
3798 pSrcBuf += len + 2;
3799 index++;
3800 pSrcBuf++; // skip picture param set
3801 len = 0;
3802 }
3803 }
3804 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3805 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3806 {
3807 m_vendor_config.nPortIndex = config->nPortIndex;
3808 m_vendor_config.nDataSize = config->nDataSize;
3809 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3810 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3811 }
3812 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3813 {
3814 if(m_vendor_config.pData)
3815 {
3816 free(m_vendor_config.pData);
3817 m_vendor_config.pData = NULL;
3818 m_vendor_config.nDataSize = 0;
3819 }
3820
3821 if (((*((OMX_U32 *) config->pData)) &
3822 VC1_SP_MP_START_CODE_MASK) ==
3823 VC1_SP_MP_START_CODE)
3824 {
3825 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3826 m_vendor_config.nPortIndex = config->nPortIndex;
3827 m_vendor_config.nDataSize = config->nDataSize;
3828 m_vendor_config.pData =
3829 (OMX_U8 *) malloc(config->nDataSize);
3830 memcpy(m_vendor_config.pData, config->pData,
3831 config->nDataSize);
3832 m_vc1_profile = VC1_SP_MP_RCV;
3833 }
3834 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3835 {
3836 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3837 m_vendor_config.nPortIndex = config->nPortIndex;
3838 m_vendor_config.nDataSize = config->nDataSize;
3839 m_vendor_config.pData =
3840 (OMX_U8 *) malloc((config->nDataSize));
3841 memcpy(m_vendor_config.pData, config->pData,
3842 config->nDataSize);
3843 m_vc1_profile = VC1_AP;
3844 }
3845 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3846 {
3847 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3848 m_vendor_config.nPortIndex = config->nPortIndex;
3849 m_vendor_config.nDataSize = config->nDataSize;
3850 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3851 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3852 m_vc1_profile = VC1_SP_MP_RCV;
3853 }
3854 else
3855 {
3856 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3857 }
3858 }
3859 return ret;
3860 }
3861 else if (configIndex == OMX_IndexConfigVideoNalSize)
3862 {
3863
3864 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3865 nal_length = pNal->nNaluBytes;
3866 m_frame_parser.init_nal_length(nal_length);
3867 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3868 return ret;
3869 }
3870
3871 return OMX_ErrorNotImplemented;
3872}
3873
3874/* ======================================================================
3875FUNCTION
3876 omx_vdec::GetExtensionIndex
3877
3878DESCRIPTION
3879 OMX GetExtensionIndex method implementaion. <TBD>
3880
3881PARAMETERS
3882 <TBD>.
3883
3884RETURN VALUE
3885 OMX Error None if everything successful.
3886
3887========================================================================== */
3888OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3889 OMX_IN OMX_STRING paramName,
3890 OMX_OUT OMX_INDEXTYPE* indexType)
3891{
3892 if(m_state == OMX_StateInvalid)
3893 {
3894 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3895 return OMX_ErrorInvalidState;
3896 }
3897 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3898 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3899 }
3900 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3901 {
3902 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3903 }
3904#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3905 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3906 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3907 }
3908 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3909 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3910 }
3911 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3912 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3913 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3914 }
3915 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3916 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3917 }
3918#endif
3919 else {
3920 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3921 return OMX_ErrorNotImplemented;
3922 }
3923 return OMX_ErrorNone;
3924}
3925
3926/* ======================================================================
3927FUNCTION
3928 omx_vdec::GetState
3929
3930DESCRIPTION
3931 Returns the state information back to the caller.<TBD>
3932
3933PARAMETERS
3934 <TBD>.
3935
3936RETURN VALUE
3937 Error None if everything is successful.
3938========================================================================== */
3939OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
3940 OMX_OUT OMX_STATETYPE* state)
3941{
3942 *state = m_state;
3943 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3944 return OMX_ErrorNone;
3945}
3946
3947/* ======================================================================
3948FUNCTION
3949 omx_vdec::ComponentTunnelRequest
3950
3951DESCRIPTION
3952 OMX Component Tunnel Request method implementation. <TBD>
3953
3954PARAMETERS
3955 None.
3956
3957RETURN VALUE
3958 OMX Error None if everything successful.
3959
3960========================================================================== */
3961OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
3962 OMX_IN OMX_U32 port,
3963 OMX_IN OMX_HANDLETYPE peerComponent,
3964 OMX_IN OMX_U32 peerPort,
3965 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
3966{
3967 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3968 return OMX_ErrorNotImplemented;
3969}
3970
3971/* ======================================================================
3972FUNCTION
3973 omx_vdec::UseOutputBuffer
3974
3975DESCRIPTION
3976 Helper function for Use buffer in the input pin
3977
3978PARAMETERS
3979 None.
3980
3981RETURN VALUE
3982 true/false
3983
3984========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003985OMX_ERRORTYPE omx_vdec::allocate_extradata()
3986{
3987#ifdef USE_ION
3988 if (drv_ctx.extradata_info.buffer_size) {
3989 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3990 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3991 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3992 free_ion_memory(&drv_ctx.extradata_info.ion);
3993 }
3994 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3995 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3996 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
3997 &drv_ctx.extradata_info.ion.ion_alloc_data,
3998 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3999 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4000 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4001 return OMX_ErrorInsufficientResources;
4002 }
4003 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4004 drv_ctx.extradata_info.size,
4005 PROT_READ|PROT_WRITE, MAP_SHARED,
4006 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4007 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4008 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4009 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4010 free_ion_memory(&drv_ctx.extradata_info.ion);
4011 return OMX_ErrorInsufficientResources;
4012 }
4013 }
4014#endif
4015 return OMX_ErrorNone;
4016}
4017
4018void omx_vdec::free_extradata() {
4019#ifdef USE_ION
4020 if (drv_ctx.extradata_info.uaddr) {
4021 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4022 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4023 free_ion_memory(&drv_ctx.extradata_info.ion);
4024 }
4025 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4026#endif
4027}
4028
Shalaj Jain273b3e02012-06-22 19:08:03 -07004029OMX_ERRORTYPE omx_vdec::use_output_buffer(
4030 OMX_IN OMX_HANDLETYPE hComp,
4031 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4032 OMX_IN OMX_U32 port,
4033 OMX_IN OMX_PTR appData,
4034 OMX_IN OMX_U32 bytes,
4035 OMX_IN OMX_U8* buffer)
4036{
4037 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4038 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4039 unsigned i= 0; // Temporary counter
4040 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4041 struct vdec_setbuffer_cmd setbuffers;
4042 OMX_PTR privateAppData = NULL;
4043 private_handle_t *handle = NULL;
4044 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004045 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004046 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4047 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004048
Shalaj Jain273b3e02012-06-22 19:08:03 -07004049 if (!m_out_mem_ptr) {
4050 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4051 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004052 if (eRet == OMX_ErrorNone)
4053 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004054 }
4055
4056 if (eRet == OMX_ErrorNone) {
4057 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4058 if(BITMASK_ABSENT(&m_out_bm_count,i))
4059 {
4060 break;
4061 }
4062 }
4063 }
4064
4065 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004066 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004067 eRet = OMX_ErrorInsufficientResources;
4068 }
4069
4070 if (eRet == OMX_ErrorNone) {
4071#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4072 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004073 if (m_use_android_native_buffers) {
4074 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4075 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4076 handle = (private_handle_t *)nBuf->handle;
4077 privateAppData = params->pAppPrivate;
4078 } else {
4079 handle = (private_handle_t *)buff;
4080 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004081 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004082
4083 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4084 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4085 " expected %u, got %lu",
4086 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4087 return OMX_ErrorBadParameter;
4088 }
4089
4090 if (!m_use_android_native_buffers) {
4091 if (!secure_mode) {
4092 buff = (OMX_U8*)mmap(0, handle->size,
4093 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4094 if (buff == MAP_FAILED) {
4095 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4096 return OMX_ErrorInsufficientResources;
4097 }
4098 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004099 }
4100#if defined(_ANDROID_ICS_)
4101 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004102 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004103#endif
4104 if(!handle) {
4105 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4106 return OMX_ErrorBadParameter;
4107 }
4108 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4109 drv_ctx.ptr_outputbuffer[i].offset = 0;
4110 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4111 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4112 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4113 } else
4114#endif
4115
4116 if (!ouput_egl_buffers && !m_use_output_pmem) {
4117#ifdef USE_ION
4118 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4119 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4120 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004121 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004122 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004123 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 -07004124 return OMX_ErrorInsufficientResources;
4125 }
4126 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4127 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4128#else
4129 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4130 open (MEM_DEVICE,O_RDWR);
4131
4132 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004133 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 -07004134 return OMX_ErrorInsufficientResources;
4135 }
4136
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004137 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004138 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4139 {
4140 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4141 open (MEM_DEVICE,O_RDWR);
4142 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004143 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 -07004144 return OMX_ErrorInsufficientResources;
4145 }
4146 }
4147
4148 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4149 drv_ctx.op_buf.buffer_size,
4150 drv_ctx.op_buf.alignment))
4151 {
4152 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4153 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4154 return OMX_ErrorInsufficientResources;
4155 }
4156#endif
4157 if(!secure_mode) {
4158 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4159 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4160 PROT_READ|PROT_WRITE, MAP_SHARED,
4161 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4162 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4163 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4164#ifdef USE_ION
4165 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4166#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004167 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004168 return OMX_ErrorInsufficientResources;
4169 }
4170 }
4171 drv_ctx.ptr_outputbuffer[i].offset = 0;
4172 privateAppData = appData;
4173 }
4174 else {
4175
4176 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4177 if (!appData || !bytes ) {
4178 if(!secure_mode && !buffer) {
4179 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4180 return OMX_ErrorBadParameter;
4181 }
4182 }
4183
4184 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4185 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4186 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4187 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4188 !pmem_list->nEntries ||
4189 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4190 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4191 return OMX_ErrorBadParameter;
4192 }
4193 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4194 pmem_list->entryList->entry;
4195 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
4196 pmem_info->pmem_fd);
4197 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4198 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4199 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4200 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4201 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4202 privateAppData = appData;
4203 }
4204 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4205 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4206
4207 *bufferHdr = (m_out_mem_ptr + i );
4208 if(secure_mode)
4209 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4210 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4211 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4212 sizeof (vdec_bufferpayload));
4213
4214 // ioctl_msg.in = &setbuffers;
4215 // ioctl_msg.out = NULL;
4216
4217 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i,
4218 drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd );
4219 // if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4220 // &ioctl_msg) < 0)
4221 // {
4222 // DEBUG_PRINT_ERROR("\n Set output buffer failed");
4223 // return OMX_ErrorInsufficientResources;
4224 // }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004225
4226
4227
4228 buf.index = i;
4229 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4230 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004231 plane[0].length = drv_ctx.op_buf.buffer_size;
4232 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[i].bufferaddr-drv_ctx.ptr_outputbuffer[i].offset);
4233 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4234 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4235 plane[0].data_offset = 0;
4236 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4237 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4238 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4239 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4240#ifdef USE_ION
4241 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4242#endif
4243 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4244 plane[extra_idx].data_offset = 0;
4245 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4246 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4247 return OMX_ErrorBadParameter;
4248 }
4249 buf.m.planes = plane;
4250 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004251
4252 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4253
4254 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4255 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4256 /*TODO: How to handle this case */
4257 return OMX_ErrorInsufficientResources;
4258 }
4259
4260 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4261 enum v4l2_buf_type buf_type;
4262 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4263 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4264 return OMX_ErrorInsufficientResources;
4265 } else {
4266 streaming[CAPTURE_PORT] = true;
4267 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4268 }
4269 }
4270
Shalaj Jain273b3e02012-06-22 19:08:03 -07004271 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004272 if (m_enable_android_native_buffers) {
4273 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4274 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4275 } else {
4276 (*bufferHdr)->pBuffer = buff;
4277 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004278 (*bufferHdr)->pAppPrivate = privateAppData;
4279 BITMASK_SET(&m_out_bm_count,i);
4280 }
4281 return eRet;
4282}
4283
4284/* ======================================================================
4285FUNCTION
4286 omx_vdec::use_input_heap_buffers
4287
4288DESCRIPTION
4289 OMX Use Buffer Heap allocation method implementation.
4290
4291PARAMETERS
4292 <TBD>.
4293
4294RETURN VALUE
4295 OMX Error None , if everything successful.
4296
4297========================================================================== */
4298OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4299 OMX_IN OMX_HANDLETYPE hComp,
4300 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4301 OMX_IN OMX_U32 port,
4302 OMX_IN OMX_PTR appData,
4303 OMX_IN OMX_U32 bytes,
4304 OMX_IN OMX_U8* buffer)
4305{
4306 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4307 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4308 if(!m_inp_heap_ptr)
4309 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4310 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4311 drv_ctx.ip_buf.actualcount);
4312 if(!m_phdr_pmem_ptr)
4313 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4314 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4315 drv_ctx.ip_buf.actualcount);
4316 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4317 {
4318 DEBUG_PRINT_ERROR("Insufficent memory");
4319 eRet = OMX_ErrorInsufficientResources;
4320 }
4321 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4322 {
4323 input_use_buffer = true;
4324 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4325 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4326 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4327 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4328 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4329 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4330 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4331 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4332 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4333 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL))
4334 {
4335 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4336 return OMX_ErrorInsufficientResources;
4337 }
4338 m_in_alloc_cnt++;
4339 }
4340 else
4341 {
4342 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4343 eRet = OMX_ErrorInsufficientResources;
4344 }
4345 return eRet;
4346}
4347
4348/* ======================================================================
4349FUNCTION
4350 omx_vdec::UseBuffer
4351
4352DESCRIPTION
4353 OMX Use Buffer method implementation.
4354
4355PARAMETERS
4356 <TBD>.
4357
4358RETURN VALUE
4359 OMX Error None , if everything successful.
4360
4361========================================================================== */
4362OMX_ERRORTYPE omx_vdec::use_buffer(
4363 OMX_IN OMX_HANDLETYPE hComp,
4364 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4365 OMX_IN OMX_U32 port,
4366 OMX_IN OMX_PTR appData,
4367 OMX_IN OMX_U32 bytes,
4368 OMX_IN OMX_U8* buffer)
4369{
4370 OMX_ERRORTYPE error = OMX_ErrorNone;
4371 struct vdec_setbuffer_cmd setbuffers;
4372 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4373
4374 if (bufferHdr == NULL || bytes == 0)
4375 {
4376 if(!secure_mode && buffer == NULL) {
4377 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4378 return OMX_ErrorBadParameter;
4379 }
4380 }
4381 if(m_state == OMX_StateInvalid)
4382 {
4383 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4384 return OMX_ErrorInvalidState;
4385 }
4386 if(port == OMX_CORE_INPUT_PORT_INDEX)
4387 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4388 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4389 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4390 else
4391 {
4392 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4393 error = OMX_ErrorBadPortIndex;
4394 }
4395 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
4396 if(error == OMX_ErrorNone)
4397 {
4398 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4399 {
4400 // Send the callback now
4401 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4402 post_event(OMX_CommandStateSet,OMX_StateIdle,
4403 OMX_COMPONENT_GENERATE_EVENT);
4404 }
4405 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4406 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4407 {
4408 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4409 post_event(OMX_CommandPortEnable,
4410 OMX_CORE_INPUT_PORT_INDEX,
4411 OMX_COMPONENT_GENERATE_EVENT);
4412 }
4413 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4414 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4415 {
4416 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4417 post_event(OMX_CommandPortEnable,
4418 OMX_CORE_OUTPUT_PORT_INDEX,
4419 OMX_COMPONENT_GENERATE_EVENT);
4420 }
4421 }
4422 return error;
4423}
4424
4425OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4426 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4427{
4428 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4429 {
4430 if(m_inp_heap_ptr[bufferindex].pBuffer)
4431 free(m_inp_heap_ptr[bufferindex].pBuffer);
4432 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4433 }
4434 if (pmem_bufferHdr)
4435 free_input_buffer(pmem_bufferHdr);
4436 return OMX_ErrorNone;
4437}
4438
4439OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4440{
4441 unsigned int index = 0;
4442 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4443 {
4444 return OMX_ErrorBadParameter;
4445 }
4446
4447 index = bufferHdr - m_inp_mem_ptr;
4448 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4449
4450 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4451 {
4452 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4453 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4454 {
4455 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4456 struct vdec_setbuffer_cmd setbuffers;
4457 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4458 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4459 sizeof (vdec_bufferpayload));
4460 ioctl_msg.in = &setbuffers;
4461 ioctl_msg.out = NULL;
4462 int ioctl_r; //= ioctl (drv_ctx.video_driver_fd,
4463 // VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
4464 if (ioctl_r < 0)
4465 {
4466 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
4467 }
4468
4469 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4470 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4471 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d",
4472 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4473 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4474 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4475 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4476 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4477 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4478 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4479 {
4480 free(m_desc_buffer_ptr[index].buf_addr);
4481 m_desc_buffer_ptr[index].buf_addr = NULL;
4482 m_desc_buffer_ptr[index].desc_data_size = 0;
4483 }
4484#ifdef USE_ION
4485 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4486#endif
4487 }
4488 }
4489
4490 return OMX_ErrorNone;
4491}
4492
4493OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4494{
4495 unsigned int index = 0;
4496
4497 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4498 {
4499 return OMX_ErrorBadParameter;
4500 }
4501
4502 index = bufferHdr - m_out_mem_ptr;
4503 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4504
4505 if (index < drv_ctx.op_buf.actualcount
4506 && drv_ctx.ptr_outputbuffer)
4507 {
4508 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
4509 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4510
4511 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4512 struct vdec_setbuffer_cmd setbuffers;
4513 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4514 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4515 sizeof (vdec_bufferpayload));
4516 ioctl_msg.in = &setbuffers;
4517 ioctl_msg.out = NULL;
4518 DEBUG_PRINT_LOW("\nRelease the Output Buffer");
4519 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
4520 &ioctl_msg) < */0)
4521 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
4522
4523#ifdef _ANDROID_
4524 if(m_enable_android_native_buffers) {
4525 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4526 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4527 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4528 }
4529 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4530 } else {
4531#endif
4532 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4533 {
4534 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4535 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4536 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d",
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004537 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004538 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4539 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004540 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4542 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4543#ifdef USE_ION
4544 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4545#endif
4546 }
4547#ifdef _ANDROID_
4548 }
4549#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004550 if (release_output_done()) {
4551 free_extradata();
4552 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004553 }
4554
4555 return OMX_ErrorNone;
4556
4557}
4558
4559OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4560 OMX_BUFFERHEADERTYPE **bufferHdr,
4561 OMX_U32 port,
4562 OMX_PTR appData,
4563 OMX_U32 bytes)
4564{
4565 OMX_BUFFERHEADERTYPE *input = NULL;
4566 unsigned char *buf_addr = NULL;
4567 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4568 unsigned i = 0;
4569
4570 /* Sanity Check*/
4571 if (bufferHdr == NULL)
4572 {
4573 return OMX_ErrorBadParameter;
4574 }
4575
4576 if (m_inp_heap_ptr == NULL)
4577 {
4578 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4579 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4580 drv_ctx.ip_buf.actualcount);
4581 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4582 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4583 drv_ctx.ip_buf.actualcount);
4584
4585 if (m_inp_heap_ptr == NULL)
4586 {
4587 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4588 return OMX_ErrorInsufficientResources;
4589 }
4590 }
4591
4592 /*Find a Free index*/
4593 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4594 {
4595 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4596 {
4597 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4598 break;
4599 }
4600 }
4601
4602 if (i < drv_ctx.ip_buf.actualcount)
4603 {
4604 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4605
4606 if (buf_addr == NULL)
4607 {
4608 return OMX_ErrorInsufficientResources;
4609 }
4610
4611 *bufferHdr = (m_inp_heap_ptr + i);
4612 input = *bufferHdr;
4613 BITMASK_SET(&m_heap_inp_bm_count,i);
4614
4615 input->pBuffer = (OMX_U8 *)buf_addr;
4616 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4617 input->nVersion.nVersion = OMX_SPEC_VERSION;
4618 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4619 input->pAppPrivate = appData;
4620 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4621 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4622 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4623 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
4624 /*Add the Buffers to freeq*/
4625 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL))
4626 {
4627 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4628 return OMX_ErrorInsufficientResources;
4629 }
4630 }
4631 else
4632 {
4633 return OMX_ErrorBadParameter;
4634 }
4635
4636 return eRet;
4637
4638}
4639
4640
4641/* ======================================================================
4642FUNCTION
4643 omx_vdec::AllocateInputBuffer
4644
4645DESCRIPTION
4646 Helper function for allocate buffer in the input pin
4647
4648PARAMETERS
4649 None.
4650
4651RETURN VALUE
4652 true/false
4653
4654========================================================================== */
4655OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4656 OMX_IN OMX_HANDLETYPE hComp,
4657 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4658 OMX_IN OMX_U32 port,
4659 OMX_IN OMX_PTR appData,
4660 OMX_IN OMX_U32 bytes)
4661{
4662
4663 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4664 struct vdec_setbuffer_cmd setbuffers;
4665 OMX_BUFFERHEADERTYPE *input = NULL;
4666 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4667 unsigned i = 0;
4668 unsigned char *buf_addr = NULL;
4669 int pmem_fd = -1;
4670
4671 if(bytes != drv_ctx.ip_buf.buffer_size)
4672 {
4673 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",
4674 bytes, drv_ctx.ip_buf.buffer_size);
4675 return OMX_ErrorBadParameter;
4676 }
4677
4678 if(!m_inp_mem_ptr)
4679 {
4680 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4681 drv_ctx.ip_buf.actualcount,
4682 drv_ctx.ip_buf.buffer_size);
4683
4684 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4685 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4686
4687 if (m_inp_mem_ptr == NULL)
4688 {
4689 return OMX_ErrorInsufficientResources;
4690 }
4691
4692 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4693 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4694
4695 if (drv_ctx.ptr_inputbuffer == NULL)
4696 {
4697 return OMX_ErrorInsufficientResources;
4698 }
4699#ifdef USE_ION
4700 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4701 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4702
4703 if (drv_ctx.ip_buf_ion_info == NULL)
4704 {
4705 return OMX_ErrorInsufficientResources;
4706 }
4707#endif
4708
4709 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4710 {
4711 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4712#ifdef USE_ION
4713 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4714#endif
4715 }
4716 }
4717
4718 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4719 {
4720 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4721 {
4722 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4723 break;
4724 }
4725 }
4726
4727 if(i < drv_ctx.ip_buf.actualcount)
4728 {
4729 struct v4l2_buffer buf;
4730 struct v4l2_plane plane;
4731 int rc;
4732 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4733#ifdef USE_ION
4734 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4735 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4736 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004737 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004738 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4739 return OMX_ErrorInsufficientResources;
4740 }
4741 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4742#else
4743 pmem_fd = open (MEM_DEVICE,O_RDWR);
4744
4745 if (pmem_fd < 0)
4746 {
4747 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4748 return OMX_ErrorInsufficientResources;
4749 }
4750
4751 if (pmem_fd == 0)
4752 {
4753 pmem_fd = open (MEM_DEVICE,O_RDWR);
4754
4755 if (pmem_fd < 0)
4756 {
4757 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4758 return OMX_ErrorInsufficientResources;
4759 }
4760 }
4761
4762 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4763 drv_ctx.ip_buf.alignment))
4764 {
4765 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4766 close(pmem_fd);
4767 return OMX_ErrorInsufficientResources;
4768 }
4769#endif
4770 if (!secure_mode) {
4771 buf_addr = (unsigned char *)mmap(NULL,
4772 drv_ctx.ip_buf.buffer_size,
4773 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4774
4775 if (buf_addr == MAP_FAILED)
4776 {
4777 close(pmem_fd);
4778#ifdef USE_ION
4779 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4780#endif
4781 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4782 return OMX_ErrorInsufficientResources;
4783 }
4784 }
4785 *bufferHdr = (m_inp_mem_ptr + i);
4786 if (secure_mode)
4787 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4788 else
4789 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4790 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4791 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4792 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4793 drv_ctx.ptr_inputbuffer [i].offset = 0;
4794
4795
4796 buf.index = i;
4797 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4798 buf.memory = V4L2_MEMORY_USERPTR;
4799 plane.bytesused = 0;
4800 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4801 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4802 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4803 plane.reserved[1] = 0;
4804 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4805 buf.m.planes = &plane;
4806 buf.length = 1;
4807
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004808 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 -07004809
4810 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4811
4812 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004813 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004814 /*TODO: How to handle this case */
4815 return OMX_ErrorInsufficientResources;
4816 }
4817
4818 input = *bufferHdr;
4819 BITMASK_SET(&m_inp_bm_count,i);
4820 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4821 if (secure_mode)
4822 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4823 else
4824 input->pBuffer = (OMX_U8 *)buf_addr;
4825 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4826 input->nVersion.nVersion = OMX_SPEC_VERSION;
4827 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4828 input->pAppPrivate = appData;
4829 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4830 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4831
4832 if (drv_ctx.disable_dmx)
4833 {
4834 eRet = allocate_desc_buffer(i);
4835 }
4836 }
4837 else
4838 {
4839 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4840 eRet = OMX_ErrorInsufficientResources;
4841 }
4842 return eRet;
4843}
4844
4845
4846/* ======================================================================
4847FUNCTION
4848 omx_vdec::AllocateOutputBuffer
4849
4850DESCRIPTION
4851 Helper fn for AllocateBuffer in the output pin
4852
4853PARAMETERS
4854 <TBD>.
4855
4856RETURN VALUE
4857 OMX Error None if everything went well.
4858
4859========================================================================== */
4860OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4861 OMX_IN OMX_HANDLETYPE hComp,
4862 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4863 OMX_IN OMX_U32 port,
4864 OMX_IN OMX_PTR appData,
4865 OMX_IN OMX_U32 bytes)
4866{
4867 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4868 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4869 unsigned i= 0; // Temporary counter
4870 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4871 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004872 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004873#ifdef USE_ION
4874 int ion_device_fd =-1;
4875 struct ion_allocation_data ion_alloc_data;
4876 struct ion_fd_data fd_ion_data;
4877#endif
4878 if(!m_out_mem_ptr)
4879 {
4880 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4881 drv_ctx.op_buf.actualcount,
4882 drv_ctx.op_buf.buffer_size);
4883 int nBufHdrSize = 0;
4884 int nPlatformEntrySize = 0;
4885 int nPlatformListSize = 0;
4886 int nPMEMInfoSize = 0;
4887 int pmem_fd = -1;
4888 unsigned char *pmem_baseaddress = NULL;
4889
4890 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4891 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4892 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4893
4894 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4895 drv_ctx.op_buf.actualcount);
4896 nBufHdrSize = drv_ctx.op_buf.actualcount *
4897 sizeof(OMX_BUFFERHEADERTYPE);
4898
4899 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4900 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4901 nPlatformListSize = drv_ctx.op_buf.actualcount *
4902 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4903 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4904 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4905
4906 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4907 sizeof(OMX_BUFFERHEADERTYPE),
4908 nPMEMInfoSize,
4909 nPlatformListSize);
4910 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4911 drv_ctx.op_buf.actualcount);
4912#ifdef USE_ION
4913 ion_device_fd = alloc_map_ion_memory(
4914 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4915 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004916 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004917 if (ion_device_fd < 0) {
4918 return OMX_ErrorInsufficientResources;
4919 }
4920 pmem_fd = fd_ion_data.fd;
4921#else
4922 pmem_fd = open (MEM_DEVICE,O_RDWR);
4923
4924 if (pmem_fd < 0)
4925 {
4926 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4927 drv_ctx.op_buf.buffer_size);
4928 return OMX_ErrorInsufficientResources;
4929 }
4930
4931 if(pmem_fd == 0)
4932 {
4933 pmem_fd = open (MEM_DEVICE,O_RDWR);
4934
4935 if (pmem_fd < 0)
4936 {
4937 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4938 drv_ctx.op_buf.buffer_size);
4939 return OMX_ErrorInsufficientResources;
4940 }
4941 }
4942
4943 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4944 drv_ctx.op_buf.actualcount,
4945 drv_ctx.op_buf.alignment))
4946 {
4947 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4948 close(pmem_fd);
4949 return OMX_ErrorInsufficientResources;
4950 }
4951#endif
4952 if (!secure_mode) {
4953 pmem_baseaddress = (unsigned char *)mmap(NULL,
4954 (drv_ctx.op_buf.buffer_size *
4955 drv_ctx.op_buf.actualcount),
4956 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4957 if (pmem_baseaddress == MAP_FAILED)
4958 {
4959 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4960 drv_ctx.op_buf.buffer_size);
4961 close(pmem_fd);
4962#ifdef USE_ION
4963 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4964#endif
4965 return OMX_ErrorInsufficientResources;
4966 }
4967 }
4968 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4969 // Alloc mem for platform specific info
4970 char *pPtr=NULL;
4971 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4972 nPMEMInfoSize,1);
4973 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4974 calloc (sizeof(struct vdec_bufferpayload),
4975 drv_ctx.op_buf.actualcount);
4976 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4977 calloc (sizeof (struct vdec_output_frameinfo),
4978 drv_ctx.op_buf.actualcount);
4979#ifdef USE_ION
4980 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4981 calloc (sizeof(struct vdec_ion),
4982 drv_ctx.op_buf.actualcount);
4983#endif
4984
4985 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4986 && drv_ctx.ptr_respbuffer)
4987 {
4988 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4989 (drv_ctx.op_buf.buffer_size *
4990 drv_ctx.op_buf.actualcount);
4991 bufHdr = m_out_mem_ptr;
4992 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4993 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4994 (((char *) m_platform_list) + nPlatformListSize);
4995 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4996 (((char *) m_platform_entry) + nPlatformEntrySize);
4997 pPlatformList = m_platform_list;
4998 pPlatformEntry = m_platform_entry;
4999 pPMEMInfo = m_pmem_info;
5000
5001 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5002
5003 // Settting the entire storage nicely
5004 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5005 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5006 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5007 {
5008 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5009 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5010 // Set the values when we determine the right HxW param
5011 bufHdr->nAllocLen = bytes;
5012 bufHdr->nFilledLen = 0;
5013 bufHdr->pAppPrivate = appData;
5014 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5015 // Platform specific PMEM Information
5016 // Initialize the Platform Entry
5017 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5018 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5019 pPlatformEntry->entry = pPMEMInfo;
5020 // Initialize the Platform List
5021 pPlatformList->nEntries = 1;
5022 pPlatformList->entryList = pPlatformEntry;
5023 // Keep pBuffer NULL till vdec is opened
5024 bufHdr->pBuffer = NULL;
5025 bufHdr->nOffset = 0;
5026
5027 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5028 pPMEMInfo->pmem_fd = 0;
5029 bufHdr->pPlatformPrivate = pPlatformList;
5030
5031 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005032 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005033#ifdef USE_ION
5034 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5035 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5036 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5037#endif
5038
5039 /*Create a mapping between buffers*/
5040 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5041 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5042 &drv_ctx.ptr_outputbuffer[i];
5043 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5044 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5045 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5046
5047 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5048 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5049 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5050 // Move the buffer and buffer header pointers
5051 bufHdr++;
5052 pPMEMInfo++;
5053 pPlatformEntry++;
5054 pPlatformList++;
5055 }
5056 }
5057 else
5058 {
5059 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
5060 m_out_mem_ptr, pPtr);
5061 if(m_out_mem_ptr)
5062 {
5063 free(m_out_mem_ptr);
5064 m_out_mem_ptr = NULL;
5065 }
5066 if(pPtr)
5067 {
5068 free(pPtr);
5069 pPtr = NULL;
5070 }
5071 if(drv_ctx.ptr_outputbuffer)
5072 {
5073 free(drv_ctx.ptr_outputbuffer);
5074 drv_ctx.ptr_outputbuffer = NULL;
5075 }
5076 if(drv_ctx.ptr_respbuffer)
5077 {
5078 free(drv_ctx.ptr_respbuffer);
5079 drv_ctx.ptr_respbuffer = NULL;
5080 }
5081#ifdef USE_ION
5082 if (drv_ctx.op_buf_ion_info) {
5083 DEBUG_PRINT_LOW("\n Free o/p ion context");
5084 free(drv_ctx.op_buf_ion_info);
5085 drv_ctx.op_buf_ion_info = NULL;
5086 }
5087#endif
5088 eRet = OMX_ErrorInsufficientResources;
5089 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005090 if (eRet == OMX_ErrorNone)
5091 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005092 }
5093
5094 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5095 {
5096 if(BITMASK_ABSENT(&m_out_bm_count,i))
5097 {
5098 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5099 break;
5100 }
5101 }
5102
5103 if (eRet == OMX_ErrorNone)
5104 {
5105 if(i < drv_ctx.op_buf.actualcount)
5106 {
5107 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005108 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005109 int rc;
5110 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5111
5112 drv_ctx.ptr_outputbuffer[i].buffer_len =
5113 drv_ctx.op_buf.buffer_size;
5114
5115 *bufferHdr = (m_out_mem_ptr + i );
5116 if (secure_mode) {
5117 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5118 }
5119 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5120
5121 buf.index = i;
5122 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5123 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005124 plane[0].length = drv_ctx.op_buf.buffer_size;
5125 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 -07005126#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005127 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005128#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005129 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5130 plane[0].data_offset = 0;
5131 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5132 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5133 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5134 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5135#ifdef USE_ION
5136 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5137#endif
5138 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5139 plane[extra_idx].data_offset = 0;
5140 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5141 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5142 return OMX_ErrorBadParameter;
5143 }
5144 buf.m.planes = plane;
5145 buf.length = drv_ctx.num_planes;
5146 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
5147 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5148 if (rc) {
5149 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150 return OMX_ErrorInsufficientResources;
5151 }
5152
5153 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5154 enum v4l2_buf_type buf_type;
5155 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5156 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5157 if (rc) {
5158 return OMX_ErrorInsufficientResources;
5159 } else {
5160 streaming[CAPTURE_PORT] = true;
5161 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5162 }
5163 }
5164
5165 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5166 (*bufferHdr)->pAppPrivate = appData;
5167 BITMASK_SET(&m_out_bm_count,i);
5168 }
5169 else
5170 {
5171 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5172 eRet = OMX_ErrorInsufficientResources;
5173 }
5174 }
5175
5176 return eRet;
5177}
5178
5179
5180// AllocateBuffer -- API Call
5181/* ======================================================================
5182FUNCTION
5183 omx_vdec::AllocateBuffer
5184
5185DESCRIPTION
5186 Returns zero if all the buffers released..
5187
5188PARAMETERS
5189 None.
5190
5191RETURN VALUE
5192 true/false
5193
5194========================================================================== */
5195OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5196 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5197 OMX_IN OMX_U32 port,
5198 OMX_IN OMX_PTR appData,
5199 OMX_IN OMX_U32 bytes)
5200{
5201 unsigned i = 0;
5202 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5203
5204 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5205 if(m_state == OMX_StateInvalid)
5206 {
5207 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5208 return OMX_ErrorInvalidState;
5209 }
5210
5211 if(port == OMX_CORE_INPUT_PORT_INDEX)
5212 {
5213 if (arbitrary_bytes)
5214 {
5215 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5216 }
5217 else
5218 {
5219 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5220 }
5221 }
5222 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5223 {
5224 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
5225 }
5226 else
5227 {
5228 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5229 eRet = OMX_ErrorBadPortIndex;
5230 }
5231 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5232 if(eRet == OMX_ErrorNone)
5233 {
5234 if(allocate_done()){
5235 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5236 {
5237 // Send the callback now
5238 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5239 post_event(OMX_CommandStateSet,OMX_StateIdle,
5240 OMX_COMPONENT_GENERATE_EVENT);
5241 }
5242 }
5243 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5244 {
5245 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5246 {
5247 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5248 post_event(OMX_CommandPortEnable,
5249 OMX_CORE_INPUT_PORT_INDEX,
5250 OMX_COMPONENT_GENERATE_EVENT);
5251 }
5252 }
5253 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5254 {
5255 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5256 {
5257 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5258 post_event(OMX_CommandPortEnable,
5259 OMX_CORE_OUTPUT_PORT_INDEX,
5260 OMX_COMPONENT_GENERATE_EVENT);
5261 }
5262 }
5263 }
5264 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5265 return eRet;
5266}
5267
5268// Free Buffer - API call
5269/* ======================================================================
5270FUNCTION
5271 omx_vdec::FreeBuffer
5272
5273DESCRIPTION
5274
5275PARAMETERS
5276 None.
5277
5278RETURN VALUE
5279 true/false
5280
5281========================================================================== */
5282OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5283 OMX_IN OMX_U32 port,
5284 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5285{
5286 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5287 unsigned int nPortIndex;
5288 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5289
5290 if(m_state == OMX_StateIdle &&
5291 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5292 {
5293 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5294 }
5295 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5296 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5297 {
5298 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
5299 }
5300 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5301 {
5302 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5303 post_event(OMX_EventError,
5304 OMX_ErrorPortUnpopulated,
5305 OMX_COMPONENT_GENERATE_EVENT);
5306
5307 return OMX_ErrorIncorrectStateOperation;
5308 }
5309 else if (m_state != OMX_StateInvalid)
5310 {
5311 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5312 post_event(OMX_EventError,
5313 OMX_ErrorPortUnpopulated,
5314 OMX_COMPONENT_GENERATE_EVENT);
5315 }
5316
5317 if(port == OMX_CORE_INPUT_PORT_INDEX)
5318 {
5319 /*Check if arbitrary bytes*/
5320 if(!arbitrary_bytes && !input_use_buffer)
5321 nPortIndex = buffer - m_inp_mem_ptr;
5322 else
5323 nPortIndex = buffer - m_inp_heap_ptr;
5324
5325 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5326 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5327 {
5328 // Clear the bit associated with it.
5329 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5330 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5331 if (input_use_buffer == true)
5332 {
5333
5334 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5335 if(m_phdr_pmem_ptr)
5336 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5337 }
5338 else
5339 {
5340 if (arbitrary_bytes)
5341 {
5342 if(m_phdr_pmem_ptr)
5343 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5344 else
5345 free_input_buffer(nPortIndex,NULL);
5346 }
5347 else
5348 free_input_buffer(buffer);
5349 }
5350 m_inp_bPopulated = OMX_FALSE;
5351 /*Free the Buffer Header*/
5352 if (release_input_done())
5353 {
5354 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5355 free_input_buffer_header();
5356 }
5357 }
5358 else
5359 {
5360 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5361 eRet = OMX_ErrorBadPortIndex;
5362 }
5363
5364 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5365 && release_input_done())
5366 {
5367 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5368 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5369 post_event(OMX_CommandPortDisable,
5370 OMX_CORE_INPUT_PORT_INDEX,
5371 OMX_COMPONENT_GENERATE_EVENT);
5372 }
5373 }
5374 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5375 {
5376 // check if the buffer is valid
5377 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
5378 if(nPortIndex < drv_ctx.op_buf.actualcount)
5379 {
5380 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5381 // Clear the bit associated with it.
5382 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5383 m_out_bPopulated = OMX_FALSE;
5384 free_output_buffer (buffer);
5385
5386 if (release_output_done())
5387 {
5388 free_output_buffer_header();
5389 }
5390 }
5391 else
5392 {
5393 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5394 eRet = OMX_ErrorBadPortIndex;
5395 }
5396 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5397 && release_output_done())
5398 {
5399 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5400
5401 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5402 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5403#ifdef _ANDROID_ICS_
5404 if (m_enable_android_native_buffers)
5405 {
5406 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5407 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5408 }
5409#endif
5410
5411 post_event(OMX_CommandPortDisable,
5412 OMX_CORE_OUTPUT_PORT_INDEX,
5413 OMX_COMPONENT_GENERATE_EVENT);
5414 }
5415 }
5416 else
5417 {
5418 eRet = OMX_ErrorBadPortIndex;
5419 }
5420 if((eRet == OMX_ErrorNone) &&
5421 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5422 {
5423 if(release_done())
5424 {
5425 // Send the callback now
5426 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5427 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5428 OMX_COMPONENT_GENERATE_EVENT);
5429 }
5430 }
5431 return eRet;
5432}
5433
5434
5435/* ======================================================================
5436FUNCTION
5437 omx_vdec::EmptyThisBuffer
5438
5439DESCRIPTION
5440 This routine is used to push the encoded video frames to
5441 the video decoder.
5442
5443PARAMETERS
5444 None.
5445
5446RETURN VALUE
5447 OMX Error None if everything went successful.
5448
5449========================================================================== */
5450OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5451 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5452{
5453 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5454 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5455
5456 if(m_state == OMX_StateInvalid)
5457 {
5458 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5459 return OMX_ErrorInvalidState;
5460 }
5461
5462 if (buffer == NULL)
5463 {
5464 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5465 return OMX_ErrorBadParameter;
5466 }
5467
5468 if (!m_inp_bEnabled)
5469 {
5470 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5471 return OMX_ErrorIncorrectStateOperation;
5472 }
5473
5474 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5475 {
5476 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex);
5477 return OMX_ErrorBadPortIndex;
5478 }
5479
5480#ifdef _ANDROID_
5481 if(iDivXDrmDecrypt)
5482 {
5483 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5484 if(drmErr != OMX_ErrorNone) {
5485 // this error can be ignored
5486 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5487 }
5488 }
5489#endif //_ANDROID_
5490 if (perf_flag)
5491 {
5492 if (!latency)
5493 {
5494 dec_time.stop();
5495 latency = dec_time.processing_time_us();
5496 dec_time.start();
5497 }
5498 }
5499
5500 if (arbitrary_bytes)
5501 {
5502 nBufferIndex = buffer - m_inp_heap_ptr;
5503 }
5504 else
5505 {
5506 if (input_use_buffer == true)
5507 {
5508 nBufferIndex = buffer - m_inp_heap_ptr;
5509 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5510 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5511 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5512 buffer = &m_inp_mem_ptr[nBufferIndex];
5513 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d",
5514 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5515 }
5516 else{
5517 nBufferIndex = buffer - m_inp_mem_ptr;
5518 }
5519 }
5520
5521 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5522 {
5523 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5524 return OMX_ErrorBadParameter;
5525 }
5526
5527 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5528 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5529 if (arbitrary_bytes)
5530 {
5531 post_event ((unsigned)hComp,(unsigned)buffer,
5532 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5533 }
5534 else
5535 {
5536 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5537 set_frame_rate(buffer->nTimeStamp);
5538 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5539 }
5540 return OMX_ErrorNone;
5541}
5542
5543/* ======================================================================
5544FUNCTION
5545 omx_vdec::empty_this_buffer_proxy
5546
5547DESCRIPTION
5548 This routine is used to push the encoded video frames to
5549 the video decoder.
5550
5551PARAMETERS
5552 None.
5553
5554RETURN VALUE
5555 OMX Error None if everything went successful.
5556
5557========================================================================== */
5558OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5559 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5560{
5561 int push_cnt = 0,i=0;
5562 unsigned nPortIndex = 0;
5563 OMX_ERRORTYPE ret = OMX_ErrorNone;
5564 struct vdec_input_frameinfo frameinfo;
5565 struct vdec_bufferpayload *temp_buffer;
5566 struct vdec_ioctl_msg ioctl_msg;
5567 struct vdec_seqheader seq_header;
5568 bool port_setting_changed = true;
5569 bool not_coded_vop = false;
5570
5571 /*Should we generate a Aync error event*/
5572 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5573 {
5574 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5575 return OMX_ErrorBadParameter;
5576 }
5577
5578 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5579
5580 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5581 {
5582 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5583 nPortIndex);
5584 return OMX_ErrorBadParameter;
5585 }
5586
5587 pending_input_buffers++;
5588
5589 /* return zero length and not an EOS buffer */
5590 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5591 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5592 {
5593 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5594 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5595 OMX_COMPONENT_GENERATE_EBD);
5596 return OMX_ErrorNone;
5597 }
5598
5599
5600 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5601 mp4StreamType psBits;
5602 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5603 psBits.numBytes = buffer->nFilledLen;
5604 mp4_headerparser.parseHeader(&psBits);
5605 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5606 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5607 if(not_coded_vop) {
5608 DEBUG_PRINT_HIGH("\n Found Not coded vop len %d frame number %d",
5609 buffer->nFilledLen,frame_count);
5610 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5611 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5612 not_coded_vop = false;
5613 buffer->nFilledLen = 0;
5614 }
5615 }
5616 }
5617
5618 if(input_flush_progress == true
5619
5620 || not_coded_vop
5621
5622 )
5623 {
5624 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5625 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5626 OMX_COMPONENT_GENERATE_EBD);
5627 return OMX_ErrorNone;
5628 }
5629
5630 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5631
5632 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5633 {
5634 return OMX_ErrorBadParameter;
5635 }
5636
5637 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5638 /*for use buffer we need to memcpy the data*/
5639 temp_buffer->buffer_len = buffer->nFilledLen;
5640
5641 if (input_use_buffer)
5642 {
5643 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5644 {
5645 if(arbitrary_bytes)
5646 {
5647 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5648 }
5649 else
5650 {
5651 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5652 buffer->nFilledLen);
5653 }
5654 }
5655 else
5656 {
5657 return OMX_ErrorBadParameter;
5658 }
5659
5660 }
5661
5662 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5663 frameinfo.client_data = (void *) buffer;
5664 frameinfo.datalen = temp_buffer->buffer_len;
5665 frameinfo.flags = 0;
5666 frameinfo.offset = buffer->nOffset;
5667 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5668 frameinfo.pmem_offset = temp_buffer->offset;
5669 frameinfo.timestamp = buffer->nTimeStamp;
5670 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5671 {
5672 DEBUG_PRINT_LOW("ETB: dmx enabled");
5673 if (m_demux_entries == 0)
5674 {
5675 extract_demux_addr_offsets(buffer);
5676 }
5677
5678 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries);
5679 handle_demux_data(buffer);
5680 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5681 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5682 }
5683 else
5684 {
5685 frameinfo.desc_addr = NULL;
5686 frameinfo.desc_size = 0;
5687 }
5688 if(!arbitrary_bytes)
5689 {
5690 frameinfo.flags |= buffer->nFlags;
5691 }
5692
5693#ifdef _ANDROID_
5694 if (m_debug_timestamp)
5695 {
5696 if(arbitrary_bytes)
5697 {
5698 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5699 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5700 }
5701 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5702 {
5703 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5704 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5705 }
5706 }
5707#endif
5708
5709#ifdef INPUT_BUFFER_LOG
5710 if (inputBufferFile1)
5711 {
5712 fwrite((const char *)temp_buffer->bufferaddr,
5713 temp_buffer->buffer_len,1,inputBufferFile1);
5714 }
5715#endif
5716
5717 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5718 {
5719 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5720 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5721 }
5722
5723 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5724 {
5725 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5726 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5727 h264_scratch.nFilledLen = 0;
5728 nal_count = 0;
5729 look_ahead_nal = false;
5730 frame_count = 0;
5731 if (m_frame_parser.mutils)
5732 m_frame_parser.mutils->initialize_frame_checking_environment();
5733 m_frame_parser.flush();
5734 h264_last_au_ts = LLONG_MAX;
5735 h264_last_au_flags = 0;
5736 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5737 m_demux_entries = 0;
5738 }
5739 struct v4l2_buffer buf = {0};
5740 struct v4l2_plane plane;
5741 int rc;
5742 unsigned long print_count;
5743 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5744 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005745 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005746 }
5747 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5748 buf.index = nPortIndex;
5749 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5750 buf.memory = V4L2_MEMORY_USERPTR;
5751 plane.bytesused = temp_buffer->buffer_len;
5752 plane.length = drv_ctx.ip_buf.buffer_size;
5753 plane.m.userptr = (unsigned long)(temp_buffer->bufferaddr-temp_buffer->offset);
5754 plane.reserved[0] = temp_buffer->pmem_fd;
5755 plane.reserved[1] = temp_buffer->offset;
5756 plane.data_offset = 0;
5757 buf.m.planes = &plane;
5758 buf.length = 1;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005759 //assumption is that timestamp is in milliseconds
5760 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5761 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005762 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5763
Shalaj Jain273b3e02012-06-22 19:08:03 -07005764 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005765 if(rc)
5766 {
5767 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5768 return OMX_ErrorHardware;
5769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770 if(!streaming[OUTPUT_PORT])
5771 {
5772 enum v4l2_buf_type buf_type;
5773 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005774
Shalaj Jain273b3e02012-06-22 19:08:03 -07005775 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5776 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5777 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5778 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005779 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005780 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005781 } else{
5782 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005783 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005784 }
5785}
5786 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5787 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5788 time_stamp_dts.insert_timestamp(buffer);
5789
5790 return ret;
5791}
5792
5793/* ======================================================================
5794FUNCTION
5795 omx_vdec::FillThisBuffer
5796
5797DESCRIPTION
5798 IL client uses this method to release the frame buffer
5799 after displaying them.
5800
5801PARAMETERS
5802 None.
5803
5804RETURN VALUE
5805 true/false
5806
5807========================================================================== */
5808OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5809 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5810{
5811
5812 if(m_state == OMX_StateInvalid)
5813 {
5814 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5815 return OMX_ErrorInvalidState;
5816 }
5817
5818 if (!m_out_bEnabled)
5819 {
5820 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5821 return OMX_ErrorIncorrectStateOperation;
5822 }
5823
5824 if (buffer == NULL || ((buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount))
5825 {
5826 return OMX_ErrorBadParameter;
5827 }
5828
5829 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5830 {
5831 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex);
5832 return OMX_ErrorBadPortIndex;
5833 }
5834
5835 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5836 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
5837 return OMX_ErrorNone;
5838}
5839/* ======================================================================
5840FUNCTION
5841 omx_vdec::fill_this_buffer_proxy
5842
5843DESCRIPTION
5844 IL client uses this method to release the frame buffer
5845 after displaying them.
5846
5847PARAMETERS
5848 None.
5849
5850RETURN VALUE
5851 true/false
5852
5853========================================================================== */
5854OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5855 OMX_IN OMX_HANDLETYPE hComp,
5856 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5857{
5858 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5859 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
5860 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5861 unsigned nPortIndex = 0;
5862 struct vdec_fillbuffer_cmd fillbuffer;
5863 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5864 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5865
5866 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_out_mem_ptr);
5867
5868 if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) >
5869 drv_ctx.op_buf.actualcount) )
5870 return OMX_ErrorBadParameter;
5871
5872 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5873 bufferAdd, bufferAdd->pBuffer);
5874 /*Return back the output buffer to client*/
5875 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5876 {
5877 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5878 buffer->nFilledLen = 0;
5879 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5880 return OMX_ErrorNone;
5881 }
5882 pending_output_buffers++;
5883 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5884 if (ptr_respbuffer)
5885 {
5886 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5887 }
5888
5889 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5890 {
5891 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5892 buffer->nFilledLen = 0;
5893 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5894 pending_output_buffers--;
5895 return OMX_ErrorBadParameter;
5896 }
5897
5898 // memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
5899 sizeof(struct vdec_bufferpayload));
5900 // fillbuffer.client_data = bufferAdd;
5901
5902#ifdef _ANDROID_ICS_
5903 if (m_enable_android_native_buffers)
5904 {
5905 // Acquire a write lock on this buffer.
5906 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5907 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5908 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5909 buffer->nFilledLen = 0;
5910 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5911 pending_output_buffers--;
5912 return OMX_ErrorInsufficientResources;
5913 } else {
5914 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5915 }
5916 }
5917#endif
5918 int rc = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005919 struct v4l2_buffer buf={0};
5920 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5921 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005923 buf.index = nPortIndex;
5924 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5925 buf.memory = V4L2_MEMORY_USERPTR;
5926 plane[0].bytesused = buffer->nFilledLen;
5927 plane[0].length = drv_ctx.op_buf.buffer_size;
5928 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr-drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5929 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5930 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5931 plane[0].data_offset = 0;
5932 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5933 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5934 plane[extra_idx].bytesused = 0;
5935 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5936 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5937#ifdef USE_ION
5938 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5939#endif
5940 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5941 plane[extra_idx].data_offset = 0;
5942 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5943 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5944 return OMX_ErrorBadParameter;
5945 }
5946 buf.m.planes = plane;
5947 buf.length = drv_ctx.num_planes;
5948 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5949 if (rc) {
5950 /*TODO: How to handle this case */
5951 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5952 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005953//#ifdef _ANDROID_ICS_
5954 // if (m_enable_android_native_buffers)
5955 // {
5956 // Unlock the buffer
5957 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
5958 // DEBUG_PRINT_ERROR("Releasing genlock failed");
5959 // return OMX_ErrorInsufficientResources;
5960 /// } else {
5961 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
5962 // }
5963 // }
5964//#endif
5965 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
5966 // pending_output_buffers--;
5967 // return OMX_ErrorBadParameter;
5968 //}
5969 return OMX_ErrorNone;
5970}
5971
5972/* ======================================================================
5973FUNCTION
5974 omx_vdec::SetCallbacks
5975
5976DESCRIPTION
5977 Set the callbacks.
5978
5979PARAMETERS
5980 None.
5981
5982RETURN VALUE
5983 OMX Error None if everything successful.
5984
5985========================================================================== */
5986OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
5987 OMX_IN OMX_CALLBACKTYPE* callbacks,
5988 OMX_IN OMX_PTR appData)
5989{
5990
5991 m_cb = *callbacks;
5992 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5993 m_cb.EventHandler,m_cb.FillBufferDone);
5994 m_app_data = appData;
5995 return OMX_ErrorNotImplemented;
5996}
5997
5998/* ======================================================================
5999FUNCTION
6000 omx_vdec::ComponentDeInit
6001
6002DESCRIPTION
6003 Destroys the component and release memory allocated to the heap.
6004
6005PARAMETERS
6006 <TBD>.
6007
6008RETURN VALUE
6009 OMX Error None if everything successful.
6010
6011========================================================================== */
6012OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6013{
6014#ifdef _ANDROID_
6015 if(iDivXDrmDecrypt)
6016 {
6017 delete iDivXDrmDecrypt;
6018 iDivXDrmDecrypt=NULL;
6019 }
6020#endif //_ANDROID_
6021
6022 int i = 0;
6023 if (OMX_StateLoaded != m_state)
6024 {
6025 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6026 m_state);
6027 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6028 }
6029 else
6030 {
6031 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6032 }
6033
6034 /*Check if the output buffers have to be cleaned up*/
6035 if(m_out_mem_ptr)
6036 {
6037 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
6038 for (i=0; i < drv_ctx.op_buf.actualcount; i++ )
6039 {
6040 free_output_buffer (&m_out_mem_ptr[i]);
6041#ifdef _ANDROID_ICS_
6042 if (m_enable_android_native_buffers)
6043 {
6044 if (native_buffer[i].inuse)
6045 {
6046 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6047 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6048 }
6049 native_buffer[i].inuse = false;
6050 }
6051 }
6052#endif
6053 }
6054#ifdef _ANDROID_ICS_
6055 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6056#endif
6057 }
6058
6059 /*Check if the input buffers have to be cleaned up*/
6060 if(m_inp_mem_ptr || m_inp_heap_ptr)
6061 {
6062 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
6063 for (i=0; i<drv_ctx.ip_buf.actualcount; i++ )
6064 {
6065 if (m_inp_mem_ptr)
6066 free_input_buffer (i,&m_inp_mem_ptr[i]);
6067 else
6068 free_input_buffer (i,NULL);
6069 }
6070 }
6071 free_input_buffer_header();
6072 free_output_buffer_header();
6073 if(h264_scratch.pBuffer)
6074 {
6075 free(h264_scratch.pBuffer);
6076 h264_scratch.pBuffer = NULL;
6077 }
6078
6079 if (h264_parser)
6080 {
6081 delete h264_parser;
6082 h264_parser = NULL;
6083 }
6084
6085 if(m_platform_list)
6086 {
6087 free(m_platform_list);
6088 m_platform_list = NULL;
6089 }
6090 if(m_vendor_config.pData)
6091 {
6092 free(m_vendor_config.pData);
6093 m_vendor_config.pData = NULL;
6094 }
6095
6096 // Reset counters in mesg queues
6097 m_ftb_q.m_size=0;
6098 m_cmd_q.m_size=0;
6099 m_etb_q.m_size=0;
6100 m_ftb_q.m_read = m_ftb_q.m_write =0;
6101 m_cmd_q.m_read = m_cmd_q.m_write =0;
6102 m_etb_q.m_read = m_etb_q.m_write =0;
6103#ifdef _ANDROID_
6104 if (m_debug_timestamp)
6105 {
6106 m_timestamp_list.reset_ts_list();
6107 }
6108#endif
6109
6110 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6111 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6112 // NULL);
6113 DEBUG_PRINT_HIGH("\n Close the driver instance");
6114
6115#ifdef INPUT_BUFFER_LOG
6116 fclose (inputBufferFile1);
6117#endif
6118#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006119 if (outputBufferFile1)
6120 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006121#endif
6122#ifdef OUTPUT_EXTRADATA_LOG
6123 fclose (outputExtradataFile);
6124#endif
6125 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6126 return OMX_ErrorNone;
6127}
6128
6129/* ======================================================================
6130FUNCTION
6131 omx_vdec::UseEGLImage
6132
6133DESCRIPTION
6134 OMX Use EGL Image method implementation <TBD>.
6135
6136PARAMETERS
6137 <TBD>.
6138
6139RETURN VALUE
6140 Not Implemented error.
6141
6142========================================================================== */
6143OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6144 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6145 OMX_IN OMX_U32 port,
6146 OMX_IN OMX_PTR appData,
6147 OMX_IN void* eglImage)
6148{
6149 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6150 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6151 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6152
6153#ifdef USE_EGL_IMAGE_GPU
6154 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6155 EGLint fd = -1, offset = 0,pmemPtr = 0;
6156#else
6157 int fd = -1, offset = 0;
6158#endif
6159 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6160 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6161 DEBUG_PRINT_ERROR("\n ");
6162 }
6163#ifdef USE_EGL_IMAGE_GPU
6164 if(m_display_id == NULL) {
6165 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6166 return OMX_ErrorInsufficientResources;
6167 }
6168 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6169 eglGetProcAddress("eglQueryImageKHR");
6170 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6171 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6172 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6173#else //with OMX test app
6174 struct temp_egl {
6175 int pmem_fd;
6176 int offset;
6177 };
6178 struct temp_egl *temp_egl_id = NULL;
6179 void * pmemPtr = (void *) eglImage;
6180 temp_egl_id = (struct temp_egl *)eglImage;
6181 if (temp_egl_id != NULL)
6182 {
6183 fd = temp_egl_id->pmem_fd;
6184 offset = temp_egl_id->offset;
6185 }
6186#endif
6187 if (fd < 0) {
6188 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6189 return OMX_ErrorInsufficientResources;
6190 }
6191 pmem_info.pmem_fd = (OMX_U32) fd;
6192 pmem_info.offset = (OMX_U32) offset;
6193 pmem_entry.entry = (void *) &pmem_info;
6194 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6195 pmem_list.entryList = &pmem_entry;
6196 pmem_list.nEntries = 1;
6197 ouput_egl_buffers = true;
6198 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6199 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6200 (OMX_U8 *)pmemPtr)) {
6201 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6202 return OMX_ErrorInsufficientResources;
6203 }
6204 return OMX_ErrorNone;
6205}
6206
6207/* ======================================================================
6208FUNCTION
6209 omx_vdec::ComponentRoleEnum
6210
6211DESCRIPTION
6212 OMX Component Role Enum method implementation.
6213
6214PARAMETERS
6215 <TBD>.
6216
6217RETURN VALUE
6218 OMX Error None if everything is successful.
6219========================================================================== */
6220OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6221 OMX_OUT OMX_U8* role,
6222 OMX_IN OMX_U32 index)
6223{
6224 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6225
6226 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6227 {
6228 if((0 == index) && role)
6229 {
6230 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6231 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6232 }
6233 else
6234 {
6235 eRet = OMX_ErrorNoMore;
6236 }
6237 }
6238 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6239 {
6240 if((0 == index) && role)
6241 {
6242 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6243 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6244 }
6245 else
6246 {
6247 eRet = OMX_ErrorNoMore;
6248 }
6249 }
6250 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6251 {
6252 if((0 == index) && role)
6253 {
6254 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6255 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6256 }
6257 else
6258 {
6259 DEBUG_PRINT_LOW("\n No more roles \n");
6260 eRet = OMX_ErrorNoMore;
6261 }
6262 }
6263
6264 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6265 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6266 )
6267
6268 {
6269 if((0 == index) && role)
6270 {
6271 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6272 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6273 }
6274 else
6275 {
6276 DEBUG_PRINT_LOW("\n No more roles \n");
6277 eRet = OMX_ErrorNoMore;
6278 }
6279 }
6280 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6281 {
6282 if((0 == index) && role)
6283 {
6284 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6285 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6286 }
6287 else
6288 {
6289 DEBUG_PRINT_LOW("\n No more roles \n");
6290 eRet = OMX_ErrorNoMore;
6291 }
6292 }
6293 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6294 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6295 )
6296 {
6297 if((0 == index) && role)
6298 {
6299 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6300 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6301 }
6302 else
6303 {
6304 DEBUG_PRINT_LOW("\n No more roles \n");
6305 eRet = OMX_ErrorNoMore;
6306 }
6307 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006308 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6309 {
6310 if((0 == index) && role)
6311 {
6312 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6313 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6314 }
6315 else
6316 {
6317 DEBUG_PRINT_LOW("\n No more roles \n");
6318 eRet = OMX_ErrorNoMore;
6319 }
6320 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006321 else
6322 {
6323 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6324 eRet = OMX_ErrorInvalidComponentName;
6325 }
6326 return eRet;
6327}
6328
6329
6330
6331
6332/* ======================================================================
6333FUNCTION
6334 omx_vdec::AllocateDone
6335
6336DESCRIPTION
6337 Checks if entire buffer pool is allocated by IL Client or not.
6338 Need this to move to IDLE state.
6339
6340PARAMETERS
6341 None.
6342
6343RETURN VALUE
6344 true/false.
6345
6346========================================================================== */
6347bool omx_vdec::allocate_done(void)
6348{
6349 bool bRet = false;
6350 bool bRet_In = false;
6351 bool bRet_Out = false;
6352
6353 bRet_In = allocate_input_done();
6354 bRet_Out = allocate_output_done();
6355
6356 if(bRet_In && bRet_Out)
6357 {
6358 bRet = true;
6359 }
6360
6361 return bRet;
6362}
6363/* ======================================================================
6364FUNCTION
6365 omx_vdec::AllocateInputDone
6366
6367DESCRIPTION
6368 Checks if I/P buffer pool is allocated by IL Client or not.
6369
6370PARAMETERS
6371 None.
6372
6373RETURN VALUE
6374 true/false.
6375
6376========================================================================== */
6377bool omx_vdec::allocate_input_done(void)
6378{
6379 bool bRet = false;
6380 unsigned i=0;
6381
6382 if (m_inp_mem_ptr == NULL)
6383 {
6384 return bRet;
6385 }
6386 if(m_inp_mem_ptr )
6387 {
6388 for(;i<drv_ctx.ip_buf.actualcount;i++)
6389 {
6390 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6391 {
6392 break;
6393 }
6394 }
6395 }
6396 if(i == drv_ctx.ip_buf.actualcount)
6397 {
6398 bRet = true;
6399 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6400 }
6401 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6402 {
6403 m_inp_bPopulated = OMX_TRUE;
6404 }
6405 return bRet;
6406}
6407/* ======================================================================
6408FUNCTION
6409 omx_vdec::AllocateOutputDone
6410
6411DESCRIPTION
6412 Checks if entire O/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_output_done(void)
6422{
6423 bool bRet = false;
6424 unsigned j=0;
6425
6426 if (m_out_mem_ptr == NULL)
6427 {
6428 return bRet;
6429 }
6430
6431 if (m_out_mem_ptr)
6432 {
6433 for(;j < drv_ctx.op_buf.actualcount;j++)
6434 {
6435 if(BITMASK_ABSENT(&m_out_bm_count,j))
6436 {
6437 break;
6438 }
6439 }
6440 }
6441
6442 if(j == drv_ctx.op_buf.actualcount)
6443 {
6444 bRet = true;
6445 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6446 if(m_out_bEnabled)
6447 m_out_bPopulated = OMX_TRUE;
6448 }
6449
6450 return bRet;
6451}
6452
6453/* ======================================================================
6454FUNCTION
6455 omx_vdec::ReleaseDone
6456
6457DESCRIPTION
6458 Checks if IL client has released all the buffers.
6459
6460PARAMETERS
6461 None.
6462
6463RETURN VALUE
6464 true/false
6465
6466========================================================================== */
6467bool omx_vdec::release_done(void)
6468{
6469 bool bRet = false;
6470
6471 if(release_input_done())
6472 {
6473 if(release_output_done())
6474 {
6475 bRet = true;
6476 }
6477 }
6478 return bRet;
6479}
6480
6481
6482/* ======================================================================
6483FUNCTION
6484 omx_vdec::ReleaseOutputDone
6485
6486DESCRIPTION
6487 Checks if IL client has released all the buffers.
6488
6489PARAMETERS
6490 None.
6491
6492RETURN VALUE
6493 true/false
6494
6495========================================================================== */
6496bool omx_vdec::release_output_done(void)
6497{
6498 bool bRet = false;
6499 unsigned i=0,j=0;
6500
6501 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6502 if(m_out_mem_ptr)
6503 {
6504 for(;j < drv_ctx.op_buf.actualcount ; j++)
6505 {
6506 if(BITMASK_PRESENT(&m_out_bm_count,j))
6507 {
6508 break;
6509 }
6510 }
6511 if(j == drv_ctx.op_buf.actualcount)
6512 {
6513 m_out_bm_count = 0;
6514 bRet = true;
6515 }
6516 }
6517 else
6518 {
6519 m_out_bm_count = 0;
6520 bRet = true;
6521 }
6522 return bRet;
6523}
6524/* ======================================================================
6525FUNCTION
6526 omx_vdec::ReleaseInputDone
6527
6528DESCRIPTION
6529 Checks if IL client has released all the buffers.
6530
6531PARAMETERS
6532 None.
6533
6534RETURN VALUE
6535 true/false
6536
6537========================================================================== */
6538bool omx_vdec::release_input_done(void)
6539{
6540 bool bRet = false;
6541 unsigned i=0,j=0;
6542
6543 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6544 if(m_inp_mem_ptr)
6545 {
6546 for(;j<drv_ctx.ip_buf.actualcount;j++)
6547 {
6548 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6549 {
6550 break;
6551 }
6552 }
6553 if(j==drv_ctx.ip_buf.actualcount)
6554 {
6555 bRet = true;
6556 }
6557 }
6558 else
6559 {
6560 bRet = true;
6561 }
6562 return bRet;
6563}
6564
6565OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6566 OMX_BUFFERHEADERTYPE * buffer)
6567{
6568 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6569 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6570 {
6571 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6572 return OMX_ErrorBadParameter;
6573 }
6574 else if (output_flush_progress)
6575 {
6576 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6577 buffer->nFilledLen = 0;
6578 buffer->nTimeStamp = 0;
6579 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6580 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6581 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6582 }
6583
6584 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6585 buffer, buffer->pBuffer);
6586 pending_output_buffers --;
6587
6588 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6589 {
6590 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6591 if (!output_flush_progress)
6592 post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE);
6593
6594 if (psource_frame)
6595 {
6596 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6597 psource_frame = NULL;
6598 }
6599 if (pdest_frame)
6600 {
6601 pdest_frame->nFilledLen = 0;
6602 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6603 pdest_frame = NULL;
6604 }
6605 }
6606
6607 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6608#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006609 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006610 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006611 int buf_index = buffer - m_out_mem_ptr;
6612 int stride = ((drv_ctx.video_resolution.frame_width + 31) & (~31));
6613 int scanlines = ((drv_ctx.video_resolution.frame_height+31) & (~31));
6614 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
6615 int i;
6616 int bytes_written = 0;
6617 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6618 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6619 temp += stride;
6620 }
6621 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
6622 int stride_c = ((drv_ctx.video_resolution.frame_width/2 + 31) & (~31))*2;
6623 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6624 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6625 temp += stride_c;
6626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006627 }
6628#endif
6629
6630 /* For use buffer we need to copy the data */
6631 if (!output_flush_progress)
6632 {
6633 time_stamp_dts.get_next_timestamp(buffer,
6634 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6635 ?true:false);
6636 }
6637 if (m_cb.FillBufferDone)
6638 {
6639 if (buffer->nFilledLen > 0)
6640 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006641 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006642 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6643 // Keep min timestamp interval to handle corrupted bit stream scenario
6644 set_frame_rate(buffer->nTimeStamp);
6645 else if (arbitrary_bytes)
6646 adjust_timestamp(buffer->nTimeStamp);
6647 if (perf_flag)
6648 {
6649 if (!proc_frms)
6650 {
6651 dec_time.stop();
6652 latency = dec_time.processing_time_us() - latency;
6653 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6654 dec_time.start();
6655 fps_metrics.start();
6656 }
6657 proc_frms++;
6658 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6659 {
6660 OMX_U64 proc_time = 0;
6661 fps_metrics.stop();
6662 proc_time = fps_metrics.processing_time_us();
6663 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6664 proc_frms, (float)proc_time / 1e6,
6665 (float)(1e6 * proc_frms) / proc_time);
6666 proc_frms = 0;
6667 }
6668 }
6669
6670#ifdef OUTPUT_EXTRADATA_LOG
6671 if (outputExtradataFile)
6672 {
6673
6674 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6675 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6676 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6677 buffer->nFilledLen + 3)&(~3));
6678 while(p_extra &&
6679 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6680 {
6681 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6682 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6683 if (p_extra->eType == OMX_ExtraDataNone)
6684 {
6685 break;
6686 }
6687 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6688 }
6689 }
6690#endif
6691 }
6692 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6693 prev_ts = LLONG_MAX;
6694 rst_prev_ts = true;
6695 }
6696
6697 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6698 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6699 buffer->pPlatformPrivate)->entryList->entry;
6700 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
6701#ifdef _ANDROID_ICS_
6702 if (m_enable_android_native_buffers)
6703 {
6704 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6705 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6706 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6707 return OMX_ErrorInsufficientResources;
6708 }
6709 else {
6710 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6711 }
6712 }
6713 }
6714#endif
6715 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6716 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
6717 }
6718 else
6719 {
6720 return OMX_ErrorBadParameter;
6721 }
6722
6723 return OMX_ErrorNone;
6724}
6725
6726OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6727 OMX_BUFFERHEADERTYPE* buffer)
6728{
6729
6730 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6731 {
6732 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6733 return OMX_ErrorBadParameter;
6734 }
6735
6736 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6737 buffer, buffer->pBuffer);
6738 pending_input_buffers--;
6739
6740 if (arbitrary_bytes)
6741 {
6742 if (pdest_frame == NULL && input_flush_progress == false)
6743 {
6744 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6745 pdest_frame = buffer;
6746 buffer->nFilledLen = 0;
6747 buffer->nTimeStamp = LLONG_MAX;
6748 push_input_buffer (hComp);
6749 }
6750 else
6751 {
6752 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6753 buffer->nFilledLen = 0;
6754 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
6755 {
6756 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6757 }
6758 }
6759 }
6760 else if(m_cb.EmptyBufferDone)
6761 {
6762 buffer->nFilledLen = 0;
6763 if (input_use_buffer == true){
6764 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6765 }
6766 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6767 }
6768 return OMX_ErrorNone;
6769}
6770
Shalaj Jain273b3e02012-06-22 19:08:03 -07006771int omx_vdec::async_message_process (void *context, void* message)
6772{
6773 omx_vdec* omx = NULL;
6774 struct vdec_msginfo *vdec_msg = NULL;
6775 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6776 struct v4l2_buffer *v4l2_buf_ptr=NULL;
6777 struct vdec_output_frameinfo *output_respbuf = NULL;
6778 int rc=1;
6779 if (context == NULL || message == NULL)
6780 {
6781 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6782 return -1;
6783 }
6784 vdec_msg = (struct vdec_msginfo *)message;
6785
6786 omx = reinterpret_cast<omx_vdec*>(context);
6787
6788#ifdef _ANDROID_
6789 if (omx->m_debug_timestamp)
6790 {
6791 if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) &&
6792 !(omx->output_flush_progress) )
6793 {
6794 OMX_TICKS expected_ts = 0;
6795 omx->m_timestamp_list.pop_min_ts(expected_ts);
6796 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6797 vdec_msg->msgdata.output_frame.time_stamp, expected_ts);
6798
6799 if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts)
6800 {
6801 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6802 }
6803 }
6804 }
6805#endif
6806
6807 switch (vdec_msg->msgcode)
6808 {
6809
6810 case VDEC_MSG_EVT_HW_ERROR:
6811 omx->post_event (NULL,vdec_msg->status_code,\
6812 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6813 break;
6814
6815 case VDEC_MSG_RESP_START_DONE:
6816 omx->post_event (NULL,vdec_msg->status_code,\
6817 OMX_COMPONENT_GENERATE_START_DONE);
6818 break;
6819
6820 case VDEC_MSG_RESP_STOP_DONE:
6821 omx->post_event (NULL,vdec_msg->status_code,\
6822 OMX_COMPONENT_GENERATE_STOP_DONE);
6823 break;
6824
6825 case VDEC_MSG_RESP_RESUME_DONE:
6826 omx->post_event (NULL,vdec_msg->status_code,\
6827 OMX_COMPONENT_GENERATE_RESUME_DONE);
6828 break;
6829
6830 case VDEC_MSG_RESP_PAUSE_DONE:
6831 omx->post_event (NULL,vdec_msg->status_code,\
6832 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6833 break;
6834
6835 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6836 omx->post_event (NULL,vdec_msg->status_code,\
6837 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6838 break;
6839 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6840 omx->post_event (NULL,vdec_msg->status_code,\
6841 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6842 break;
6843 case VDEC_MSG_RESP_INPUT_FLUSHED:
6844 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6845
6846 // omxhdr = (OMX_BUFFERHEADERTYPE* ) \
6847 // vdec_msg->msgdata.input_frame_clientdata;
6848
6849 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6850 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6851 if (omxhdr == NULL ||
6852 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6853 {
6854 omxhdr = NULL;
6855 vdec_msg->status_code = VDEC_S_EFATAL;
6856 }
6857
6858 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6859 OMX_COMPONENT_GENERATE_EBD);
6860 break;
6861 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6862 int64_t *timestamp;
6863 timestamp = (int64_t *) malloc(sizeof(int64_t));
6864 if (timestamp) {
6865 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6866 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6867 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6868 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6869 vdec_msg->msgdata.output_frame.time_stamp);
6870 }
6871 break;
6872 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6873 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6874
6875 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6876 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6877 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6878 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6879 vdec_msg->msgdata.output_frame.pic_type);
6880
6881 if (omxhdr && omxhdr->pOutputPortPrivate &&
6882 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6883 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6884 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6885 {
6886 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6887 {
6888 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6889 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006890 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006891 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6892
6893 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6894 {
6895 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6896 //rc = -1;
6897 }
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08006898 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6899 {
6900 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6901 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006902 vdec_msg->msgdata.output_frame.bufferaddr=omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6903 output_respbuf = (struct vdec_output_frameinfo *)\
6904 omxhdr->pOutputPortPrivate;
6905 // output_respbuf->framesize.bottom =
6906 // vdec_msg->msgdata.output_frame.framesize.bottom;
6907 // output_respbuf->framesize.left =
6908 // vdec_msg->msgdata.output_frame.framesize.left;
6909 // output_respbuf->framesize.right =
6910 // vdec_msg->msgdata.output_frame.framesize.right;
6911 // output_respbuf->framesize.top =
6912 // vdec_msg->msgdata.output_frame.framesize.top;
6913 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6914 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6915 // output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp;
6916 // output_respbuf->flags = vdec_msg->msgdata.output_frame.flags;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006917 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
6918 {
6919 output_respbuf->pic_type = PICTURE_TYPE_I;
6920 }
6921 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
6922 {
6923 output_respbuf->pic_type = PICTURE_TYPE_P;
6924 }
6925 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6926 output_respbuf->pic_type = PICTURE_TYPE_B;
6927 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006928 // output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format;
6929
6930 if (omx->output_use_buffer)
6931 memcpy ( omxhdr->pBuffer,
6932 (vdec_msg->msgdata.output_frame.bufferaddr +
6933 vdec_msg->msgdata.output_frame.offset),
6934 vdec_msg->msgdata.output_frame.len );
6935 }
6936 else
6937 omxhdr->nFilledLen = 0;
6938 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6939 OMX_COMPONENT_GENERATE_FBD);
6940 }
6941 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6942 omx->post_event (NULL, vdec_msg->status_code,
6943 OMX_COMPONENT_GENERATE_EOS_DONE);
6944 else
6945 omx->post_event (NULL, vdec_msg->status_code,
6946 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6947 break;
6948 case VDEC_MSG_EVT_CONFIG_CHANGED:
6949 DEBUG_PRINT_HIGH("\n Port settings changed");
6950 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6951 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6952 break;
6953 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
6954 {
6955 DEBUG_PRINT_HIGH("\n Port settings changed info");
6956 // get_buffer_req and populate port defn structure
6957 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07006958 struct v4l2_format fmt;
6959 int ret;
6960 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6961 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
6962 omx->drv_ctx.video_resolution.scan_lines = omx->drv_ctx.video_resolution.frame_height = fmt.fmt.pix_mp.height;
6963 omx->drv_ctx.video_resolution.stride = omx->drv_ctx.video_resolution.frame_width = fmt.fmt.pix_mp.width;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006964 omx->m_port_def.nPortIndex = 1;
6965 eRet = omx->update_portdef(&(omx->m_port_def));
Praneeth Paladuguea69de02012-10-30 11:40:17 -07006966 omx->post_event (NULL,vdec_msg->status_code,\
6967 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006968 break;
6969 }
6970 default:
6971 break;
6972 }
6973 return rc;
6974}
6975
6976OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
6977 OMX_HANDLETYPE hComp,
6978 OMX_BUFFERHEADERTYPE *buffer
6979 )
6980{
6981 unsigned address,p2,id;
6982 DEBUG_PRINT_LOW("\n Empty this arbitrary");
6983
6984 if (buffer == NULL)
6985 {
6986 return OMX_ErrorBadParameter;
6987 }
6988 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6989 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
6990 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
6991
6992 /* return zero length and not an EOS buffer */
6993 /* return buffer if input flush in progress */
6994 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6995 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
6996 {
6997 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6998 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6999 return OMX_ErrorNone;
7000 }
7001
7002 if (psource_frame == NULL)
7003 {
7004 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
7005 psource_frame = buffer;
7006 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7007 push_input_buffer (hComp);
7008 }
7009 else
7010 {
7011 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
7012 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
7013 {
7014 return OMX_ErrorBadParameter;
7015 }
7016 }
7017
7018
7019 return OMX_ErrorNone;
7020}
7021
7022OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7023{
7024 unsigned address,p2,id;
7025 OMX_ERRORTYPE ret = OMX_ErrorNone;
7026
7027 if (pdest_frame == NULL || psource_frame == NULL)
7028 {
7029 /*Check if we have a destination buffer*/
7030 if (pdest_frame == NULL)
7031 {
7032 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7033 if (m_input_free_q.m_size)
7034 {
7035 m_input_free_q.pop_entry(&address,&p2,&id);
7036 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7037 pdest_frame->nFilledLen = 0;
7038 pdest_frame->nTimeStamp = LLONG_MAX;
7039 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7040 }
7041 }
7042
7043 /*Check if we have a destination buffer*/
7044 if (psource_frame == NULL)
7045 {
7046 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7047 if (m_input_pending_q.m_size)
7048 {
7049 m_input_pending_q.pop_entry(&address,&p2,&id);
7050 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
7051 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7052 psource_frame->nTimeStamp);
7053 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7054 psource_frame->nFlags,psource_frame->nFilledLen);
7055
7056 }
7057 }
7058
7059 }
7060
7061 while ((pdest_frame != NULL) && (psource_frame != NULL))
7062 {
7063 switch (codec_type_parse)
7064 {
7065 case CODEC_TYPE_MPEG4:
7066 case CODEC_TYPE_H263:
7067 case CODEC_TYPE_MPEG2:
7068 ret = push_input_sc_codec(hComp);
7069 break;
7070 case CODEC_TYPE_H264:
7071 ret = push_input_h264(hComp);
7072 break;
7073 case CODEC_TYPE_VC1:
7074 ret = push_input_vc1(hComp);
7075 break;
7076 }
7077 if (ret != OMX_ErrorNone)
7078 {
7079 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7080 omx_report_error ();
7081 break;
7082 }
7083 }
7084
7085 return ret;
7086}
7087
7088OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7089{
7090 OMX_U32 partial_frame = 1;
7091 OMX_BOOL generate_ebd = OMX_TRUE;
7092 unsigned address,p2,id;
7093
7094 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
7095 psource_frame,psource_frame->nTimeStamp);
7096 if (m_frame_parser.parse_sc_frame(psource_frame,
7097 pdest_frame,&partial_frame) == -1)
7098 {
7099 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7100 return OMX_ErrorBadParameter;
7101 }
7102
7103 if (partial_frame == 0)
7104 {
7105 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
7106 pdest_frame->nFilledLen,psource_frame,frame_count);
7107
7108
7109 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
7110 /*First Parsed buffer will have only header Hence skip*/
7111 if (frame_count == 0)
7112 {
7113 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7114
7115 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7116 codec_type_parse == CODEC_TYPE_DIVX) {
7117 mp4StreamType psBits;
7118 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7119 psBits.numBytes = pdest_frame->nFilledLen;
7120 mp4_headerparser.parseHeader(&psBits);
7121 }
7122
7123 frame_count++;
7124 }
7125 else
7126 {
7127 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7128 if(pdest_frame->nFilledLen)
7129 {
7130 /*Push the frame to the Decoder*/
7131 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7132 {
7133 return OMX_ErrorBadParameter;
7134 }
7135 frame_count++;
7136 pdest_frame = NULL;
7137
7138 if (m_input_free_q.m_size)
7139 {
7140 m_input_free_q.pop_entry(&address,&p2,&id);
7141 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7142 pdest_frame->nFilledLen = 0;
7143 }
7144 }
7145 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7146 {
7147 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
7148 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
7149 pdest_frame = NULL;
7150 }
7151 }
7152 }
7153 else
7154 {
7155 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
7156 /*Check if Destination Buffer is full*/
7157 if (pdest_frame->nAllocLen ==
7158 pdest_frame->nFilledLen + pdest_frame->nOffset)
7159 {
7160 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7161 return OMX_ErrorStreamCorrupt;
7162 }
7163 }
7164
7165 if (psource_frame->nFilledLen == 0)
7166 {
7167 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7168 {
7169 if (pdest_frame)
7170 {
7171 pdest_frame->nFlags |= psource_frame->nFlags;
7172 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7173 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7174 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7175 pdest_frame->nFilledLen,frame_count++);
7176 /*Push the frame to the Decoder*/
7177 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7178 {
7179 return OMX_ErrorBadParameter;
7180 }
7181 frame_count++;
7182 pdest_frame = NULL;
7183 }
7184 else
7185 {
7186 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7187 generate_ebd = OMX_FALSE;
7188 }
7189 }
7190 if(generate_ebd)
7191 {
7192 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7193 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7194 psource_frame = NULL;
7195
7196 if (m_input_pending_q.m_size)
7197 {
7198 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7199 m_input_pending_q.pop_entry(&address,&p2,&id);
7200 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7201 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7202 psource_frame->nTimeStamp);
7203 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7204 psource_frame->nFlags,psource_frame->nFilledLen);
7205 }
7206 }
7207 }
7208 return OMX_ErrorNone;
7209}
7210
7211OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7212{
7213 OMX_U32 partial_frame = 1;
7214 unsigned address,p2,id;
7215 OMX_BOOL isNewFrame = OMX_FALSE;
7216 OMX_BOOL generate_ebd = OMX_TRUE;
7217
7218 if (h264_scratch.pBuffer == NULL)
7219 {
7220 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7221 return OMX_ErrorBadParameter;
7222 }
7223 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d "
7224 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7225 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7226 if (h264_scratch.nFilledLen && look_ahead_nal)
7227 {
7228 look_ahead_nal = false;
7229 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7230 h264_scratch.nFilledLen)
7231 {
7232 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7233 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7234 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7235 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7236 h264_scratch.nFilledLen = 0;
7237 }
7238 else
7239 {
7240 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7241 return OMX_ErrorBadParameter;
7242 }
7243 }
7244 if (nal_length == 0)
7245 {
7246 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7247 if (m_frame_parser.parse_sc_frame(psource_frame,
7248 &h264_scratch,&partial_frame) == -1)
7249 {
7250 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7251 return OMX_ErrorBadParameter;
7252 }
7253 }
7254 else
7255 {
7256 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7257 if (m_frame_parser.parse_h264_nallength(psource_frame,
7258 &h264_scratch,&partial_frame) == -1)
7259 {
7260 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7261 return OMX_ErrorBadParameter;
7262 }
7263 }
7264
7265 if (partial_frame == 0)
7266 {
7267 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7268 {
7269 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7270 nal_count++;
7271 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7272 h264_scratch.nFlags = psource_frame->nFlags;
7273 }
7274 else
7275 {
7276 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen);
7277 if(h264_scratch.nFilledLen)
7278 {
7279 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7280 NALU_TYPE_SPS);
7281#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7282 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7283 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7284 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7285 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7286 // If timeinfo is present frame info from SEI is already processed
7287 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7288 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7289#endif
7290 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7291 nal_count++;
7292 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7293 pdest_frame->nTimeStamp = h264_last_au_ts;
7294 pdest_frame->nFlags = h264_last_au_flags;
7295#ifdef PANSCAN_HDLR
7296 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7297 h264_parser->update_panscan_data(h264_last_au_ts);
7298#endif
7299 }
7300 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7301 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7302 h264_last_au_ts = h264_scratch.nTimeStamp;
7303 h264_last_au_flags = h264_scratch.nFlags;
7304#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7305 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7306 {
7307 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7308 if (!VALID_TS(h264_last_au_ts))
7309 h264_last_au_ts = ts_in_sei;
7310 }
7311#endif
7312 } else
7313 h264_last_au_ts = LLONG_MAX;
7314 }
7315
7316 if (!isNewFrame)
7317 {
7318 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7319 h264_scratch.nFilledLen)
7320 {
7321 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
7322 h264_scratch.nFilledLen);
7323 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7324 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7325 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7326 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7327 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7328 h264_scratch.nFilledLen = 0;
7329 }
7330 else
7331 {
7332 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7333 return OMX_ErrorBadParameter;
7334 }
7335 }
7336 else
7337 {
7338 look_ahead_nal = true;
7339 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7340 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7341 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7342 pdest_frame->nFilledLen,frame_count++);
7343
7344 if (pdest_frame->nFilledLen == 0)
7345 {
7346 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7347 look_ahead_nal = false;
7348 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7349 h264_scratch.nFilledLen)
7350 {
7351 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7352 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7353 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7354 h264_scratch.nFilledLen = 0;
7355 }
7356 else
7357 {
7358 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7359 return OMX_ErrorBadParameter;
7360 }
7361 }
7362 else
7363 {
7364 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7365 {
7366 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7367 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7368 }
7369 /*Push the frame to the Decoder*/
7370 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7371 {
7372 return OMX_ErrorBadParameter;
7373 }
7374 //frame_count++;
7375 pdest_frame = NULL;
7376 if (m_input_free_q.m_size)
7377 {
7378 m_input_free_q.pop_entry(&address,&p2,&id);
7379 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7380 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7381 pdest_frame->nFilledLen = 0;
7382 pdest_frame->nFlags = 0;
7383 pdest_frame->nTimeStamp = LLONG_MAX;
7384 }
7385 }
7386 }
7387 }
7388 }
7389 else
7390 {
7391 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7392 /*Check if Destination Buffer is full*/
7393 if (h264_scratch.nAllocLen ==
7394 h264_scratch.nFilledLen + h264_scratch.nOffset)
7395 {
7396 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7397 return OMX_ErrorStreamCorrupt;
7398 }
7399 }
7400
7401 if (!psource_frame->nFilledLen)
7402 {
7403 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7404
7405 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7406 {
7407 if (pdest_frame)
7408 {
7409 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7410 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7411 h264_scratch.nFilledLen)
7412 {
7413 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7414 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7415 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7416 h264_scratch.nFilledLen = 0;
7417 }
7418 else
7419 {
7420 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7421 return OMX_ErrorBadParameter;
7422 }
7423 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7424 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7425
7426 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x",
7427 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7428 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7429#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7430 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7431 {
7432 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7433 if (!VALID_TS(pdest_frame->nTimeStamp))
7434 pdest_frame->nTimeStamp = ts_in_sei;
7435 }
7436#endif
7437 /*Push the frame to the Decoder*/
7438 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7439 {
7440 return OMX_ErrorBadParameter;
7441 }
7442 frame_count++;
7443 pdest_frame = NULL;
7444 }
7445 else
7446 {
7447 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
7448 pdest_frame,h264_scratch.nFilledLen);
7449 generate_ebd = OMX_FALSE;
7450 }
7451 }
7452 }
7453 if(generate_ebd && !psource_frame->nFilledLen)
7454 {
7455 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7456 psource_frame = NULL;
7457 if (m_input_pending_q.m_size)
7458 {
7459 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7460 m_input_pending_q.pop_entry(&address,&p2,&id);
7461 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7462 DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d",
7463 psource_frame->nFlags,psource_frame->nFilledLen);
7464 }
7465 }
7466 return OMX_ErrorNone;
7467}
7468
7469OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7470{
7471 OMX_U8 *buf, *pdest;
7472 OMX_U32 partial_frame = 1;
7473 OMX_U32 buf_len, dest_len;
7474
7475 if(first_frame == 0)
7476 {
7477 first_frame = 1;
7478 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7479 if(!m_vendor_config.pData)
7480 {
7481 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7482 buf = psource_frame->pBuffer;
7483 buf_len = psource_frame->nFilledLen;
7484
7485 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7486 VC1_SP_MP_START_CODE)
7487 {
7488 m_vc1_profile = VC1_SP_MP_RCV;
7489 }
7490 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7491 {
7492 m_vc1_profile = VC1_AP;
7493 }
7494 else
7495 {
7496 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7497 return OMX_ErrorStreamCorrupt;
7498 }
7499 }
7500 else
7501 {
7502 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7503 pdest_frame->nOffset;
7504 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7505 pdest_frame->nOffset);
7506
7507 if(dest_len < m_vendor_config.nDataSize)
7508 {
7509 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7510 return OMX_ErrorBadParameter;
7511 }
7512 else
7513 {
7514 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7515 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7516 }
7517 }
7518 }
7519
7520 switch(m_vc1_profile)
7521 {
7522 case VC1_AP:
7523 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7524 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7525 {
7526 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7527 return OMX_ErrorBadParameter;
7528 }
7529 break;
7530
7531 case VC1_SP_MP_RCV:
7532 default:
7533 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7534 return OMX_ErrorBadParameter;
7535 }
7536 return OMX_ErrorNone;
7537}
7538
7539bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7540 OMX_U32 alignment)
7541{
7542 struct pmem_allocation allocation;
7543 allocation.size = buffer_size;
7544 allocation.align = clip2(alignment);
7545 if (allocation.align < 4096)
7546 {
7547 allocation.align = 4096;
7548 }
7549 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7550 {
7551 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7552 allocation.align, allocation.size);
7553 return false;
7554 }
7555 return true;
7556}
7557#ifdef USE_ION
7558int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7559 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7560 struct ion_fd_data *fd_data, int flag)
7561{
7562 int fd = -EINVAL;
7563 int rc = -EINVAL;
7564 int ion_dev_flag;
7565 struct vdec_ion ion_buf_info;
7566 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7567 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7568 return -EINVAL;
7569 }
Arun Menon737de532012-09-14 14:48:18 -07007570 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007571 fd = open (MEM_DEVICE, ion_dev_flag);
7572 if (fd < 0) {
7573 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7574 return fd;
7575 }
Arun Menon737de532012-09-14 14:48:18 -07007576 alloc_data->flags = 0;
7577 if(!secure_mode && (flag & ION_FLAG_CACHED))
7578 {
7579 alloc_data->flags |= ION_FLAG_CACHED;
7580 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007581 alloc_data->len = buffer_size;
7582 alloc_data->align = clip2(alignment);
7583 if (alloc_data->align < 4096)
7584 {
7585 alloc_data->align = 4096;
7586 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007587 if ((secure_mode) && (flag & ION_SECURE))
7588 alloc_data->flags |= ION_SECURE;
7589
7590 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Vinay Kalia14c26132012-12-07 15:18:14 -08007591 if (!secure_mode)
7592 alloc_data->heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007593 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7594 if (rc || !alloc_data->handle) {
7595 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7596 alloc_data->handle = NULL;
7597 close(fd);
7598 fd = -ENOMEM;
7599 return fd;
7600 }
7601 fd_data->handle = alloc_data->handle;
7602 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7603 if (rc) {
7604 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7605 ion_buf_info.ion_alloc_data = *alloc_data;
7606 ion_buf_info.ion_device_fd = fd;
7607 ion_buf_info.fd_ion_data = *fd_data;
7608 free_ion_memory(&ion_buf_info);
7609 fd_data->fd =-1;
7610 close(fd);
7611 fd = -ENOMEM;
7612 }
7613
7614 return fd;
7615}
7616
7617void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7618
7619 if(!buf_ion_info) {
7620 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7621 return;
7622 }
7623 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7624 &buf_ion_info->ion_alloc_data.handle)) {
7625 DEBUG_PRINT_ERROR("\n ION: free failed" );
7626 }
7627 close(buf_ion_info->ion_device_fd);
7628 buf_ion_info->ion_device_fd = -1;
7629 buf_ion_info->ion_alloc_data.handle = NULL;
7630 buf_ion_info->fd_ion_data.fd = -1;
7631}
7632#endif
7633void omx_vdec::free_output_buffer_header()
7634{
7635 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7636 output_use_buffer = false;
7637 ouput_egl_buffers = false;
7638
7639 if (m_out_mem_ptr)
7640 {
7641 free (m_out_mem_ptr);
7642 m_out_mem_ptr = NULL;
7643 }
7644
7645 if(m_platform_list)
7646 {
7647 free(m_platform_list);
7648 m_platform_list = NULL;
7649 }
7650
7651 if (drv_ctx.ptr_respbuffer)
7652 {
7653 free (drv_ctx.ptr_respbuffer);
7654 drv_ctx.ptr_respbuffer = NULL;
7655 }
7656 if (drv_ctx.ptr_outputbuffer)
7657 {
7658 free (drv_ctx.ptr_outputbuffer);
7659 drv_ctx.ptr_outputbuffer = NULL;
7660 }
7661#ifdef USE_ION
7662 if (drv_ctx.op_buf_ion_info) {
7663 DEBUG_PRINT_LOW("\n Free o/p ion context");
7664 free(drv_ctx.op_buf_ion_info);
7665 drv_ctx.op_buf_ion_info = NULL;
7666 }
7667#endif
7668}
7669
7670void omx_vdec::free_input_buffer_header()
7671{
7672 input_use_buffer = false;
7673 if (arbitrary_bytes)
7674 {
7675 if (m_frame_parser.mutils)
7676 {
7677 DEBUG_PRINT_LOW("\n Free utils parser");
7678 delete (m_frame_parser.mutils);
7679 m_frame_parser.mutils = NULL;
7680 }
7681
7682 if (m_inp_heap_ptr)
7683 {
7684 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7685 free (m_inp_heap_ptr);
7686 m_inp_heap_ptr = NULL;
7687 }
7688
7689 if (m_phdr_pmem_ptr)
7690 {
7691 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7692 free (m_phdr_pmem_ptr);
7693 m_phdr_pmem_ptr = NULL;
7694 }
7695 }
7696 if (m_inp_mem_ptr)
7697 {
7698 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7699 free (m_inp_mem_ptr);
7700 m_inp_mem_ptr = NULL;
7701 }
7702 if (drv_ctx.ptr_inputbuffer)
7703 {
7704 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7705 free (drv_ctx.ptr_inputbuffer);
7706 drv_ctx.ptr_inputbuffer = NULL;
7707 }
7708#ifdef USE_ION
7709 if (drv_ctx.ip_buf_ion_info) {
7710 DEBUG_PRINT_LOW("\n Free ion context");
7711 free(drv_ctx.ip_buf_ion_info);
7712 drv_ctx.ip_buf_ion_info = NULL;
7713 }
7714#endif
7715}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007716
7717int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007718{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007719 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007720 int rc = 0;
7721 enum v4l2_ports v4l2_port;
7722
7723 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7724 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7725 v4l2_port = OUTPUT_PORT;
7726 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7727 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7728 v4l2_port = CAPTURE_PORT;
7729 } else if (port == OMX_ALL) {
7730 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7731 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7732
7733 if (!rc_input)
7734 return rc_input;
7735 else
7736 return rc_output;
7737 }
7738
7739 if (!streaming[v4l2_port]) {
7740 // already streamed off, warn and move on
7741 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7742 " which is already streamed off", v4l2_port);
7743 return 0;
7744 }
7745
7746 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7747
Shalaj Jain273b3e02012-06-22 19:08:03 -07007748 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7749 if (rc) {
7750 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007751 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007752 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007753 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007754 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007755
7756 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007757}
7758
7759OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7760{
7761 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7762 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007763 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007764 struct v4l2_format fmt;
7765 int ret;
7766 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7767 buffer_prop->actualcount, buffer_prop->buffer_size);
7768 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007769 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007770 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7771 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7772 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7773 fmt.fmt.pix_mp.pixelformat = output_capability;
7774 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7775 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7776 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7777 fmt.fmt.pix_mp.pixelformat = capture_capability;
7778 }else {eRet = OMX_ErrorBadParameter;}
7779 if(eRet==OMX_ErrorNone){
7780 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7781 }
7782 if(ret)
7783 {
7784 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7785 /*TODO: How to handle this case */
7786 eRet = OMX_ErrorInsufficientResources;
7787 return eRet;
7788 }
7789 else
7790 {
7791 buffer_prop->actualcount = bufreq.count;
7792 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007793 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007794 }
7795 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7796 buffer_prop->actualcount, buffer_prop->buffer_size);
7797
7798 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7799 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7800
7801 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7802
7803 drv_ctx.video_resolution.frame_height = fmt.fmt.pix_mp.height;
7804 drv_ctx.video_resolution.frame_width = fmt.fmt.pix_mp.width;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007805 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007806 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007807
7808 if(ret)
7809 {
7810 /*TODO: How to handle this case */
7811 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7812 eRet = OMX_ErrorInsufficientResources;
7813 }
7814 else
7815 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007816 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007817 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7818 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007819 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7820 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7821 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7822 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7823 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7824 return OMX_ErrorBadParameter;
7825 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007826 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7827 {
7828 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007829 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007830 }
7831 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7832 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007833 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007834 }
7835 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7836 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007837 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7838 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7839 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007840 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007841 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007842 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007843 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007844 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7845 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007846 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7847 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7848 drv_ctx.extradata_info.buffer_size = extra_data_size;
7849 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007850 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7851 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007852 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007853 if (in_reconfig) // BufReq will be set to driver when port is disabled
7854 buffer_prop->buffer_size = buf_size;
7855 else if (buf_size != buffer_prop->buffer_size)
7856 {
7857 buffer_prop->buffer_size = buf_size;
7858 eRet = set_buffer_req(buffer_prop);
7859 }
7860 }
7861 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7862 buffer_prop->actualcount, buffer_prop->buffer_size);
7863 return eRet;
7864}
7865
7866OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7867{
7868 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7869 unsigned buf_size = 0;
7870 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007871 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007872 int ret;
7873 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7874 buffer_prop->actualcount, buffer_prop->buffer_size);
7875 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7876 if (buf_size != buffer_prop->buffer_size)
7877 {
7878 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7879 buffer_prop->buffer_size, buf_size);
7880 eRet = OMX_ErrorBadParameter;
7881 }
7882 else
7883 {
7884 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7885 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007886
7887 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7888 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7889 fmt.fmt.pix_mp.pixelformat = output_capability;
7890 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7891 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7892 fmt.fmt.pix_mp.pixelformat = capture_capability;
7893 } else {eRet = OMX_ErrorBadParameter;}
7894
7895 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7896 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007897 {
7898 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007899 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 eRet = OMX_ErrorInsufficientResources;
7901 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007902
7903 bufreq.memory = V4L2_MEMORY_USERPTR;
7904 bufreq.count = buffer_prop->actualcount;
7905 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7906 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7907 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7908 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7909 } else {eRet = OMX_ErrorBadParameter;}
7910
7911 if (eRet==OMX_ErrorNone) {
7912 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7913 }
7914
7915 if (ret)
7916 {
7917 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7918 /*TODO: How to handle this case */
7919 eRet = OMX_ErrorInsufficientResources;
7920 } else if (bufreq.count < buffer_prop->actualcount) {
7921 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7922 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7923 buffer_prop->actualcount, bufreq.count);
7924 eRet = OMX_ErrorInsufficientResources;
7925 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007926 }
7927 return eRet;
7928}
7929
Shalaj Jain273b3e02012-06-22 19:08:03 -07007930OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7931{
7932 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7933 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7934 ioctl_msg.in = NULL;
7935 ioctl_msg.out = &drv_ctx.video_resolution;
7936 if (/*ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)*/0)
7937 {
7938 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES");
7939 eRet = OMX_ErrorHardware;
7940 }
7941 return eRet;
7942}
7943
7944OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7945{
7946 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7947 if (!portDefn)
7948 {
7949 return OMX_ErrorBadParameter;
7950 }
7951 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7952 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7953 portDefn->nSize = sizeof(portDefn);
7954 portDefn->eDomain = OMX_PortDomainVideo;
7955 if (drv_ctx.frame_rate.fps_denominator > 0)
7956 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7957 drv_ctx.frame_rate.fps_denominator;
7958 else {
7959 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7960 return OMX_ErrorBadParameter;
7961 }
7962 if (0 == portDefn->nPortIndex)
7963 {
7964 portDefn->eDir = OMX_DirInput;
7965 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7966 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7967 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7968 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7969 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7970 portDefn->bEnabled = m_inp_bEnabled;
7971 portDefn->bPopulated = m_inp_bPopulated;
7972 }
7973 else if (1 == portDefn->nPortIndex)
7974 {
7975 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07007976 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7977 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7978 portDefn->nBufferSize = drv_ctx.op_buf.buffer_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007979 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7980 portDefn->bEnabled = m_out_bEnabled;
7981 portDefn->bPopulated = m_out_bPopulated;
7982 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007983 portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
7984 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007985 else if (drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2)
7986 portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
7987 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
7988 else
7989 {
7990 DEBUG_PRINT_ERROR("ERROR: Color format unknown: %x\n", drv_ctx.output_format);
7991 }
7992 }
7993 else
7994 {
7995 portDefn->eDir = OMX_DirMax;
7996 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7997 (int)portDefn->nPortIndex);
7998 eRet = OMX_ErrorBadPortIndex;
7999 }
8000 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8001 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8002 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8003 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8004 DEBUG_PRINT_LOW("update_portdef Width = %d Height = %d Stride = %u"
8005 "SliceHeight = %u \n", portDefn->format.video.nFrameHeight,
8006 portDefn->format.video.nFrameWidth,
8007 portDefn->format.video.nStride,
8008 portDefn->format.video.nSliceHeight);
8009 return eRet;
8010
8011}
8012
8013OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8014{
8015 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8016 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8017 unsigned i= 0;
8018
8019 if(!m_out_mem_ptr) {
8020 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8021 int nBufHdrSize = 0;
8022 int nPlatformEntrySize = 0;
8023 int nPlatformListSize = 0;
8024 int nPMEMInfoSize = 0;
8025 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8026 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8027 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8028
8029 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8030 drv_ctx.op_buf.actualcount);
8031 nBufHdrSize = drv_ctx.op_buf.actualcount *
8032 sizeof(OMX_BUFFERHEADERTYPE);
8033
8034 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8035 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8036 nPlatformListSize = drv_ctx.op_buf.actualcount *
8037 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8038 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8039 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8040
8041 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8042 sizeof(OMX_BUFFERHEADERTYPE),
8043 nPMEMInfoSize,
8044 nPlatformListSize);
8045 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8046 m_out_bm_count);
8047 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8048 // Alloc mem for platform specific info
8049 char *pPtr=NULL;
8050 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8051 nPMEMInfoSize,1);
8052 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8053 calloc (sizeof(struct vdec_bufferpayload),
8054 drv_ctx.op_buf.actualcount);
8055 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8056 calloc (sizeof (struct vdec_output_frameinfo),
8057 drv_ctx.op_buf.actualcount);
8058#ifdef USE_ION
8059 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8060 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8061#endif
8062
8063 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8064 && drv_ctx.ptr_respbuffer)
8065 {
8066 bufHdr = m_out_mem_ptr;
8067 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8068 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8069 (((char *) m_platform_list) + nPlatformListSize);
8070 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8071 (((char *) m_platform_entry) + nPlatformEntrySize);
8072 pPlatformList = m_platform_list;
8073 pPlatformEntry = m_platform_entry;
8074 pPMEMInfo = m_pmem_info;
8075
8076 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8077
8078 // Settting the entire storage nicely
8079 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8080 m_out_mem_ptr,pPlatformEntry);
8081 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8082 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8083 {
8084 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8085 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8086 // Set the values when we determine the right HxW param
8087 bufHdr->nAllocLen = 0;
8088 bufHdr->nFilledLen = 0;
8089 bufHdr->pAppPrivate = NULL;
8090 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8091 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8092 pPlatformEntry->entry = pPMEMInfo;
8093 // Initialize the Platform List
8094 pPlatformList->nEntries = 1;
8095 pPlatformList->entryList = pPlatformEntry;
8096 // Keep pBuffer NULL till vdec is opened
8097 bufHdr->pBuffer = NULL;
8098 pPMEMInfo->offset = 0;
8099 pPMEMInfo->pmem_fd = 0;
8100 bufHdr->pPlatformPrivate = pPlatformList;
8101 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8102#ifdef USE_ION
8103 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8104#endif
8105 /*Create a mapping between buffers*/
8106 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8107 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8108 &drv_ctx.ptr_outputbuffer[i];
8109 // Move the buffer and buffer header pointers
8110 bufHdr++;
8111 pPMEMInfo++;
8112 pPlatformEntry++;
8113 pPlatformList++;
8114 }
8115 }
8116 else
8117 {
8118 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
8119 m_out_mem_ptr, pPtr);
8120 if(m_out_mem_ptr)
8121 {
8122 free(m_out_mem_ptr);
8123 m_out_mem_ptr = NULL;
8124 }
8125 if(pPtr)
8126 {
8127 free(pPtr);
8128 pPtr = NULL;
8129 }
8130 if(drv_ctx.ptr_outputbuffer)
8131 {
8132 free(drv_ctx.ptr_outputbuffer);
8133 drv_ctx.ptr_outputbuffer = NULL;
8134 }
8135 if(drv_ctx.ptr_respbuffer)
8136 {
8137 free(drv_ctx.ptr_respbuffer);
8138 drv_ctx.ptr_respbuffer = NULL;
8139 }
8140#ifdef USE_ION
8141 if (drv_ctx.op_buf_ion_info) {
8142 DEBUG_PRINT_LOW("\n Free o/p ion context");
8143 free(drv_ctx.op_buf_ion_info);
8144 drv_ctx.op_buf_ion_info = NULL;
8145 }
8146#endif
8147 eRet = OMX_ErrorInsufficientResources;
8148 }
8149 } else {
8150 eRet = OMX_ErrorInsufficientResources;
8151 }
8152 return eRet;
8153}
8154
8155void omx_vdec::complete_pending_buffer_done_cbs()
8156{
8157 unsigned p1;
8158 unsigned p2;
8159 unsigned ident;
8160 omx_cmd_queue tmp_q, pending_bd_q;
8161 pthread_mutex_lock(&m_lock);
8162 // pop all pending GENERATE FDB from ftb queue
8163 while (m_ftb_q.m_size)
8164 {
8165 m_ftb_q.pop_entry(&p1,&p2,&ident);
8166 if(ident == OMX_COMPONENT_GENERATE_FBD)
8167 {
8168 pending_bd_q.insert_entry(p1,p2,ident);
8169 }
8170 else
8171 {
8172 tmp_q.insert_entry(p1,p2,ident);
8173 }
8174 }
8175 //return all non GENERATE FDB to ftb queue
8176 while(tmp_q.m_size)
8177 {
8178 tmp_q.pop_entry(&p1,&p2,&ident);
8179 m_ftb_q.insert_entry(p1,p2,ident);
8180 }
8181 // pop all pending GENERATE EDB from etb queue
8182 while (m_etb_q.m_size)
8183 {
8184 m_etb_q.pop_entry(&p1,&p2,&ident);
8185 if(ident == OMX_COMPONENT_GENERATE_EBD)
8186 {
8187 pending_bd_q.insert_entry(p1,p2,ident);
8188 }
8189 else
8190 {
8191 tmp_q.insert_entry(p1,p2,ident);
8192 }
8193 }
8194 //return all non GENERATE FDB to etb queue
8195 while(tmp_q.m_size)
8196 {
8197 tmp_q.pop_entry(&p1,&p2,&ident);
8198 m_etb_q.insert_entry(p1,p2,ident);
8199 }
8200 pthread_mutex_unlock(&m_lock);
8201 // process all pending buffer dones
8202 while(pending_bd_q.m_size)
8203 {
8204 pending_bd_q.pop_entry(&p1,&p2,&ident);
8205 switch(ident)
8206 {
8207 case OMX_COMPONENT_GENERATE_EBD:
8208 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8209 {
8210 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8211 omx_report_error ();
8212 }
8213 break;
8214
8215 case OMX_COMPONENT_GENERATE_FBD:
8216 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8217 {
8218 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8219 omx_report_error ();
8220 }
8221 break;
8222 }
8223 }
8224}
8225
8226void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8227{
8228 OMX_U32 new_frame_interval = 0;
8229 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
8230 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8231 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8232 {
8233 new_frame_interval = (act_timestamp > prev_ts)?
8234 act_timestamp - prev_ts :
8235 prev_ts - act_timestamp;
8236 if (new_frame_interval < frm_int || frm_int == 0)
8237 {
8238 frm_int = new_frame_interval;
8239 if(frm_int)
8240 {
8241 drv_ctx.frame_rate.fps_numerator = 1e6;
8242 drv_ctx.frame_rate.fps_denominator = frm_int;
8243 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
8244 frm_int, drv_ctx.frame_rate.fps_numerator /
8245 (float)drv_ctx.frame_rate.fps_denominator);
8246 ioctl_msg.in = &drv_ctx.frame_rate;
8247 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
8248 (void*)&ioctl_msg) < */0)
8249 {
8250 DEBUG_PRINT_ERROR("Setting frame rate failed");
8251 }
8252 }
8253 }
8254 }
8255 prev_ts = act_timestamp;
8256}
8257
8258void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8259{
8260 if (rst_prev_ts && VALID_TS(act_timestamp))
8261 {
8262 prev_ts = act_timestamp;
8263 rst_prev_ts = false;
8264 }
8265 else if (VALID_TS(prev_ts))
8266 {
8267 bool codec_cond = (drv_ctx.timestamp_adjust)?
8268 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8269 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8270 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8271 if(frm_int > 0 && codec_cond)
8272 {
8273 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8274 act_timestamp = prev_ts + frm_int;
8275 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8276 prev_ts = act_timestamp;
8277 }
8278 else
8279 set_frame_rate(act_timestamp);
8280 }
8281 else if (frm_int > 0) // In this case the frame rate was set along
8282 { // with the port definition, start ts with 0
8283 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8284 rst_prev_ts = true;
8285 }
8286}
8287
8288void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8289{
8290 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8291 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008292 OMX_U32 frame_rate = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008293 OMX_U32 consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008294 OMX_U32 num_MB_in_frame;
8295 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008296 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008297 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008298 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + p_buf_hdr->nOffset);
8299 if (!drv_ctx.extradata_info.uaddr) {
8300 return;
8301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008302 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008303 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8304 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8305 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008306 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008307 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008308 if (data) {
8309 while((consumed_len < drv_ctx.extradata_info.buffer_size)
8310 && (data->eType != EXTRADATA_NONE)) {
8311 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
8312 DEBUG_PRINT_ERROR("Invalid extra data size");
8313 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008314 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008315 switch(data->eType) {
8316 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008317 struct msm_vidc_interlace_payload *payload;
8318 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008319 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8320 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008321 OMX_U32 mbaff = 0;
8322 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8323 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8324 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8325 else
8326 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8327 if(m_enable_android_native_buffers)
8328 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008329 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008330 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008331 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8332 append_interlace_extradata(p_extra, payload->format);
8333 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8334 }
8335 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008336 case EXTRADATA_FRAME_RATE:
8337 struct msm_vidc_framerate_payload *frame_rate_payload;
8338 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8339 frame_rate = frame_rate_payload->frame_rate;
8340 break;
8341 case EXTRADATA_TIMESTAMP:
8342 struct msm_vidc_ts_payload *time_stamp_payload;
8343 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
8344 break;
8345 case EXTRADATA_NUM_CONCEALED_MB:
8346 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8347 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8348 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8349 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8350 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8351 break;
8352 case EXTRADATA_RECOVERY_POINT_SEI:
8353 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8354 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8355 recovery_sei_flags = recovery_sei_payload->flags;
8356 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8357 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008358 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008359 }
8360 break;
8361 case EXTRADATA_PANSCAN_WINDOW:
8362 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8363 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008364 default:
8365 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008366 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008367 consumed_len += data->nSize;
8368 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008369 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008370 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008371 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008372 append_frame_info_extradata(p_extra,
8373 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
8374 panscan_payload);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008375 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008376unrecognized_extradata:
8377 if(!secure_mode && client_extradata)
8378 append_terminator_extradata(p_extra);
8379 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008380}
8381
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008382OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8383 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008384{
8385 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008386 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008387 if(m_state != OMX_StateLoaded)
8388 {
8389 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8390 return OMX_ErrorIncorrectStateOperation;
8391 }
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008392 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%x] requested[%x] enable[%d], is_internal: %d\n",
8393 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008394
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008395 if (!is_internal) {
8396 if (enable)
8397 client_extradata |= requested_extradata;
8398 else
8399 client_extradata = client_extradata & ~requested_extradata;
8400 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008401
8402 if (enable) {
8403 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8404 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8405 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8406 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8407 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8408 " Quality of interlaced clips might be impacted.\n");
8409 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008410 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8411 {
8412 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8413 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8414 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8415 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8416 }
8417 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8418 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8419 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8420 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8421 }
8422 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8423 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8424 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8425 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8426 }
8427 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8428 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8429 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8430 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8431 }
8432 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8433 {
8434 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8435 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8436 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8437 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8438 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008439 }
8440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008441 return ret;
8442}
8443
8444OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8445{
8446 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8447 OMX_U8 *data_ptr = extra->data, data = 0;
8448 while (byte_count < extra->nDataSize)
8449 {
8450 data = *data_ptr;
8451 while (data)
8452 {
8453 num_MB += (data&0x01);
8454 data >>= 1;
8455 }
8456 data_ptr++;
8457 byte_count++;
8458 }
8459 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8460 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8461 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8462}
8463
8464void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8465{
8466 if (!m_debug_extradata)
8467 return;
8468
8469 DEBUG_PRINT_HIGH(
8470 "============== Extra Data ==============\n"
8471 " Size: %u \n"
8472 " Version: %u \n"
8473 " PortIndex: %u \n"
8474 " Type: %x \n"
8475 " DataSize: %u \n",
8476 extra->nSize, extra->nVersion.nVersion,
8477 extra->nPortIndex, extra->eType, extra->nDataSize);
8478
8479 if (extra->eType == OMX_ExtraDataInterlaceFormat)
8480 {
8481 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8482 DEBUG_PRINT_HIGH(
8483 "------ Interlace Format ------\n"
8484 " Size: %u \n"
8485 " Version: %u \n"
8486 " PortIndex: %u \n"
8487 " Is Interlace Format: %u \n"
8488 " Interlace Formats: %u \n"
8489 "=========== End of Interlace ===========\n",
8490 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8491 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8492 }
8493 else if (extra->eType == OMX_ExtraDataFrameInfo)
8494 {
8495 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8496
8497 DEBUG_PRINT_HIGH(
8498 "-------- Frame Format --------\n"
8499 " Picture Type: %u \n"
8500 " Interlace Type: %u \n"
8501 " Pan Scan Total Frame Num: %u \n"
8502 " Concealed Macro Blocks: %u \n"
8503 " frame rate: %u \n"
8504 " Aspect Ratio X: %u \n"
8505 " Aspect Ratio Y: %u \n",
8506 fminfo->ePicType,
8507 fminfo->interlaceType,
8508 fminfo->panScan.numWindows,
8509 fminfo->nConcealedMacroblocks,
8510 fminfo->nFrameRate,
8511 fminfo->aspectRatio.aspectRatioX,
8512 fminfo->aspectRatio.aspectRatioY);
8513
8514 for (int i = 0; i < fminfo->panScan.numWindows; i++)
8515 {
8516 DEBUG_PRINT_HIGH(
8517 "------------------------------\n"
8518 " Pan Scan Frame Num: %d \n"
8519 " Rectangle x: %d \n"
8520 " Rectangle y: %d \n"
8521 " Rectangle dx: %d \n"
8522 " Rectangle dy: %d \n",
8523 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8524 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8525 }
8526
8527 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8528 }
8529 else if (extra->eType == OMX_ExtraDataNone)
8530 {
8531 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8532 }
8533 else
8534 {
8535 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8536 }
8537}
8538
8539void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8540 OMX_U32 interlaced_format_type)
8541{
8542 OMX_STREAMINTERLACEFORMAT *interlace_format;
8543 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008544 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8545 return;
8546 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008547 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8548 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8549 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8550 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8551 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8552 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8553 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8554 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8555 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8556 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008557 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008558 {
8559 interlace_format->bInterlaceFormat = OMX_FALSE;
8560 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8561 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8562 }
8563 else
8564 {
8565 interlace_format->bInterlaceFormat = OMX_TRUE;
8566 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8567 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8568 }
8569 print_debug_extradata(extra);
8570}
8571
8572
8573void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008574 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
8575 struct msm_vidc_panscan_window_payload *panscan_payload)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008576{
8577 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008578 struct msm_vidc_panscan_window *panscan_window;
8579 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8580 return;
8581 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008582 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8583 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8584 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8585 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8586 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8587 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8588 switch (picture_type)
8589 {
8590 case PICTURE_TYPE_I:
8591 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8592 break;
8593 case PICTURE_TYPE_P:
8594 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8595 break;
8596 case PICTURE_TYPE_B:
8597 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8598 break;
8599 default:
8600 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8601 }
8602 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8603 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8604 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8605 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8606 else
8607 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008608 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008609 frame_info->nConcealedMacroblocks = num_conceal_mb;
8610 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008611 frame_info->panScan.numWindows = 0;
8612 if(panscan_payload) {
8613 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8614 panscan_window = &panscan_payload->wnd[0];
8615 for (int i = 0; i < frame_info->panScan.numWindows; i++)
8616 {
8617 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8618 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8619 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8620 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8621 panscan_window++;
8622 }
8623 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008624 print_debug_extradata(extra);
8625}
8626
8627void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8628{
8629 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8630 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8631 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8632 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8633 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8634 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8635 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8636 *portDefn = m_port_def;
8637 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u"
8638 "sliceheight = %u \n",portDefn->format.video.nFrameHeight,
8639 portDefn->format.video.nFrameWidth,
8640 portDefn->format.video.nStride,
8641 portDefn->format.video.nSliceHeight);
8642}
8643
8644void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8645{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008646 if (!client_extradata) {
8647 return;
8648 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008649 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8650 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8651 extra->eType = OMX_ExtraDataNone;
8652 extra->nDataSize = 0;
8653 extra->data[0] = 0;
8654
8655 print_debug_extradata(extra);
8656}
8657
8658OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8659{
8660 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8661 if (index >= drv_ctx.ip_buf.actualcount)
8662 {
8663 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8664 return OMX_ErrorInsufficientResources;
8665 }
8666 if (m_desc_buffer_ptr == NULL)
8667 {
8668 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8669 calloc( (sizeof(desc_buffer_hdr)),
8670 drv_ctx.ip_buf.actualcount);
8671 if (m_desc_buffer_ptr == NULL)
8672 {
8673 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8674 return OMX_ErrorInsufficientResources;
8675 }
8676 }
8677
8678 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8679 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8680 {
8681 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8682 return OMX_ErrorInsufficientResources;
8683 }
8684
8685 return eRet;
8686}
8687
8688void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8689{
8690 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries);
8691 if (m_demux_entries < 8192)
8692 {
8693 m_demux_offsets[m_demux_entries++] = address_offset;
8694 }
8695 return;
8696}
8697
8698void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8699{
8700 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8701 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8702 OMX_U32 index = 0;
8703
8704 m_demux_entries = 0;
8705
8706 while (index < bytes_to_parse)
8707 {
8708 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8709 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8710 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8711 (buf[index+2] == 0x01)) )
8712 {
8713 //Found start code, insert address offset
8714 insert_demux_addr_offset(index);
8715 if (buf[index+2] == 0x01) // 3 byte start code
8716 index += 3;
8717 else //4 byte start code
8718 index += 4;
8719 }
8720 else
8721 index++;
8722 }
8723 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries);
8724 return;
8725}
8726
8727OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8728{
8729 //fix this, handle 3 byte start code, vc1 terminator entry
8730 OMX_U8 *p_demux_data = NULL;
8731 OMX_U32 desc_data = 0;
8732 OMX_U32 start_addr = 0;
8733 OMX_U32 nal_size = 0;
8734 OMX_U32 suffix_byte = 0;
8735 OMX_U32 demux_index = 0;
8736 OMX_U32 buffer_index = 0;
8737
8738 if (m_desc_buffer_ptr == NULL)
8739 {
8740 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8741 return OMX_ErrorBadParameter;
8742 }
8743
8744 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8745 if (buffer_index > drv_ctx.ip_buf.actualcount)
8746 {
8747 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index);
8748 return OMX_ErrorBadParameter;
8749 }
8750
8751 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8752
8753 if ( ((OMX_U8*)p_demux_data == NULL) ||
8754 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8755 {
8756 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8757 return OMX_ErrorBadParameter;
8758 }
8759 else
8760 {
8761 for (; demux_index < m_demux_entries; demux_index++)
8762 {
8763 desc_data = 0;
8764 start_addr = m_demux_offsets[demux_index];
8765 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8766 {
8767 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8768 }
8769 else
8770 {
8771 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8772 }
8773 if (demux_index < (m_demux_entries - 1))
8774 {
8775 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8776 }
8777 else
8778 {
8779 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8780 }
8781 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)",
8782 start_addr,
8783 suffix_byte,
8784 nal_size,
8785 demux_index);
8786 desc_data = (start_addr >> 3) << 1;
8787 desc_data |= (start_addr & 7) << 21;
8788 desc_data |= suffix_byte << 24;
8789
8790 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8791 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8792 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8793 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8794
8795 p_demux_data += 16;
8796 }
8797 if (codec_type_parse == CODEC_TYPE_VC1)
8798 {
8799 DEBUG_PRINT_LOW("VC1 terminator entry");
8800 desc_data = 0;
8801 desc_data = 0x82 << 24;
8802 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8803 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8804 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8805 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8806 p_demux_data += 16;
8807 m_demux_entries++;
8808 }
8809 //Add zero word to indicate end of descriptors
8810 memset(p_demux_data, 0, sizeof(OMX_U32));
8811
8812 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8813 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size);
8814 }
8815 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8816 m_demux_entries = 0;
8817 DEBUG_PRINT_LOW("Demux table complete!");
8818 return OMX_ErrorNone;
8819}
8820
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008821OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008822{
8823 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008824 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008825 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008826 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8827 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008828 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008829 delete iDivXDrmDecrypt;
8830 iDivXDrmDecrypt = NULL;
8831 }
8832 }
8833 else {
8834 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008835 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008836 }
8837 return err;
8838}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008839