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