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