OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / qcom / media / mm-video / vidc / vdec / src / omx_vdec.cpp
1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, 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
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED 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 <stdlib.h>
45 #include <unistd.h>
46 #include <errno.h>
47 #include "omx_vdec.h"
48 #include <fcntl.h>
49
50 #define BITSTREAM_LOG 0
51
52 #if BITSTREAM_LOG
53 FILE *outputBufferFile1;
54 char filename [] = "/data/input-bitstream.m4v";
55 #endif
56
57 #define H264_SUPPORTED_WIDTH (480)
58 #define H264_SUPPORTED_HEIGHT (368)
59
60 #define MPEG4_SUPPORTED_WIDTH (480)
61 #define MPEG4_SUPPORTED_HEIGHT (368)
62
63 #define VC1_SP_MP_START_CODE        0xC5000000
64 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
65 #define VC1_AP_SEQ_START_CODE       0x0F010000
66 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
67 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
68 #define VC1_SIMPLE_PROFILE          0
69 #define VC1_MAIN_PROFILE            1
70 #define VC1_ADVANCE_PROFILE         3
71 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
72 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
73 #define VC1_STRUCT_C_LEN            4
74 #define VC1_STRUCT_C_POS            8
75 #define VC1_STRUCT_A_POS            12
76 #define VC1_STRUCT_B_POS            24
77 #define VC1_SEQ_LAYER_SIZE          36
78
79 #ifdef _ANDROID_
80     extern "C"{
81         #include<utils/Log.h>
82     }
83 #endif//_ANDROID_
84
85 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
86 #define DEBUG_PRINT_ERROR(...) printf(__VA_ARGS__)
87 #define DEBUG_PRINT_LOW(...) printf(__VA_ARGS__)
88
89
90 void* async_message_thread (void *input)
91 {
92   struct vdec_ioctl_msg ioctl_msg;
93   struct vdec_msginfo vdec_msg;
94   omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
95
96   DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
97   while (1)
98   {
99     ioctl_msg.inputparam = NULL;
100     ioctl_msg.outputparam = (void*)&vdec_msg;
101
102     /*Wait for a message from the video decoder driver*/
103     if (ioctl ( omx->driver_context.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,
104                 (void*)&ioctl_msg) < 0)
105     {
106       DEBUG_PRINT_ERROR("\n Error in ioctl read next msg");
107       break;
108     }
109     else
110     {
111       /*Call Instance specific process function*/
112       if (omx->async_message_process(input,&vdec_msg) < 0)
113       {
114         DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message");
115       }
116     }
117   }
118   DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
119   return NULL;
120 }
121
122 void* message_thread(void *input)
123 {
124   omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
125   unsigned char id;
126   int n;
127
128   DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
129   while (1)
130   {
131
132     n = read(omx->m_pipe_in, &id, 1);
133
134     if(0 == n)
135     {
136       break;
137     }
138
139     if (1 == n)
140     {
141         omx->process_event_cb(omx, id);
142     }
143     if ((n < 0) && (errno != EINTR))
144     {
145       DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
146       break;
147     }
148   }
149   DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
150   return 0;
151 }
152
153 void post_message(omx_vdec *omx, unsigned char id)
154 {
155       int ret_value;
156       DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
157       ret_value = write(omx->m_pipe_out, &id, 1);
158       DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
159 }
160
161 // omx_cmd_queue destructor
162 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
163 {
164   // Nothing to do
165 }
166
167 // omx cmd queue constructor
168 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
169 {
170     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
171 }
172
173 // omx cmd queue insert
174 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
175 {
176   bool ret = true;
177   if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
178   {
179     m_q[m_write].id       = id;
180     m_q[m_write].param1   = p1;
181     m_q[m_write].param2   = p2;
182     m_write++;
183     m_size ++;
184     if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
185     {
186       m_write = 0;
187     }
188   }
189   else
190   {
191     ret = false;
192     DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
193   }
194   return ret;
195 }
196
197 // omx cmd queue pop
198 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
199 {
200   bool ret = true;
201   if (m_size > 0)
202   {
203     *id = m_q[m_read].id;
204     *p1 = m_q[m_read].param1;
205     *p2 = m_q[m_read].param2;
206     // Move the read pointer ahead
207     ++m_read;
208     --m_size;
209     if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
210     {
211       m_read = 0;
212     }
213   }
214   else
215   {
216     ret = false;
217   }
218   return ret;
219 }
220
221 // Retrieve the first mesg type in the queue
222 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
223 {
224     return m_q[m_read].id;
225 }
226
227 // factory function executed by the core to create instances
228 void *get_omx_component_factory_fn(void)
229 {
230   return (new omx_vdec);
231 }
232
233 #ifdef _ANDROID_
234 VideoHeap::VideoHeap(int fd, size_t size, void* base)
235 {
236     // dup file descriptor, map once, use pmem
237     init(dup(fd), base, size, 0 , "/dev/pmem_adsp");
238 }
239 #endif // _ANDROID_
240
241 /* ======================================================================
242 FUNCTION
243   omx_vdec::omx_vdec
244
245 DESCRIPTION
246   Constructor
247
248 PARAMETERS
249   None
250
251 RETURN VALUE
252   None.
253 ========================================================================== */
254 omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
255                       m_app_data(NULL),
256                       m_color_format(OMX_COLOR_FormatYUV420Planar),
257                       m_inp_mem_ptr(NULL),
258                       m_out_mem_ptr(NULL),
259                       pending_input_buffers(0),
260                       pending_output_buffers(0),
261                       m_out_bm_count(0),
262                       m_out_buf_count(0),
263                       m_inp_buf_count(OMX_VIDEO_DEC_NUM_INPUT_BUFFERS),
264                       m_inp_buf_size(OMX_VIDEO_DEC_INPUT_BUFFER_SIZE),
265                       m_inp_bm_count(0),
266                       m_inp_bPopulated(OMX_FALSE),
267                       m_out_bPopulated(OMX_FALSE),
268                       m_height(0),
269                       m_width(0),
270                       m_port_height(0),
271                       m_port_width(0),
272                       m_crop_x(0),
273                       m_crop_y(0),
274                       m_crop_dx(0),
275                       m_crop_dy(0),
276                       m_flags(0),
277                       m_inp_bEnabled(OMX_TRUE),
278                       m_out_bEnabled(OMX_TRUE),
279                       m_event_port_settings_sent(false),
280                       input_flush_progress (false),
281                       output_flush_progress (false),
282                       m_platform_list(NULL),
283                       m_platform_entry(NULL),
284                       m_pmem_info(NULL),
285                       input_use_buffer (false),
286                       output_use_buffer (false),
287                       m_ineos_reached (0),
288                       m_outeos_pending (0),
289                       m_outeos_reached (0),
290                       arbitrary_bytes (true),
291                       psource_frame (NULL),
292                       pdest_frame (NULL),
293                       m_inp_heap_ptr (NULL),
294                       m_heap_inp_bm_count (0),
295                       codec_type_parse ((codec_type)0),
296                       first_frame_meta (true),
297                       frame_count (0),
298                       nal_count (0),
299                       nal_length(0),
300                       look_ahead_nal (false),
301                       first_frame(0),
302                       first_buffer(NULL),
303                       first_frame_size (0),
304                       set_seq_header_done(false),
305                       gate_output_buffers(true),
306                       gate_input_buffers(false),
307                       stride(0),
308                       sent_first_frame(false),
309                       m_error_propogated(false),
310                       scan_lines(0),
311                       m_device_file_ptr(NULL),
312                       m_vc1_profile((vc1_profile_type)0)
313 {
314   /* Assumption is that , to begin with , we have all the frames with decoder */
315   DEBUG_PRINT_HIGH("\n In OMX vdec Constuctor");
316   memset(&m_cmp,0,sizeof(m_cmp));
317   memset(&m_cb,0,sizeof(m_cb));
318   memset (&driver_context,0,sizeof(driver_context));
319   memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
320   memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
321   driver_context.video_driver_fd = -1;
322   m_vendor_config.pData = NULL;
323   pthread_mutex_init(&m_lock, NULL);
324   sem_init(&m_cmd_lock,0,0);
325 }
326
327
328 /* ======================================================================
329 FUNCTION
330   omx_vdec::~omx_vdec
331
332 DESCRIPTION
333   Destructor
334
335 PARAMETERS
336   None
337
338 RETURN VALUE
339   None.
340 ========================================================================== */
341 omx_vdec::~omx_vdec()
342 {
343   m_pmem_info = NULL;
344   m_port_width = m_port_height = 0;
345   DEBUG_PRINT_HIGH("\n In OMX vdec Destructor");
346   if(m_pipe_in) close(m_pipe_in);
347   if(m_pipe_out) close(m_pipe_out);
348   m_pipe_in = -1;
349   m_pipe_out = -1;
350   DEBUG_PRINT_HIGH("\n Waiting on OMX Msg Thread exit");
351   pthread_join(msg_thread_id,NULL);
352   DEBUG_PRINT_HIGH("\n Waiting on OMX Async Thread exit");
353   pthread_join(async_thread_id,NULL);
354   pthread_mutex_destroy(&m_lock);
355   sem_destroy(&m_cmd_lock);
356   DEBUG_PRINT_HIGH("\n Exit OMX vdec Destructor");
357 }
358
359 /* ======================================================================
360 FUNCTION
361   omx_vdec::OMXCntrlProcessMsgCb
362
363 DESCRIPTION
364   IL Client callbacks are generated through this routine. The decoder
365   provides the thread context for this routine.
366
367 PARAMETERS
368   ctxt -- Context information related to the self.
369   id   -- Event identifier. This could be any of the following:
370           1. Command completion event
371           2. Buffer done callback event
372           3. Frame done callback event
373
374 RETURN VALUE
375   None.
376
377 ========================================================================== */
378 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
379 {
380   unsigned p1; // Parameter - 1
381   unsigned p2; // Parameter - 2
382   unsigned ident;
383   unsigned qsize=0; // qsize
384   omx_vdec *pThis = (omx_vdec *) ctxt;
385
386   if(!pThis)
387   {
388     DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
389         __func__);
390     return;
391   }
392
393   // Protect the shared queue data structure
394   do
395   {
396     /*Read the message id's from the queue*/
397     pthread_mutex_lock(&pThis->m_lock);
398     qsize = pThis->m_cmd_q.m_size;
399     if(qsize)
400     {
401       pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
402     }
403
404     if (qsize == 0 && !pThis->gate_output_buffers)
405     {
406       qsize = pThis->m_ftb_q.m_size;
407       if (qsize)
408       {
409         pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
410       }
411     }
412
413     if (qsize == 0)
414     {
415       qsize = pThis->m_etb_q.m_size;
416       if (qsize)
417       {
418         pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
419       }
420     }
421     pthread_mutex_unlock(&pThis->m_lock);
422
423     /*process message if we have one*/
424     if(qsize > 0)
425     {
426       id = ident;
427       switch (id)
428       {
429         case OMX_COMPONENT_GENERATE_EVENT:
430           if (pThis->m_cb.EventHandler)
431           {
432             switch (p1)
433             {
434               case OMX_CommandStateSet:
435                 pThis->m_state = (OMX_STATETYPE) p2;
436                 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
437                     pThis->m_state);
438                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
439                                       OMX_EventCmdComplete, p1, p2, NULL);
440                 break;
441
442               case OMX_EventError:
443                 if(p2 == OMX_StateInvalid)
444                 {
445                     DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
446                     pThis->m_state = (OMX_STATETYPE) p2;
447                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
448                                OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
449                 }
450                 else if (p2 == (unsigned)OMX_ErrorHardware)
451                 {
452                    pThis->omx_report_error();
453                 }
454                 else
455                 {
456                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
457                                       OMX_EventError, p2, NULL, NULL );
458                 }
459                 break;
460
461               case OMX_CommandPortDisable:
462                 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
463                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
464                                       OMX_EventCmdComplete, p1, p2, NULL );
465                 //TODO: Check if output port is one that got disabled
466                 pThis->gate_output_buffers = false;
467                 break;
468               case OMX_CommandPortEnable:
469                 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
470                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
471                                       OMX_EventCmdComplete, p1, p2, NULL );
472                 break;
473
474               default:
475                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
476                                          OMX_EventCmdComplete, p1, p2, NULL );
477                 break;
478
479             }
480           }
481           else
482           {
483             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
484           }
485           break;
486         case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
487           if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
488               (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
489           {
490             DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
491             pThis->omx_report_error ();
492           }
493       break;
494         case OMX_COMPONENT_GENERATE_ETB:
495           if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
496               (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
497           {
498             DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
499             pThis->omx_report_error ();
500           }
501          break;
502
503         case OMX_COMPONENT_GENERATE_FTB:
504           if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
505                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
506           {
507              DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
508              pThis->omx_report_error ();
509           }
510         break;
511
512         case OMX_COMPONENT_GENERATE_COMMAND:
513           pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
514                                     (OMX_U32)p2,(OMX_PTR)NULL);
515           break;
516
517         case OMX_COMPONENT_GENERATE_EBD:
518
519           if (p2 != VDEC_S_SUCCESS)
520           {
521             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
522             pThis->omx_report_error ();
523           }
524           else
525           {
526             if ( pThis->empty_buffer_done(&pThis->m_cmp,
527                  (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
528             {
529                DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
530                pThis->omx_report_error ();
531             }
532           }
533           break;
534
535         case OMX_COMPONENT_GENERATE_FBD:
536           if (p2 != VDEC_S_SUCCESS)
537           {
538             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
539             pThis->omx_report_error ();
540           }
541           else
542           {
543              if ( pThis->fill_buffer_done(&pThis->m_cmp,
544                   (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
545              {
546                DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
547                pThis->omx_report_error ();
548              }
549           }
550           break;
551
552         case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
553           DEBUG_PRINT_HIGH("\n Flush i/p Port complete");
554           pThis->input_flush_progress = false;
555           DEBUG_PRINT_LOW("\n Input flush done pending input %d",
556                              pThis->pending_input_buffers);
557
558           if (pThis->m_cb.EventHandler)
559           {
560             if (p2 != VDEC_S_SUCCESS)
561             {
562               DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
563               pThis->omx_report_error ();
564             }
565             else
566             {
567               /*Check if we need generate event for Flush done*/
568               if(BITMASK_PRESENT(&pThis->m_flags,
569                                  OMX_COMPONENT_INPUT_FLUSH_PENDING))
570               {
571                 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
572                 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
573                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
574                                          OMX_EventCmdComplete,OMX_CommandFlush,
575                                          OMX_CORE_INPUT_PORT_INDEX,NULL );
576               }
577               if (BITMASK_PRESENT(&pThis->m_flags,
578                                        OMX_COMPONENT_IDLE_PENDING))
579               {
580                 if (!pThis->output_flush_progress)
581                 {
582                    DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
583                    if (ioctl (pThis->driver_context.video_driver_fd,
584                               VDEC_IOCTL_CMD_STOP,NULL ) < 0)
585                    {
586                      DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
587                      pThis->omx_report_error ();
588                    }
589                 }
590               }
591             }
592           }
593
594           break;
595
596         case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
597         DEBUG_PRINT_HIGH("\n Flush o/p Port complete");
598         pThis->output_flush_progress = false;
599         DEBUG_PRINT_LOW("\n Output flush done pending buf %d",pThis->pending_output_buffers);
600
601         if (pThis->m_cb.EventHandler)
602         {
603           if (p2 != VDEC_S_SUCCESS)
604           {
605             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
606             pThis->omx_report_error ();
607           }
608           else
609           {
610             /*Check if we need generate event for Flush done*/
611             if(BITMASK_PRESENT(&pThis->m_flags,
612                                OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
613             {
614               DEBUG_PRINT_LOW("\n Notify Output Flush done");
615               BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
616
617               pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
618                                        OMX_EventCmdComplete,OMX_CommandFlush,
619                                        OMX_CORE_OUTPUT_PORT_INDEX,NULL );
620             }
621             if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
622             {
623               if (!pThis->input_flush_progress)
624               {
625                 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
626                 if (ioctl (pThis->driver_context.video_driver_fd,
627                            VDEC_IOCTL_CMD_STOP,NULL ) < 0)
628                 {
629                   DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
630                   pThis->omx_report_error ();
631                 }
632               }
633             }
634           }
635         }
636         break;
637
638         case OMX_COMPONENT_GENERATE_START_DONE:
639           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
640
641           if (pThis->m_cb.EventHandler)
642           {
643             if (p2 != VDEC_S_SUCCESS)
644             {
645               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
646               pThis->omx_report_error ();
647             }
648             else
649             {
650               DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
651               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
652               {
653                 DEBUG_PRINT_LOW("\n Move to executing");
654                 // Send the callback now
655                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
656                 pThis->m_state = OMX_StateExecuting;
657                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
658                                        OMX_EventCmdComplete,OMX_CommandStateSet,
659                                        OMX_StateExecuting, NULL);
660               }
661               else if (BITMASK_PRESENT(&pThis->m_flags,
662                                        OMX_COMPONENT_PAUSE_PENDING))
663               {
664                 if (ioctl (pThis->driver_context.video_driver_fd,
665                            VDEC_IOCTL_CMD_PAUSE,NULL ) < 0)
666                 {
667                   DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
668                   pThis->omx_report_error ();
669                 }
670               }
671             }
672           }
673           else
674           {
675             DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
676           }
677           break;
678
679         case OMX_COMPONENT_GENERATE_PAUSE_DONE:
680           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
681           if (pThis->m_cb.EventHandler)
682           {
683             if (p2 != VDEC_S_SUCCESS)
684             {
685               DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
686               pThis->omx_report_error ();
687             }
688             else
689             {
690               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
691               {
692                 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
693                 //Send the callback now
694                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
695                 pThis->m_state = OMX_StatePause;
696                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
697                                        OMX_EventCmdComplete,OMX_CommandStateSet,
698                                        OMX_StatePause, NULL);
699               }
700             }
701           }
702
703           break;
704
705         case OMX_COMPONENT_GENERATE_RESUME_DONE:
706           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
707           if (pThis->m_cb.EventHandler)
708           {
709             if (p2 != VDEC_S_SUCCESS)
710             {
711               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
712               pThis->omx_report_error ();
713             }
714             else
715             {
716               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
717               {
718                 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
719                 // Send the callback now
720                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
721                 pThis->m_state = OMX_StateExecuting;
722                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
723                                        OMX_EventCmdComplete,OMX_CommandStateSet,
724                                        OMX_StateExecuting,NULL);
725               }
726             }
727           }
728
729           break;
730
731         case OMX_COMPONENT_GENERATE_STOP_DONE:
732           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
733           if (pThis->m_cb.EventHandler)
734           {
735             if (p2 != VDEC_S_SUCCESS)
736             {
737               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
738               pThis->omx_report_error ();
739             }
740             else
741             {
742               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
743               {
744                 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
745                 // Send the callback now
746                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
747                 pThis->m_state = OMX_StateIdle;
748                 DEBUG_PRINT_LOW("\n Move to Idle State");
749                 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
750                                        OMX_EventCmdComplete,OMX_CommandStateSet,
751                                          OMX_StateIdle,NULL);
752               }
753             }
754           }
755
756           break;
757
758         case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
759           DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
760           pThis->omx_report_error ();
761           break;
762
763         default:
764           break;
765         }
766       }
767     pthread_mutex_lock(&pThis->m_lock);
768     if(!pThis->gate_output_buffers)
769     {
770     qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
771             pThis->m_etb_q.m_size;
772     }
773     else
774     {
775       qsize = pThis->m_cmd_q.m_size + pThis->m_etb_q.m_size;
776     }
777     pthread_mutex_unlock(&pThis->m_lock);
778   }
779   while(qsize>0);
780
781 }
782
783
784
785 /* ======================================================================
786 FUNCTION
787   omx_vdec::ComponentInit
788
789 DESCRIPTION
790   Initialize the component.
791
792 PARAMETERS
793   ctxt -- Context information related to the self.
794   id   -- Event identifier. This could be any of the following:
795           1. Command completion event
796           2. Buffer done callback event
797           3. Frame done callback event
798
799 RETURN VALUE
800   None.
801
802 ========================================================================== */
803 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
804 {
805
806   OMX_ERRORTYPE eRet = OMX_ErrorNone;
807   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
808   unsigned int   alignment = 0,buffer_size = 0;
809   int fds[2];
810   int r;
811    bool is_fluid = false;
812
813   if (!m_device_file_ptr) {
814     int bytes_read = 0,count = 0;
815     unsigned min_size;
816     m_device_file_ptr = fopen("/sys/devices/system/soc/soc0/hw_platform","rb");
817     if (m_device_file_ptr) {
818       (void)fgets((char *)m_hwdevice_name,sizeof(m_hwdevice_name),m_device_file_ptr);
819       DEBUG_PRINT_HIGH ("\n Name of the device is %s",m_hwdevice_name);
820       min_size = strnlen((const char *)m_hwdevice_name,sizeof(m_hwdevice_name));
821       if (strlen("Fluid") < min_size) {
822           min_size = strnlen("Fluid",sizeof("Fluid"));
823       }
824       if  (!strncmp("Fluid",(const char *)m_hwdevice_name,min_size)) {
825         is_fluid = true;
826       }
827       fclose (m_device_file_ptr);
828     } else {
829       DEBUG_PRINT_HIGH("\n Could not open hw_platform file");
830     }
831   }
832
833   DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Start of New Playback");
834   driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
835                       O_RDWR|O_NONBLOCK);
836
837   DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
838                    driver_context.video_driver_fd);
839
840   if(driver_context.video_driver_fd == 0){
841     driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
842                       O_RDWR|O_NONBLOCK);
843   }
844
845   if(driver_context.video_driver_fd < 0)
846   {
847     DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure\n");
848     return OMX_ErrorInsufficientResources;
849   }
850
851 #ifndef MULTI_DEC_INST
852   unsigned int instance_count = 0;
853   if (!is_fluid) {
854     ioctl_msg.outputparam = &instance_count;
855     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_NUMBER_INSTANCES,
856                (void*)&ioctl_msg) < 0){
857         DEBUG_PRINT_ERROR("\n Instance Query Failed");
858         return OMX_ErrorInsufficientResources;
859     }
860     if (instance_count > 1) {
861       close(driver_context.video_driver_fd);
862       DEBUG_PRINT_ERROR("\n Reject Second instance of Decoder");
863       driver_context.video_driver_fd = -1;
864       return OMX_ErrorInsufficientResources;
865     }
866   }
867 #endif
868
869 #if BITSTREAM_LOG
870   outputBufferFile1 = fopen (filename, "ab");
871 #endif
872
873   // Copy the role information which provides the decoder kind
874   strncpy(driver_context.kind,role,128);
875
876   if(!strncmp(driver_context.kind,"OMX.qcom.video.decoder.mpeg4",\
877       OMX_MAX_STRINGNAME_SIZE))
878   {
879      strncpy((char *)m_cRole, "video_decoder.mpeg4",\
880      OMX_MAX_STRINGNAME_SIZE);
881      driver_context.decoder_format = VDEC_CODECTYPE_MPEG4;
882      eCompressionFormat = OMX_VIDEO_CodingMPEG4;
883      /*Initialize Start Code for MPEG4*/
884      codec_type_parse = CODEC_TYPE_MPEG4;
885      m_frame_parser.init_start_codes (codec_type_parse);
886   }
887   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",\
888          OMX_MAX_STRINGNAME_SIZE))
889   {
890      strncpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
891      DEBUG_PRINT_LOW("\n H263 Decoder selected");
892      driver_context.decoder_format = VDEC_CODECTYPE_H263;
893      eCompressionFormat = OMX_VIDEO_CodingH263;
894      codec_type_parse = CODEC_TYPE_H263;
895      m_frame_parser.init_start_codes (codec_type_parse);
896   }
897   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",\
898          OMX_MAX_STRINGNAME_SIZE))
899   {
900     strncpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
901     driver_context.decoder_format = VDEC_CODECTYPE_H264;
902     eCompressionFormat = OMX_VIDEO_CodingAVC;
903     codec_type_parse = CODEC_TYPE_H264;
904     m_frame_parser.init_start_codes (codec_type_parse);
905     m_frame_parser.init_nal_length(nal_length);
906   }
907   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",\
908          OMX_MAX_STRINGNAME_SIZE))
909   {
910     strncpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
911     driver_context.decoder_format = VDEC_CODECTYPE_VC1;
912     eCompressionFormat = OMX_VIDEO_CodingWMV;
913     codec_type_parse = CODEC_TYPE_VC1;
914     m_frame_parser.init_start_codes (codec_type_parse);
915   }
916   else
917   {
918     DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
919     eRet = OMX_ErrorInvalidComponentName;
920   }
921
922   if (eRet == OMX_ErrorNone)
923   {
924     driver_context.output_format = VDEC_YUV_FORMAT_NV12;
925
926     if  (is_fluid) {
927
928          FILE * pFile;
929          char disable_overlay = '0';
930          pFile = fopen
931          ("/data/data/com.arcsoft.videowall/files/disableoverlay.txt", "rb" );
932          if (pFile == NULL) {
933            DEBUG_PRINT_HIGH(" fopen FAiLED  for disableoverlay.txt\n");
934          } else {
935             int count  = fread(&disable_overlay, 1, 1, pFile);
936             fclose(pFile);
937          }
938
939          if(disable_overlay == '1') {
940              DEBUG_PRINT_HIGH(" vdec : TILE format \n");
941              driver_context.output_format = VDEC_YUV_FORMAT_TILE_4x2;
942          } else {
943              DEBUG_PRINT_HIGH("  vdec : NV 12 format \n");
944              driver_context.output_format = VDEC_YUV_FORMAT_NV12;
945          }
946       }
947
948     /*Initialize Decoder with codec type and resolution*/
949     ioctl_msg.inputparam = &driver_context.decoder_format;
950     ioctl_msg.outputparam = NULL;
951
952     if ( (eRet == OMX_ErrorNone) &&
953          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_CODEC,
954                 (void*)&ioctl_msg) < 0)
955
956     {
957       DEBUG_PRINT_ERROR("\n Set codec type failed");
958       eRet = OMX_ErrorInsufficientResources;
959     }
960
961     /*Set the output format*/
962     ioctl_msg.inputparam = &driver_context.output_format;
963     ioctl_msg.outputparam = NULL;
964
965     if ( (eRet == OMX_ErrorNone) &&
966          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT,
967            (void*)&ioctl_msg) < 0)
968     {
969       DEBUG_PRINT_ERROR("\n Set output format failed");
970       eRet = OMX_ErrorInsufficientResources;
971     }
972
973 #ifdef MAX_RES_720P
974     driver_context.video_resoultion.frame_height = 720;
975     driver_context.video_resoultion.frame_width = 1280;
976     driver_context.video_resoultion.stride = 1280;
977     driver_context.video_resoultion.scan_lines = 720;
978 #endif
979 #ifdef MAX_RES_1080P
980     driver_context.video_resoultion.frame_height = 1088;
981     driver_context.video_resoultion.frame_width = 1920;
982     driver_context.video_resoultion.stride = 1920;
983     driver_context.video_resoultion.scan_lines = 1088;
984 #endif
985
986     ioctl_msg.inputparam = &driver_context.video_resoultion;
987     ioctl_msg.outputparam = NULL;
988
989     if ( (eRet == OMX_ErrorNone) &&
990         ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
991            (void*)&ioctl_msg) < 0)
992     {
993       DEBUG_PRINT_ERROR("\n Set Resolution failed");
994       eRet = OMX_ErrorInsufficientResources;
995     }
996
997     /*Get the Buffer requirements for input and output ports*/
998     driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
999     ioctl_msg.inputparam = NULL;
1000     ioctl_msg.outputparam = &driver_context.input_buffer;
1001
1002     if ( (eRet == OMX_ErrorNone) &&
1003          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
1004            (void*)&ioctl_msg) < 0)
1005     {
1006       DEBUG_PRINT_ERROR("\n Requesting for input buffer requirements failed");
1007       eRet = OMX_ErrorInsufficientResources;
1008     }
1009
1010     m_inp_buf_count = driver_context.input_buffer.actualcount;
1011     buffer_size = driver_context.input_buffer.buffer_size;
1012     alignment = driver_context.input_buffer.alignment;
1013     m_inp_buf_size = ((buffer_size + alignment -1 ) & (~(alignment -1)));
1014     m_inp_buf_count_min = driver_context.input_buffer.mincount;
1015
1016     /*Get the Buffer requirements for input and output ports*/
1017     driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1018     ioctl_msg.inputparam = &driver_context.input_buffer;
1019     ioctl_msg.outputparam = NULL;
1020
1021     m_inp_buf_count_min = m_inp_buf_count = driver_context.input_buffer.actualcount =
1022      driver_context.input_buffer.mincount + 3;
1023
1024     if ( (eRet == OMX_ErrorNone) &&
1025          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
1026            (void*)&ioctl_msg) < 0)
1027     {
1028       DEBUG_PRINT_ERROR("\n Set input buffer requirements failed");
1029       eRet = OMX_ErrorInsufficientResources;
1030     }
1031
1032
1033     driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1034     ioctl_msg.inputparam = NULL;
1035     ioctl_msg.outputparam = &driver_context.output_buffer;
1036
1037     if ((eRet == OMX_ErrorNone) &&
1038         ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
1039            (void*)&ioctl_msg) < 0)
1040     {
1041       DEBUG_PRINT_ERROR("\n Requesting for output buffer requirements failed");
1042       eRet = OMX_ErrorInsufficientResources;
1043     }
1044
1045     m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount;
1046     m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount;
1047
1048     alignment = driver_context.output_buffer.alignment;
1049     buffer_size = driver_context.output_buffer.buffer_size;
1050     m_out_buf_size_recon = m_out_buf_size =
1051       ((buffer_size + alignment - 1) & (~(alignment -1)));
1052 #ifdef MAX_RES_720P
1053     scan_lines = m_crop_dy = m_height = 720;
1054     stride = m_crop_dx = m_width = 1280;
1055 #endif
1056 #ifdef MAX_RES_1080P
1057     scan_lines = m_crop_dy = m_height = 1088;
1058     stride = m_crop_dx = m_width = 1920;
1059 #endif
1060     m_port_height             = m_height;
1061     m_port_width              = m_width;
1062     m_state                   = OMX_StateLoaded;
1063
1064     if(pipe(fds))
1065     {
1066       DEBUG_PRINT_ERROR("pipe creation failed\n");
1067       eRet = OMX_ErrorInsufficientResources;
1068     }
1069     else
1070     {
1071       int temp1[2];
1072       if(fds[0] == 0 || fds[1] == 0)
1073       {
1074         if (pipe (temp1))
1075         {
1076           DEBUG_PRINT_ERROR("pipe creation failed\n");
1077           return OMX_ErrorInsufficientResources;
1078         }
1079         //close (fds[0]);
1080         //close (fds[1]);
1081         fds[0] = temp1 [0];
1082         fds[1] = temp1 [1];
1083       }
1084       m_pipe_in = fds[0];
1085       m_pipe_out = fds[1];
1086       r = pthread_create(&msg_thread_id,0,message_thread,this);
1087
1088       if(r < 0)
1089       {
1090         DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1091         eRet = OMX_ErrorInsufficientResources;
1092       }
1093       else
1094       {
1095         r = pthread_create(&async_thread_id,0,async_message_thread,this);
1096         if(r < 0)
1097         {
1098           DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed");
1099           eRet = OMX_ErrorInsufficientResources;
1100         }
1101       }
1102     }
1103   }
1104
1105   if (eRet != OMX_ErrorNone)
1106   {
1107     DEBUG_PRINT_ERROR("\n Component Init Failed");
1108     DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1109     (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1110         NULL);
1111     DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1112     close (driver_context.video_driver_fd);
1113     driver_context.video_driver_fd = -1;
1114   }
1115   else
1116   {
1117     DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1118   }
1119
1120   return eRet;
1121 }
1122
1123 /* ======================================================================
1124 FUNCTION
1125   omx_vdec::GetComponentVersion
1126
1127 DESCRIPTION
1128   Returns the component version.
1129
1130 PARAMETERS
1131   TBD.
1132
1133 RETURN VALUE
1134   OMX_ErrorNone.
1135
1136 ========================================================================== */
1137 OMX_ERRORTYPE  omx_vdec::get_component_version
1138                                      (
1139                                       OMX_IN OMX_HANDLETYPE hComp,
1140                                       OMX_OUT OMX_STRING componentName,
1141                                       OMX_OUT OMX_VERSIONTYPE* componentVersion,
1142                                       OMX_OUT OMX_VERSIONTYPE* specVersion,
1143                                       OMX_OUT OMX_UUIDTYPE* componentUUID
1144                                       )
1145 {
1146     if(m_state == OMX_StateInvalid)
1147     {
1148         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1149         return OMX_ErrorInvalidState;
1150     }
1151   /* TBD -- Return the proper version */
1152   return OMX_ErrorNone;
1153 }
1154 /* ======================================================================
1155 FUNCTION
1156   omx_vdec::SendCommand
1157
1158 DESCRIPTION
1159   Returns zero if all the buffers released..
1160
1161 PARAMETERS
1162   None.
1163
1164 RETURN VALUE
1165   true/false
1166
1167 ========================================================================== */
1168 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1169                                       OMX_IN OMX_COMMANDTYPE cmd,
1170                                       OMX_IN OMX_U32 param1,
1171                                       OMX_IN OMX_PTR cmdData
1172                                       )
1173 {
1174     DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1175     if(m_state == OMX_StateInvalid)
1176     {
1177         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1178         return OMX_ErrorInvalidState;
1179     }
1180     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1181     sem_wait(&m_cmd_lock);
1182     DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1183     return OMX_ErrorNone;
1184 }
1185
1186 /* ======================================================================
1187 FUNCTION
1188   omx_vdec::SendCommand
1189
1190 DESCRIPTION
1191   Returns zero if all the buffers released..
1192
1193 PARAMETERS
1194   None.
1195
1196 RETURN VALUE
1197   true/false
1198
1199 ========================================================================== */
1200 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1201                                             OMX_IN OMX_COMMANDTYPE cmd,
1202                                             OMX_IN OMX_U32 param1,
1203                                             OMX_IN OMX_PTR cmdData
1204                                             )
1205 {
1206   OMX_ERRORTYPE eRet = OMX_ErrorNone;
1207   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1208   int bFlag = 1,sem_posted = 0;;
1209
1210   DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1211   DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1212     m_state, eState);
1213
1214   if(cmd == OMX_CommandStateSet)
1215   {
1216     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1217     DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1218     /***************************/
1219     /* Current State is Loaded */
1220     /***************************/
1221     if(m_state == OMX_StateLoaded)
1222     {
1223       if(eState == OMX_StateIdle)
1224       {
1225         //if all buffers are allocated or all ports disabled
1226         if(allocate_done() ||
1227           (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1228         {
1229           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1230         }
1231         else
1232         {
1233           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1234           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1235           // Skip the event notification
1236           bFlag = 0;
1237         }
1238       }
1239       /* Requesting transition from Loaded to Loaded */
1240       else if(eState == OMX_StateLoaded)
1241       {
1242         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1243         post_event(OMX_EventError,OMX_ErrorSameState,\
1244                    OMX_COMPONENT_GENERATE_EVENT);
1245         eRet = OMX_ErrorSameState;
1246       }
1247       /* Requesting transition from Loaded to WaitForResources */
1248       else if(eState == OMX_StateWaitForResources)
1249       {
1250         /* Since error is None , we will post an event
1251            at the end of this function definition */
1252         DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1253       }
1254       /* Requesting transition from Loaded to Executing */
1255       else if(eState == OMX_StateExecuting)
1256       {
1257         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1258         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1259                    OMX_COMPONENT_GENERATE_EVENT);
1260         eRet = OMX_ErrorIncorrectStateTransition;
1261       }
1262       /* Requesting transition from Loaded to Pause */
1263       else if(eState == OMX_StatePause)
1264       {
1265         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1266         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1267                    OMX_COMPONENT_GENERATE_EVENT);
1268         eRet = OMX_ErrorIncorrectStateTransition;
1269       }
1270       /* Requesting transition from Loaded to Invalid */
1271       else if(eState == OMX_StateInvalid)
1272       {
1273         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1274         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1275         eRet = OMX_ErrorInvalidState;
1276       }
1277       else
1278       {
1279         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1280                           eState);
1281         eRet = OMX_ErrorBadParameter;
1282       }
1283     }
1284
1285     /***************************/
1286     /* Current State is IDLE */
1287     /***************************/
1288     else if(m_state == OMX_StateIdle)
1289     {
1290       if(eState == OMX_StateLoaded)
1291       {
1292         if(release_done())
1293         {
1294           /*
1295              Since error is None , we will post an event at the end
1296              of this function definition
1297           */
1298           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1299         }
1300         else
1301         {
1302           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1303           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1304           // Skip the event notification
1305           bFlag = 0;
1306         }
1307       }
1308       /* Requesting transition from Idle to Executing */
1309       else if(eState == OMX_StateExecuting)
1310       {
1311         BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1312         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1313         post_event (NULL,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_START_DONE);
1314         bFlag = 0;
1315       }
1316       /* Requesting transition from Idle to Idle */
1317       else if(eState == OMX_StateIdle)
1318       {
1319         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1320         post_event(OMX_EventError,OMX_ErrorSameState,\
1321                    OMX_COMPONENT_GENERATE_EVENT);
1322         eRet = OMX_ErrorSameState;
1323       }
1324       /* Requesting transition from Idle to WaitForResources */
1325       else if(eState == OMX_StateWaitForResources)
1326       {
1327         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1328         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1329                    OMX_COMPONENT_GENERATE_EVENT);
1330         eRet = OMX_ErrorIncorrectStateTransition;
1331       }
1332        /* Requesting transition from Idle to Pause */
1333        else if(eState == OMX_StatePause)
1334       {
1335          /*To pause the Video core we need to start the driver*/
1336          if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_START,
1337                     NULL) < 0)
1338          {
1339            DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1340            omx_report_error ();
1341            eRet = OMX_ErrorHardware;
1342          }
1343          else
1344          {
1345            BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1346            DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1347            bFlag = 0;
1348          }
1349       }
1350       /* Requesting transition from Idle to Invalid */
1351        else if(eState == OMX_StateInvalid)
1352       {
1353         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1354         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1355         eRet = OMX_ErrorInvalidState;
1356       }
1357       else
1358       {
1359         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1360         eRet = OMX_ErrorBadParameter;
1361       }
1362     }
1363
1364     /******************************/
1365     /* Current State is Executing */
1366     /******************************/
1367     else if(m_state == OMX_StateExecuting)
1368     {
1369        DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1370        /* Requesting transition from Executing to Idle */
1371        if(eState == OMX_StateIdle)
1372        {
1373          /* Since error is None , we will post an event
1374          at the end of this function definition
1375          */
1376          DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
1377          BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1378          if(!sem_posted)
1379          {
1380            sem_posted = 1;
1381            sem_post (&m_cmd_lock);
1382            execute_omx_flush(OMX_ALL);
1383          }
1384          bFlag = 0;
1385        }
1386        /* Requesting transition from Executing to Paused */
1387        else if(eState == OMX_StatePause)
1388        {
1389          DEBUG_PRINT_LOW("\n PAUSE Command Issued");
1390          if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
1391                     NULL) < 0)
1392          {
1393            DEBUG_PRINT_ERROR("\n Error In Pause State");
1394            post_event(OMX_EventError,OMX_ErrorHardware,\
1395                       OMX_COMPONENT_GENERATE_EVENT);
1396            eRet = OMX_ErrorHardware;
1397          }
1398          else
1399          {
1400            BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1401            DEBUG_PRINT_LOW("send_command_proxy(): Pause-->Executing\n");
1402            bFlag = 0;
1403          }
1404        }
1405        /* Requesting transition from Executing to Loaded */
1406        else if(eState == OMX_StateLoaded)
1407        {
1408          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
1409          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1410                     OMX_COMPONENT_GENERATE_EVENT);
1411          eRet = OMX_ErrorIncorrectStateTransition;
1412        }
1413        /* Requesting transition from Executing to WaitForResources */
1414        else if(eState == OMX_StateWaitForResources)
1415        {
1416          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
1417          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1418                     OMX_COMPONENT_GENERATE_EVENT);
1419          eRet = OMX_ErrorIncorrectStateTransition;
1420        }
1421        /* Requesting transition from Executing to Executing */
1422        else if(eState == OMX_StateExecuting)
1423        {
1424          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
1425          post_event(OMX_EventError,OMX_ErrorSameState,\
1426                     OMX_COMPONENT_GENERATE_EVENT);
1427          eRet = OMX_ErrorSameState;
1428        }
1429        /* Requesting transition from Executing to Invalid */
1430        else if(eState == OMX_StateInvalid)
1431        {
1432          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
1433          post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1434          eRet = OMX_ErrorInvalidState;
1435        }
1436        else
1437        {
1438          DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
1439          eRet = OMX_ErrorBadParameter;
1440        }
1441     }
1442     /***************************/
1443     /* Current State is Pause  */
1444     /***************************/
1445     else if(m_state == OMX_StatePause)
1446     {
1447       /* Requesting transition from Pause to Executing */
1448       if(eState == OMX_StateExecuting)
1449       {
1450         DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1451         if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
1452                    NULL) < 0)
1453         {
1454           DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed");
1455           post_event(OMX_EventError,OMX_ErrorHardware,\
1456                      OMX_COMPONENT_GENERATE_EVENT);
1457           eRet = OMX_ErrorHardware;
1458         }
1459         else
1460         {
1461           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1462           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1463           post_event (NULL,VDEC_S_SUCCESS,\
1464                       OMX_COMPONENT_GENERATE_RESUME_DONE);
1465           bFlag = 0;
1466         }
1467       }
1468       /* Requesting transition from Pause to Idle */
1469       else if(eState == OMX_StateIdle)
1470       {
1471         /* Since error is None , we will post an event
1472         at the end of this function definition */
1473         DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1474          BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1475          if(!sem_posted)
1476          {
1477            sem_posted = 1;
1478            sem_post (&m_cmd_lock);
1479            execute_omx_flush(OMX_ALL);
1480          }
1481          bFlag = 0;
1482       }
1483       /* Requesting transition from Pause to loaded */
1484       else if(eState == OMX_StateLoaded)
1485       {
1486         DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
1487         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1488                    OMX_COMPONENT_GENERATE_EVENT);
1489         eRet = OMX_ErrorIncorrectStateTransition;
1490       }
1491       /* Requesting transition from Pause to WaitForResources */
1492       else if(eState == OMX_StateWaitForResources)
1493       {
1494         DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
1495         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1496                    OMX_COMPONENT_GENERATE_EVENT);
1497         eRet = OMX_ErrorIncorrectStateTransition;
1498       }
1499       /* Requesting transition from Pause to Pause */
1500       else if(eState == OMX_StatePause)
1501       {
1502         DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
1503         post_event(OMX_EventError,OMX_ErrorSameState,\
1504                    OMX_COMPONENT_GENERATE_EVENT);
1505         eRet = OMX_ErrorSameState;
1506       }
1507        /* Requesting transition from Pause to Invalid */
1508       else if(eState == OMX_StateInvalid)
1509       {
1510         DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
1511         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1512         eRet = OMX_ErrorInvalidState;
1513       }
1514       else
1515       {
1516         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
1517         eRet = OMX_ErrorBadParameter;
1518       }
1519     }
1520      /***************************/
1521     /* Current State is WaitForResources  */
1522     /***************************/
1523     else if(m_state == OMX_StateWaitForResources)
1524     {
1525       /* Requesting transition from WaitForResources to Loaded */
1526       if(eState == OMX_StateLoaded)
1527       {
1528         /* Since error is None , we will post an event
1529         at the end of this function definition */
1530         DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
1531       }
1532       /* Requesting transition from WaitForResources to WaitForResources */
1533       else if (eState == OMX_StateWaitForResources)
1534       {
1535         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
1536         post_event(OMX_EventError,OMX_ErrorSameState,
1537                    OMX_COMPONENT_GENERATE_EVENT);
1538         eRet = OMX_ErrorSameState;
1539       }
1540       /* Requesting transition from WaitForResources to Executing */
1541       else if(eState == OMX_StateExecuting)
1542       {
1543         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
1544         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1545                    OMX_COMPONENT_GENERATE_EVENT);
1546         eRet = OMX_ErrorIncorrectStateTransition;
1547       }
1548       /* Requesting transition from WaitForResources to Pause */
1549       else if(eState == OMX_StatePause)
1550       {
1551         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
1552         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1553                    OMX_COMPONENT_GENERATE_EVENT);
1554         eRet = OMX_ErrorIncorrectStateTransition;
1555       }
1556       /* Requesting transition from WaitForResources to Invalid */
1557       else if(eState == OMX_StateInvalid)
1558       {
1559         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
1560         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1561         eRet = OMX_ErrorInvalidState;
1562       }
1563       /* Requesting transition from WaitForResources to Loaded -
1564       is NOT tested by Khronos TS */
1565
1566     }
1567     else
1568     {
1569       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
1570       eRet = OMX_ErrorBadParameter;
1571     }
1572   }
1573   /********************************/
1574   /* Current State is Invalid */
1575   /*******************************/
1576   else if(m_state == OMX_StateInvalid)
1577   {
1578     /* State Transition from Inavlid to any state */
1579     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
1580                   || OMX_StateIdle || OMX_StateExecuting
1581                   || OMX_StatePause || OMX_StateInvalid))
1582     {
1583       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
1584       post_event(OMX_EventError,OMX_ErrorInvalidState,\
1585                  OMX_COMPONENT_GENERATE_EVENT);
1586       eRet = OMX_ErrorInvalidState;
1587     }
1588   }
1589   else if (cmd == OMX_CommandFlush)
1590   {
1591     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
1592         "with param1: %d", param1);
1593     if(0 == param1 || OMX_ALL == param1)
1594     {
1595       BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1596     }
1597     if(1 == param1 || OMX_ALL == param1)
1598     {
1599       //generate output flush event only.
1600       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1601     }
1602     if (!sem_posted){
1603       sem_posted = 1;
1604       DEBUG_PRINT_LOW("\n Set the Semaphore");
1605       sem_post (&m_cmd_lock);
1606       execute_omx_flush(param1);
1607     }
1608     bFlag = 0;
1609   }
1610   else if ( cmd == OMX_CommandPortEnable)
1611   {
1612     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
1613         "with param1: %d", param1);
1614     if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
1615       {
1616         m_inp_bEnabled = OMX_TRUE;
1617
1618         if( (m_state == OMX_StateLoaded &&
1619              !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1620             || allocate_input_done())
1621         {
1622           post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
1623                      OMX_COMPONENT_GENERATE_EVENT);
1624         }
1625         else
1626         {
1627           DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
1628           BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1629           // Skip the event notification
1630           bFlag = 0;
1631         }
1632       }
1633       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
1634       {
1635           DEBUG_PRINT_LOW("\n Enable output Port command recieved");
1636           m_out_bEnabled = OMX_TRUE;
1637
1638           if( (m_state == OMX_StateLoaded &&
1639               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1640               || (allocate_output_done()))
1641           {
1642              post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
1643                         OMX_COMPONENT_GENERATE_EVENT);
1644
1645           }
1646           else
1647           {
1648               DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
1649               BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1650               // Skip the event notification
1651               bFlag = 0;
1652           }
1653       }
1654   }
1655   else if (cmd == OMX_CommandPortDisable)
1656   {
1657       DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
1658           "with param1: %d", param1);
1659       if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
1660       {
1661           m_inp_bEnabled = OMX_FALSE;
1662           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1663               && release_input_done())
1664           {
1665              post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
1666                         OMX_COMPONENT_GENERATE_EVENT);
1667           }
1668           else
1669           {
1670              BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1671              if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1672              {
1673                if(!sem_posted)
1674                {
1675                  sem_posted = 1;
1676                  sem_post (&m_cmd_lock);
1677                 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
1678                }
1679              }
1680
1681              // Skip the event notification
1682              bFlag = 0;
1683           }
1684       }
1685       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
1686       {
1687           m_out_bEnabled = OMX_FALSE;
1688           DEBUG_PRINT_LOW("\n Disable output Port command recieved");
1689           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1690               && release_output_done())
1691           {
1692              post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
1693                         OMX_COMPONENT_GENERATE_EVENT);
1694           }
1695           else
1696          {
1697             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1698             if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1699             {
1700               if(!sem_posted)
1701               {
1702                 sem_posted = 1;
1703                 sem_post (&m_cmd_lock);
1704                 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
1705               }
1706             }
1707             // Skip the event notification
1708             bFlag = 0;
1709
1710          }
1711       }
1712   }
1713   else
1714   {
1715     DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
1716     eRet = OMX_ErrorNotImplemented;
1717   }
1718   if(eRet == OMX_ErrorNone && bFlag)
1719   {
1720     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1721   }
1722   if(!sem_posted)
1723   {
1724     sem_post(&m_cmd_lock);
1725   }
1726
1727   return eRet;
1728 }
1729
1730 /* ======================================================================
1731 FUNCTION
1732   omx_vdec::ExecuteOmxFlush
1733
1734 DESCRIPTION
1735   Executes the OMX flush.
1736
1737 PARAMETERS
1738   flushtype - input flush(1)/output flush(0)/ both.
1739
1740 RETURN VALUE
1741   true/false
1742
1743 ========================================================================== */
1744 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
1745 {
1746   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1747   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_ALL;
1748   bool bRet = false;
1749
1750   if(flushType == 0 || flushType == OMX_ALL)
1751   {
1752     input_flush_progress = true;
1753     //flush input only
1754     bRet = execute_input_flush(flushType);
1755   }
1756   if(flushType == 1 || flushType == OMX_ALL)
1757   {
1758     //flush output only
1759     output_flush_progress = true;
1760     bRet = execute_output_flush(flushType);
1761   }
1762
1763   if(flushType == OMX_ALL)
1764   {
1765     /*Check if there are buffers with the Driver*/
1766     DEBUG_PRINT_LOW("\n Flush ALL ioctl issued");
1767     ioctl_msg.inputparam = &flush_dir;
1768     ioctl_msg.outputparam = NULL;
1769
1770     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1771     {
1772       DEBUG_PRINT_ERROR("\n Flush ALL Failed ");
1773       return false;
1774     }
1775   }
1776
1777   return bRet;
1778 }
1779 /*=========================================================================
1780 FUNCTION : execute_output_flush
1781
1782 DESCRIPTION
1783   Executes the OMX flush at OUTPUT PORT.
1784
1785 PARAMETERS
1786   None.
1787
1788 RETURN VALUE
1789   true/false
1790 ==========================================================================*/
1791 bool omx_vdec::execute_output_flush(OMX_U32 flushType)
1792 {
1793   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1794   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_OUTPUT;
1795   unsigned      p1 = 0; // Parameter - 1
1796   unsigned      p2 = 0; // Parameter - 2
1797   unsigned      ident = 0;
1798   bool bRet = true;
1799
1800   /*Generate FBD for all Buffers in the FTBq*/
1801   pthread_mutex_lock(&m_lock);
1802   DEBUG_PRINT_LOW("\n Initiate Output Flush");
1803   while (m_ftb_q.m_size)
1804   {
1805     DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
1806                        m_ftb_q.m_size,pending_output_buffers);
1807     m_ftb_q.pop_entry(&p1,&p2,&ident);
1808
1809     if(ident == OMX_COMPONENT_GENERATE_FTB )
1810     {
1811       DEBUG_PRINT_LOW("\n Inside Flush Buffer OMX_COMPONENT_GENERATE_FTB");
1812       pending_output_buffers++;
1813       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1814     }
1815     else if (ident == OMX_COMPONENT_GENERATE_FBD)
1816     {
1817       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1818     }
1819   }
1820   pthread_mutex_unlock(&m_lock);
1821
1822   if(gate_output_buffers)
1823   {
1824     DEBUG_PRINT_LOW("\n Output Buffers gated Check flush response");
1825     if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1826     {
1827       DEBUG_PRINT_LOW("\n Notify Output Flush done");
1828       BITMASK_CLEAR (&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1829       m_cb.EventHandler(&m_cmp,m_app_data,OMX_EventCmdComplete,OMX_CommandFlush,
1830                                OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1831     }
1832     output_flush_progress = false;
1833     return bRet;
1834   }
1835
1836   DEBUG_PRINT_LOW("\n output buffers count = %d",pending_output_buffers);
1837
1838   if(flushType == 1)
1839   {
1840     /*Check if there are buffers with the Driver*/
1841     DEBUG_PRINT_LOW("\n ioctl command flush for output");
1842     ioctl_msg.inputparam = &flush_dir;
1843     ioctl_msg.outputparam = NULL;
1844
1845     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1846     {
1847       DEBUG_PRINT_ERROR("\n output flush failed");
1848       return false;
1849     }
1850   }
1851
1852   return bRet;
1853 }
1854 /*=========================================================================
1855 FUNCTION : execute_input_flush
1856
1857 DESCRIPTION
1858   Executes the OMX flush at INPUT PORT.
1859
1860 PARAMETERS
1861   None.
1862
1863 RETURN VALUE
1864   true/false
1865 ==========================================================================*/
1866 bool omx_vdec::execute_input_flush(OMX_U32 flushType)
1867 {
1868   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1869   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT;
1870   unsigned       i =0;
1871   unsigned      p1 = 0; // Parameter - 1
1872   unsigned      p2 = 0; // Parameter - 2
1873   unsigned      ident = 0;
1874   bool bRet = true;
1875
1876   /*Generate EBD for all Buffers in the ETBq*/
1877   DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
1878
1879   pthread_mutex_lock(&m_lock);
1880   DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
1881   while (m_etb_q.m_size)
1882   {
1883     m_etb_q.pop_entry(&p1,&p2,&ident);
1884
1885     if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
1886     {
1887       DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
1888       m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
1889     }
1890     else if(ident == OMX_COMPONENT_GENERATE_ETB)
1891     {
1892       pending_input_buffers++;
1893       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1894     }
1895     else if (ident == OMX_COMPONENT_GENERATE_EBD)
1896     {
1897       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1898     }
1899   }
1900
1901   /*Check if Heap Buffers are to be flushed*/
1902   if (arbitrary_bytes)
1903   {
1904     DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
1905     h264_scratch.nFilledLen = 0;
1906     nal_count = 0;
1907     look_ahead_nal = false;
1908     frame_count = 0;
1909     DEBUG_PRINT_LOW("\n Initialize parser");
1910     if (m_frame_parser.mutils)
1911     {
1912       m_frame_parser.mutils->initialize_frame_checking_environment();
1913     }
1914
1915     while (m_input_pending_q.m_size)
1916     {
1917       m_input_pending_q.pop_entry(&p1,&p2,&ident);
1918       m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
1919     }
1920
1921     if (psource_frame)
1922     {
1923       m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
1924       psource_frame = NULL;
1925     }
1926
1927     if (pdest_frame)
1928     {
1929       pdest_frame->nFilledLen = 0;
1930       m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
1931       pdest_frame = NULL;
1932     }
1933     m_frame_parser.flush();
1934   }
1935
1936   pthread_mutex_unlock(&m_lock);
1937   DEBUG_PRINT_LOW("\n Value of pending input buffers %d \n",pending_input_buffers);
1938
1939   if(flushType == 0)
1940   {
1941     /*Check if there are buffers with the Driver*/
1942     DEBUG_PRINT_LOW("\n Input Flush ioctl issued");
1943     ioctl_msg.inputparam = &flush_dir;
1944     ioctl_msg.outputparam = NULL;
1945
1946     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1947     {
1948       DEBUG_PRINT_ERROR("\n Input Flush Failed ");
1949       return false;
1950     }
1951   }
1952
1953   return bRet;
1954 }
1955
1956
1957 /* ======================================================================
1958 FUNCTION
1959   omx_vdec::SendCommandEvent
1960
1961 DESCRIPTION
1962   Send the event to decoder pipe.  This is needed to generate the callbacks
1963   in decoder thread context.
1964
1965 PARAMETERS
1966   None.
1967
1968 RETURN VALUE
1969   true/false
1970
1971 ========================================================================== */
1972 bool omx_vdec::post_event(unsigned int p1,
1973                           unsigned int p2,
1974                           unsigned int id)
1975 {
1976   bool bRet      =                      false;
1977
1978
1979   pthread_mutex_lock(&m_lock);
1980
1981   if( id == OMX_COMPONENT_GENERATE_FTB || \
1982       (id == OMX_COMPONENT_GENERATE_FBD)||
1983       (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH))
1984   {
1985     m_ftb_q.insert_entry(p1,p2,id);
1986   }
1987   else if((id == OMX_COMPONENT_GENERATE_ETB) \
1988           || (id == OMX_COMPONENT_GENERATE_EBD)||
1989           (id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)||
1990           (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH))
1991   {
1992     m_etb_q.insert_entry(p1,p2,id);
1993   }
1994   else
1995   {
1996     m_cmd_q.insert_entry(p1,p2,id);
1997   }
1998
1999   bRet = true;
2000   DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2001   post_message(this, id);
2002
2003   pthread_mutex_unlock(&m_lock);
2004
2005   return bRet;
2006 }
2007
2008 /* ======================================================================
2009 FUNCTION
2010   omx_vdec::GetParameter
2011
2012 DESCRIPTION
2013   OMX Get Parameter method implementation
2014
2015 PARAMETERS
2016   <TBD>.
2017
2018 RETURN VALUE
2019   Error None if successful.
2020
2021 ========================================================================== */
2022 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2023                                            OMX_IN OMX_INDEXTYPE paramIndex,
2024                                            OMX_INOUT OMX_PTR     paramData)
2025 {
2026     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2027     unsigned int height=0,width = 0;
2028
2029     DEBUG_PRINT_LOW("get_parameter: \n");
2030     if(m_state == OMX_StateInvalid)
2031     {
2032         DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2033         return OMX_ErrorInvalidState;
2034     }
2035     if(paramData == NULL)
2036     {
2037         DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2038         return OMX_ErrorBadParameter;
2039     }
2040   switch(paramIndex)
2041   {
2042     case OMX_IndexParamPortDefinition:
2043     {
2044       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2045       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2046
2047       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2048
2049         portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
2050         portDefn->nSize = sizeof(portDefn);
2051         portDefn->eDomain    = OMX_PortDomainVideo;
2052         portDefn->format.video.nFrameHeight =  m_crop_dy;
2053         portDefn->format.video.nFrameWidth  =  m_crop_dx;
2054         portDefn->format.video.nStride = m_width;
2055         portDefn->format.video.nSliceHeight = m_height;
2056         portDefn->format.video.xFramerate= 25;
2057
2058       if (0 == portDefn->nPortIndex)
2059       {
2060         portDefn->eDir =  OMX_DirInput;
2061         /*Actual count is based on input buffer count*/
2062         portDefn->nBufferCountActual = m_inp_buf_count;
2063         /*Set the Min count*/
2064         portDefn->nBufferCountMin    = m_inp_buf_count_min;
2065         portDefn->nBufferSize        = m_inp_buf_size;
2066         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
2067         portDefn->format.video.eCompressionFormat = eCompressionFormat;
2068         portDefn->bEnabled   = m_inp_bEnabled;
2069         portDefn->bPopulated = m_inp_bPopulated;
2070       }
2071       else if (1 == portDefn->nPortIndex)
2072       {
2073         m_out_buf_count = m_out_buf_count_recon;
2074         m_out_buf_count_min = m_out_buf_count_min_recon;
2075         m_out_buf_size = m_out_buf_size_recon;
2076         portDefn->eDir =  OMX_DirOutput;
2077         portDefn->nBufferCountActual = m_out_buf_count;
2078         portDefn->nBufferCountMin    = m_out_buf_count_min;
2079         portDefn->nBufferSize = m_out_buf_size;
2080         portDefn->bEnabled   = m_out_bEnabled;
2081         portDefn->bPopulated = m_out_bPopulated;
2082         height = driver_context.video_resoultion.frame_height;
2083         width = driver_context.video_resoultion.frame_width;
2084
2085         portDefn->format.video.nFrameHeight =  height;
2086         portDefn->format.video.nFrameWidth  =  width;
2087         portDefn->format.video.nStride      = stride;
2088         portDefn->format.video.nSliceHeight = scan_lines;
2089         DEBUG_PRINT_LOW("\n Get Param Slice Height %d Slice Width %d",
2090                            scan_lines,stride);
2091         //TODO: Need to add color format
2092         portDefn->format.video.eColorFormat = m_color_format;
2093         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2094         DEBUG_PRINT_LOW("\n Output Actual %d Output Min %d",
2095                            portDefn->nBufferCountActual,portDefn->nBufferCountMin);
2096       }
2097       else
2098       {
2099         portDefn->eDir =  OMX_DirMax;
2100         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
2101                  (int)portDefn->nPortIndex);
2102         eRet = OMX_ErrorBadPortIndex;
2103       }
2104
2105       break;
2106     }
2107     case OMX_IndexParamVideoInit:
2108     {
2109       OMX_PORT_PARAM_TYPE *portParamType =
2110                               (OMX_PORT_PARAM_TYPE *) paramData;
2111       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2112
2113       portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2114       portParamType->nSize = sizeof(portParamType);
2115       portParamType->nPorts           = 2;
2116       portParamType->nStartPortNumber = 0;
2117       break;
2118     }
2119     case OMX_IndexParamVideoPortFormat:
2120     {
2121       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2122                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2123       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2124
2125       portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2126       portFmt->nSize             = sizeof(portFmt);
2127
2128       if (0 == portFmt->nPortIndex)
2129       {
2130         if (0 == portFmt->nIndex)
2131         {
2132               portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
2133               portFmt->eCompressionFormat = eCompressionFormat;
2134         }
2135         else
2136         {
2137           DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2138               " NoMore compression formats\n");
2139           eRet =  OMX_ErrorNoMore;
2140         }
2141       }
2142       else if (1 == portFmt->nPortIndex)
2143       {
2144         if (0 == portFmt->nIndex)
2145         {
2146            if (driver_context.output_format == VDEC_YUV_FORMAT_NV12)
2147              portFmt->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2148            else
2149             portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)0x7F000000;
2150
2151            portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
2152         }
2153         else
2154         {
2155            DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2156                   " NoMore Color formats\n");
2157            eRet =  OMX_ErrorNoMore;
2158         }
2159       }
2160       else
2161       {
2162         DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2163                           (int)portFmt->nPortIndex);
2164         eRet = OMX_ErrorBadPortIndex;
2165       }
2166       break;
2167     }
2168     /*Component should support this port definition*/
2169     case OMX_IndexParamAudioInit:
2170     {
2171         OMX_PORT_PARAM_TYPE *audioPortParamType =
2172                                               (OMX_PORT_PARAM_TYPE *) paramData;
2173         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2174         audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2175         audioPortParamType->nSize = sizeof(audioPortParamType);
2176         audioPortParamType->nPorts           = 0;
2177         audioPortParamType->nStartPortNumber = 0;
2178         break;
2179     }
2180     /*Component should support this port definition*/
2181     case OMX_IndexParamImageInit:
2182     {
2183         OMX_PORT_PARAM_TYPE *imagePortParamType =
2184                                               (OMX_PORT_PARAM_TYPE *) paramData;
2185         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2186         imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2187         imagePortParamType->nSize = sizeof(imagePortParamType);
2188         imagePortParamType->nPorts           = 0;
2189         imagePortParamType->nStartPortNumber = 0;
2190         break;
2191
2192     }
2193     /*Component should support this port definition*/
2194     case OMX_IndexParamOtherInit:
2195     {
2196         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2197                           paramIndex);
2198         eRet =OMX_ErrorUnsupportedIndex;
2199         break;
2200     }
2201     case OMX_IndexParamStandardComponentRole:
2202     {
2203         OMX_PARAM_COMPONENTROLETYPE *comp_role;
2204         comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2205         comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2206         comp_role->nSize = sizeof(*comp_role);
2207
2208         DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2209                     paramIndex);
2210         strncpy((char*)comp_role->cRole,(const char*)m_cRole,
2211                     OMX_MAX_STRINGNAME_SIZE);
2212         break;
2213     }
2214     /* Added for parameter test */
2215     case OMX_IndexParamPriorityMgmt:
2216         {
2217
2218             OMX_PRIORITYMGMTTYPE *priorityMgmType =
2219                                              (OMX_PRIORITYMGMTTYPE *) paramData;
2220             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2221             priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2222             priorityMgmType->nSize = sizeof(priorityMgmType);
2223
2224             break;
2225         }
2226     /* Added for parameter test */
2227     case OMX_IndexParamCompBufferSupplier:
2228         {
2229             OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2230                                      (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2231             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2232
2233             bufferSupplierType->nSize = sizeof(bufferSupplierType);
2234             bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2235             if(0 == bufferSupplierType->nPortIndex)
2236                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2237             else if (1 == bufferSupplierType->nPortIndex)
2238                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2239             else
2240                 eRet = OMX_ErrorBadPortIndex;
2241
2242
2243             break;
2244         }
2245     case OMX_IndexParamVideoAvc:
2246         {
2247             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2248                         paramIndex);
2249             break;
2250         }
2251     case OMX_IndexParamVideoH263:
2252         {
2253             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2254                         paramIndex);
2255             break;
2256         }
2257     case OMX_IndexParamVideoMpeg4:
2258         {
2259             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2260                         paramIndex);
2261             break;
2262         }
2263     default:
2264     {
2265       DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2266       eRet =OMX_ErrorUnsupportedIndex;
2267     }
2268
2269   }
2270
2271   DEBUG_PRINT_LOW("\n get_parameter returning Height %d , Width %d \n",
2272               m_height, m_width);
2273   return eRet;
2274
2275 }
2276
2277 /* ======================================================================
2278 FUNCTION
2279   omx_vdec::Setparameter
2280
2281 DESCRIPTION
2282   OMX Set Parameter method implementation.
2283
2284 PARAMETERS
2285   <TBD>.
2286
2287 RETURN VALUE
2288   OMX Error None if successful.
2289
2290 ========================================================================== */
2291 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2292                                            OMX_IN OMX_INDEXTYPE paramIndex,
2293                                            OMX_IN OMX_PTR        paramData)
2294 {
2295     OMX_ERRORTYPE eRet = OMX_ErrorNone;
2296     struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
2297     unsigned int   alignment = 0,buffer_size = 0;
2298     int           i;
2299
2300     if(m_state == OMX_StateInvalid)
2301     {
2302         DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2303         return OMX_ErrorInvalidState;
2304     }
2305     if(paramData == NULL)
2306     {
2307          DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2308          return OMX_ErrorBadParameter;
2309     }
2310   switch(paramIndex)
2311   {
2312     case OMX_IndexParamPortDefinition:
2313     {
2314       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2315       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2316
2317       /*set_parameter can be called in loaded state
2318       or disabled port */
2319
2320       /* When the component is in Loaded state and IDLE Pending*/
2321       if(((m_state == OMX_StateLoaded)&&
2322           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2323          /* Or while the I/P or the O/P port or disabled */
2324          ||((OMX_DirInput == portDefn->eDir && m_inp_bEnabled == OMX_FALSE)||
2325          (OMX_DirOutput == portDefn->eDir && m_out_bEnabled == OMX_FALSE)))
2326       {
2327        DEBUG_PRINT_LOW("Set Parameter called in valid state");
2328       }
2329       else
2330       {
2331          DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2332          return OMX_ErrorIncorrectStateOperation;
2333       }
2334       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2335              (int)portDefn->format.video.nFrameHeight,
2336              (int)portDefn->format.video.nFrameWidth);
2337
2338       eRet = omx_vdec_validate_port_param(portDefn->format.video.nFrameHeight,
2339                                           portDefn->format.video.nFrameWidth);
2340       if(eRet != OMX_ErrorNone)
2341       {
2342          return OMX_ErrorUnsupportedSetting;
2343       }
2344       if(OMX_DirOutput == portDefn->eDir)
2345       {
2346           if ( portDefn->nBufferCountActual < m_out_buf_count_min ||
2347                portDefn->nBufferSize !=  m_out_buf_size
2348               )
2349           {
2350               return OMX_ErrorBadParameter;
2351           }
2352           driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2353           ioctl_msg.inputparam = NULL;
2354           ioctl_msg.outputparam = &driver_context.output_buffer;
2355
2356           if (ioctl (driver_context.video_driver_fd,
2357                      VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2358           {
2359               DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2360               return OMX_ErrorUnsupportedSetting;
2361           }
2362           driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2363           driver_context.output_buffer.actualcount =
2364                                                 portDefn->nBufferCountActual;
2365           ioctl_msg.inputparam = &driver_context.output_buffer;
2366           ioctl_msg.outputparam = NULL;
2367
2368           if (ioctl (driver_context.video_driver_fd,
2369                      VDEC_IOCTL_SET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2370           {
2371               DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2372               return OMX_ErrorUnsupportedSetting;
2373           }
2374           m_out_buf_count = portDefn->nBufferCountActual;
2375           m_out_buf_count_recon = m_out_buf_count;
2376         DEBUG_PRINT_LOW("set_parameter:OMX_IndexParamPortDefinition output port\n");
2377       }
2378       else if(OMX_DirInput == portDefn->eDir)
2379       {
2380          if(m_height != portDefn->format.video.nFrameHeight ||
2381             m_width  != portDefn->format.video.nFrameWidth)
2382          {
2383            DEBUG_PRINT_LOW("set_parameter ip port: stride %d\n",
2384                        (int)portDefn->format.video.nStride);
2385            // set the HxW only if non-zero
2386            if((portDefn->format.video.nFrameHeight != 0x0)
2387               && (portDefn->format.video.nFrameWidth != 0x0))
2388            {
2389                m_crop_x = m_crop_y = 0;
2390                m_crop_dy = m_port_height = m_height =
2391                  portDefn->format.video.nFrameHeight;
2392                m_crop_dx = m_port_width = m_width  =
2393                  portDefn->format.video.nFrameWidth;
2394                scan_lines = portDefn->format.video.nSliceHeight;
2395                stride = portDefn->format.video.nStride;
2396                DEBUG_PRINT_LOW("\n SetParam with new H %d and W %d\n",
2397                            m_height, m_width );
2398                driver_context.video_resoultion.frame_height = m_height;
2399                driver_context.video_resoultion.frame_width = m_width;
2400                driver_context.video_resoultion.stride = stride;
2401                driver_context.video_resoultion.scan_lines = scan_lines;
2402                ioctl_msg.inputparam = &driver_context.video_resoultion;
2403                ioctl_msg.outputparam = NULL;
2404
2405                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
2406                           (void*)&ioctl_msg) < 0)
2407                {
2408                    DEBUG_PRINT_ERROR("\n Set Resolution failed");
2409                    return OMX_ErrorUnsupportedSetting;
2410                }
2411                driver_context.output_buffer.buffer_type =
2412                                                         VDEC_BUFFER_TYPE_OUTPUT;
2413                ioctl_msg.inputparam = NULL;
2414                ioctl_msg.outputparam = &driver_context.output_buffer;
2415
2416                if (ioctl (driver_context.video_driver_fd,
2417                           VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2418                {
2419                    DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2420                    return OMX_ErrorUnsupportedSetting;
2421                }
2422
2423                m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount;
2424                m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount;
2425
2426                alignment = driver_context.output_buffer.alignment;
2427                buffer_size = driver_context.output_buffer.buffer_size;
2428                m_out_buf_size_recon = m_out_buf_size =
2429                  ((buffer_size + alignment - 1) & (~(alignment - 1)));
2430            }
2431         }
2432         else
2433         {
2434             /*
2435               If actual buffer count is greater than the Min buffer
2436               count,change the actual count.
2437               m_inp_buf_count is initialized to OMX_CORE_NUM_INPUT_BUFFERS
2438               in the constructor
2439             */
2440             if ( portDefn->nBufferCountActual < m_inp_buf_count_min ||
2441                  portDefn->nBufferSize !=  m_inp_buf_size
2442                 )
2443             {
2444                 return OMX_ErrorBadParameter;
2445             }
2446                /*Get the Buffer requirements for input and output ports*/
2447                driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
2448                ioctl_msg.inputparam = NULL;
2449                ioctl_msg.outputparam = &driver_context.input_buffer;
2450
2451                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
2452                           (void*)&ioctl_msg) < 0)
2453                {
2454                    DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
2455                    return OMX_ErrorUnsupportedSetting;
2456                }
2457
2458                driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
2459                driver_context.input_buffer.actualcount =
2460                  portDefn->nBufferCountActual;
2461                ioctl_msg.inputparam = &driver_context.input_buffer;
2462                ioctl_msg.outputparam = NULL;
2463
2464                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
2465                           (void*)&ioctl_msg) < 0)
2466                {
2467                    DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
2468                    return OMX_ErrorUnsupportedSetting;
2469                }
2470
2471             m_inp_buf_count = portDefn->nBufferCountActual;
2472           DEBUG_PRINT_LOW("\n set_parameter: Image Dimensions same  \n");
2473         }
2474
2475       }
2476       else if (portDefn->eDir ==  OMX_DirMax)
2477       {
2478           DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2479                       (int)portDefn->nPortIndex);
2480           eRet = OMX_ErrorBadPortIndex;
2481       }
2482     }
2483     break;
2484
2485
2486     case OMX_IndexParamVideoPortFormat:
2487     {
2488       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2489                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2490       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2491               portFmt->eColorFormat);
2492
2493       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2494              portFmt->eColorFormat);
2495       if(1 == portFmt->nPortIndex)
2496       {
2497
2498          m_color_format = portFmt->eColorFormat;
2499       }
2500     }
2501     break;
2502
2503     case OMX_QcomIndexPortDefn:
2504     {
2505         OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
2506             (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
2507         DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
2508             portFmt->nFramePackingFormat);
2509
2510         /* Input port */
2511         if (portFmt->nPortIndex == 0)
2512         {
2513             if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
2514             {
2515                arbitrary_bytes = true;
2516             }
2517             else if (portFmt->nFramePackingFormat ==
2518                 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
2519             {
2520                arbitrary_bytes = false;
2521             }
2522             else
2523             {
2524                 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
2525                     portFmt->nFramePackingFormat);
2526                 eRet = OMX_ErrorUnsupportedSetting;
2527             }
2528         }
2529     }
2530     break;
2531
2532      case OMX_IndexParamStandardComponentRole:
2533      {
2534           OMX_PARAM_COMPONENTROLETYPE *comp_role;
2535           comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2536           DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
2537                        comp_role->cRole);
2538
2539           if((m_state == OMX_StateLoaded)&&
2540               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2541           {
2542            DEBUG_PRINT_LOW("Set Parameter called in valid state");
2543           }
2544           else
2545           {
2546              DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2547              return OMX_ErrorIncorrectStateOperation;
2548           }
2549
2550           if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2551           {
2552               if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2553               {
2554                   strncpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2555               }
2556               else
2557               {
2558                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2559                   eRet =OMX_ErrorUnsupportedSetting;
2560               }
2561           }
2562           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2563           {
2564               if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2565               {
2566                   strncpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
2567               }
2568               else
2569               {
2570                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2571                   eRet = OMX_ErrorUnsupportedSetting;
2572               }
2573           }
2574           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
2575           {
2576               if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
2577               {
2578                   strncpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
2579               }
2580               else
2581               {
2582                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2583                   eRet =OMX_ErrorUnsupportedSetting;
2584               }
2585           }
2586           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
2587           {
2588               if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
2589               {
2590                   strncpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
2591               }
2592               else
2593               {
2594                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2595                   eRet =OMX_ErrorUnsupportedSetting;
2596               }
2597           }
2598           else
2599           {
2600                DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", driver_context.kind);
2601                eRet = OMX_ErrorInvalidComponentName;
2602           }
2603           break;
2604      }
2605
2606     case OMX_IndexParamPriorityMgmt:
2607         {
2608             if(m_state != OMX_StateLoaded)
2609             {
2610                DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2611                return OMX_ErrorIncorrectStateOperation;
2612             }
2613             OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
2614             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
2615               priorityMgmtype->nGroupID);
2616
2617             DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
2618              priorityMgmtype->nGroupPriority);
2619
2620             m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
2621             m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
2622
2623             break;
2624         }
2625
2626       case OMX_IndexParamCompBufferSupplier:
2627       {
2628           OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2629             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
2630                 bufferSupplierType->eBufferSupplier);
2631              if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
2632                 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
2633
2634              else
2635
2636              eRet = OMX_ErrorBadPortIndex;
2637
2638           break;
2639
2640       }
2641       case OMX_IndexParamVideoAvc:
2642           {
2643               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
2644                     paramIndex);
2645               break;
2646           }
2647       case OMX_IndexParamVideoH263:
2648           {
2649               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
2650                     paramIndex);
2651               break;
2652           }
2653       case OMX_IndexParamVideoMpeg4:
2654           {
2655               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
2656                     paramIndex);
2657               break;
2658           }
2659
2660     default:
2661     {
2662       DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
2663       eRet = OMX_ErrorUnsupportedIndex;
2664     }
2665   }
2666
2667   return eRet;
2668 }
2669
2670 /* ======================================================================
2671 FUNCTION
2672   omx_vdec::GetConfig
2673
2674 DESCRIPTION
2675   OMX Get Config Method implementation.
2676
2677 PARAMETERS
2678   <TBD>.
2679
2680 RETURN VALUE
2681   OMX Error None if successful.
2682
2683 ========================================================================== */
2684 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
2685                                         OMX_IN OMX_INDEXTYPE configIndex,
2686                                         OMX_INOUT OMX_PTR     configData)
2687 {
2688   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2689
2690   if (m_state == OMX_StateInvalid)
2691   {
2692      DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
2693      return OMX_ErrorInvalidState;
2694   }
2695
2696   switch (configIndex)
2697   {
2698     case OMX_QcomIndexConfigInterlaced:
2699     {
2700       OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
2701                                    (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
2702       if (configFmt->nPortIndex == 1)
2703       {
2704         if (configFmt->nIndex == 0)
2705         {
2706           configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
2707         }
2708         else if (configFmt->nIndex == 1)
2709         {
2710           configFmt->eInterlaceType =
2711                                   OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
2712         }
2713         else if (configFmt->nIndex == 2)
2714         {
2715           configFmt->eInterlaceType =
2716           OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
2717         }
2718         else
2719         {
2720           DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
2721                             " NoMore Interlaced formats\n");
2722           eRet = OMX_ErrorNoMore;
2723         }
2724
2725       }
2726       else
2727       {
2728         DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
2729         (int)configFmt->nPortIndex);
2730         eRet = OMX_ErrorBadPortIndex;
2731       }
2732     break;
2733     }
2734     case OMX_QcomIndexQueryNumberOfVideoDecInstance:
2735     {
2736         struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
2737         QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
2738           (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
2739         ioctl_msg.outputparam = (void*)&decoderinstances->nNumOfInstances;
2740         (void)(ioctl(driver_context.video_driver_fd,
2741                VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
2742     break;
2743     }
2744     default:
2745     {
2746       DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
2747       eRet = OMX_ErrorBadParameter;
2748     }
2749
2750   }
2751
2752   return eRet;
2753 }
2754
2755 /* ======================================================================
2756 FUNCTION
2757   omx_vdec::SetConfig
2758
2759 DESCRIPTION
2760   OMX Set Config method implementation
2761
2762 PARAMETERS
2763   <TBD>.
2764
2765 RETURN VALUE
2766   OMX Error None if successful.
2767 ========================================================================== */
2768 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
2769                                         OMX_IN OMX_INDEXTYPE configIndex,
2770                                         OMX_IN OMX_PTR        configData)
2771 {
2772   if(m_state == OMX_StateInvalid)
2773   {
2774       DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
2775       return OMX_ErrorInvalidState;
2776   }
2777
2778   OMX_ERRORTYPE ret = OMX_ErrorNone;
2779   OMX_VIDEO_CONFIG_NALSIZE *pNal;
2780
2781   DEBUG_PRINT_LOW("\n Set Config Called");
2782
2783   if (m_state == OMX_StateExecuting)
2784   {
2785      DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
2786      return ret;
2787   }
2788
2789   if (configIndex == OMX_IndexVendorVideoExtraData)
2790   {
2791     OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
2792     DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
2793     if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.avc"))
2794     {
2795       DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
2796       OMX_U32 extra_size;
2797       // Parsing done here for the AVC atom is definitely not generic
2798       // Currently this piece of code is working, but certainly
2799       // not tested with all .mp4 files.
2800       // Incase of failure, we might need to revisit this
2801       // for a generic piece of code.
2802
2803       // Retrieve size of NAL length field
2804       // byte #4 contains the size of NAL lenght field
2805       nal_length = (config->pData[4] & 0x03) + 1;
2806
2807       extra_size = 0;
2808       if (nal_length > 2)
2809       {
2810         /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
2811         extra_size = (nal_length - 2) * 2;
2812       }
2813
2814       // SPS starts from byte #6
2815       OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
2816       OMX_U8 *pDestBuf;
2817       m_vendor_config.nPortIndex = config->nPortIndex;
2818
2819       // minus 6 --> SPS starts from byte #6
2820       // minus 1 --> picture param set byte to be ignored from avcatom
2821       m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
2822       m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
2823       OMX_U32 len;
2824       OMX_U8 index = 0;
2825       // case where SPS+PPS is sent as part of set_config
2826       pDestBuf = m_vendor_config.pData;
2827
2828       DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
2829            m_vendor_config.nPortIndex,
2830            m_vendor_config.nDataSize,
2831            m_vendor_config.pData);
2832       while (index < 2)
2833       {
2834         uint8 *psize;
2835         len = *pSrcBuf;
2836         len = len << 8;
2837         len |= *(pSrcBuf + 1);
2838         psize = (uint8 *) & len;
2839         memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
2840         for (int i = 0; i < nal_length; i++)
2841         {
2842           pDestBuf[i] = psize[nal_length - 1 - i];
2843         }
2844         //memcpy(pDestBuf,pSrcBuf,(len+2));
2845         pDestBuf += len + nal_length;
2846         pSrcBuf += len + 2;
2847         index++;
2848         pSrcBuf++;   // skip picture param set
2849         len = 0;
2850       }
2851     }
2852     else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4"))
2853     {
2854       m_vendor_config.nPortIndex = config->nPortIndex;
2855       m_vendor_config.nDataSize = config->nDataSize;
2856       m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
2857       memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
2858     }
2859     else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.vc1"))
2860     {
2861         if(m_vendor_config.pData)
2862         {
2863             free(m_vendor_config.pData);
2864             m_vendor_config.pData = NULL;
2865             m_vendor_config.nDataSize = 0;
2866         }
2867
2868         if (((*((OMX_U32 *) config->pData)) &
2869              VC1_SP_MP_START_CODE_MASK) ==
2870              VC1_SP_MP_START_CODE)
2871         {
2872             DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
2873             m_vendor_config.nPortIndex = config->nPortIndex;
2874             m_vendor_config.nDataSize = config->nDataSize;
2875             m_vendor_config.pData =
2876                 (OMX_U8 *) malloc(config->nDataSize);
2877             memcpy(m_vendor_config.pData, config->pData,
2878                    config->nDataSize);
2879             m_vc1_profile = VC1_SP_MP_RCV;
2880         }
2881         else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
2882         {
2883             DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
2884             m_vendor_config.nPortIndex = config->nPortIndex;
2885             m_vendor_config.nDataSize = config->nDataSize;
2886             m_vendor_config.pData =
2887                 (OMX_U8 *) malloc((config->nDataSize));
2888             memcpy(m_vendor_config.pData, config->pData,
2889                    config->nDataSize);
2890             m_vc1_profile = VC1_AP;
2891         }
2892         else if ((config->nDataSize == VC1_STRUCT_C_LEN))
2893         {
2894             DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
2895             m_vendor_config.nPortIndex = config->nPortIndex;
2896             m_vendor_config.nDataSize  = config->nDataSize;
2897             m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
2898             memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
2899             m_vc1_profile = VC1_SP_MP_RCV;
2900         }
2901         else
2902         {
2903             DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
2904         }
2905     }
2906     return ret;
2907   }
2908   else if (configIndex == OMX_IndexConfigVideoNalSize)
2909   {
2910
2911     pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
2912     nal_length = pNal->nNaluBytes;
2913     m_frame_parser.init_nal_length(nal_length);
2914     DEBUG_PRINT_LOW("\n Nal Length option called with Size %d",nal_length);
2915     return ret;
2916   }
2917
2918   return OMX_ErrorNotImplemented;
2919 }
2920
2921 /* ======================================================================
2922 FUNCTION
2923   omx_vdec::GetExtensionIndex
2924
2925 DESCRIPTION
2926   OMX GetExtensionIndex method implementaion.  <TBD>
2927
2928 PARAMETERS
2929   <TBD>.
2930
2931 RETURN VALUE
2932   OMX Error None if everything successful.
2933
2934 ========================================================================== */
2935 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
2936                                                 OMX_IN OMX_STRING      paramName,
2937                                                 OMX_OUT OMX_INDEXTYPE* indexType)
2938 {
2939     DEBUG_PRINT_ERROR("get_extension_index: Error, Not implemented\n");
2940     if(m_state == OMX_StateInvalid)
2941     {
2942         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
2943         return OMX_ErrorInvalidState;
2944     }
2945     return OMX_ErrorNotImplemented;
2946 }
2947
2948 /* ======================================================================
2949 FUNCTION
2950   omx_vdec::GetState
2951
2952 DESCRIPTION
2953   Returns the state information back to the caller.<TBD>
2954
2955 PARAMETERS
2956   <TBD>.
2957
2958 RETURN VALUE
2959   Error None if everything is successful.
2960 ========================================================================== */
2961 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
2962                                        OMX_OUT OMX_STATETYPE* state)
2963 {
2964   *state = m_state;
2965   DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
2966   return OMX_ErrorNone;
2967 }
2968
2969 /* ======================================================================
2970 FUNCTION
2971   omx_vdec::ComponentTunnelRequest
2972
2973 DESCRIPTION
2974   OMX Component Tunnel Request method implementation. <TBD>
2975
2976 PARAMETERS
2977   None.
2978
2979 RETURN VALUE
2980   OMX Error None if everything successful.
2981
2982 ========================================================================== */
2983 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
2984                                                      OMX_IN OMX_U32                        port,
2985                                                      OMX_IN OMX_HANDLETYPE        peerComponent,
2986                                                      OMX_IN OMX_U32                    peerPort,
2987                                                      OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
2988 {
2989   DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
2990   return OMX_ErrorNotImplemented;
2991 }
2992
2993 /* ======================================================================
2994 FUNCTION
2995   omx_vdec::UseInputBuffer
2996
2997 DESCRIPTION
2998   Helper function for Use buffer in the input pin
2999
3000 PARAMETERS
3001   None.
3002
3003 RETURN VALUE
3004   true/false
3005
3006 ========================================================================== */
3007 OMX_ERRORTYPE  omx_vdec::use_input_buffer(
3008                          OMX_IN OMX_HANDLETYPE            hComp,
3009                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3010                          OMX_IN OMX_U32                   port,
3011                          OMX_IN OMX_PTR                   appData,
3012                          OMX_IN OMX_U32                   bytes,
3013                          OMX_IN OMX_U8*                   buffer)
3014 {
3015   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3016   struct vdec_setbuffer_cmd setbuffers;
3017   OMX_BUFFERHEADERTYPE *input = NULL;
3018   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3019   unsigned   i = 0;
3020   unsigned char *buf_addr = NULL;
3021   int pmem_fd = -1;
3022
3023   if(bytes != m_inp_buf_size)
3024   {
3025     return OMX_ErrorBadParameter;
3026   }
3027
3028   if(!m_inp_mem_ptr)
3029   {
3030     DEBUG_PRINT_HIGH("\n Use i/p buffer case - Header List allocation");
3031     input_use_buffer = true;
3032     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
3033     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
3034
3035     if (m_inp_mem_ptr == NULL)
3036     {
3037       return OMX_ErrorInsufficientResources;
3038     }
3039
3040     driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
3041     calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
3042
3043     if (driver_context.ptr_inputbuffer == NULL)
3044     {
3045       return OMX_ErrorInsufficientResources;
3046     }
3047
3048     for (i=0; i < m_inp_buf_count; i++)
3049     {
3050       driver_context.ptr_inputbuffer [i].pmem_fd = -1;
3051     }
3052   }
3053
3054   for(i=0; i< m_inp_buf_count; i++)
3055   {
3056     if(BITMASK_ABSENT(&m_inp_bm_count,i))
3057     {
3058       break;
3059     }
3060   }
3061
3062   if(i < m_inp_buf_count)
3063   {
3064     pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
3065
3066     if (pmem_fd < 0)
3067     {
3068       return OMX_ErrorInsufficientResources;
3069     }
3070
3071     if(pmem_fd == 0)
3072     {
3073       pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
3074       if (pmem_fd < 0)
3075       {
3076         return OMX_ErrorInsufficientResources;
3077       }
3078     }
3079
3080     if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
3081       driver_context.input_buffer.alignment))
3082     {
3083       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3084       close(pmem_fd);
3085       return OMX_ErrorInsufficientResources;
3086     }
3087
3088     buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
3089                     MAP_SHARED,pmem_fd,0);
3090
3091     if (buf_addr == MAP_FAILED)
3092     {
3093       return OMX_ErrorInsufficientResources;
3094     }
3095
3096     driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr;
3097     driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd;
3098     driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size;
3099     driver_context.ptr_inputbuffer [i].offset = 0;
3100
3101     setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
3102     memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i],
3103             sizeof (vdec_bufferpayload));
3104     ioctl_msg.inputparam  = &setbuffers;
3105     ioctl_msg.outputparam = NULL;
3106
3107     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
3108          &ioctl_msg) < 0)
3109     {
3110       return OMX_ErrorInsufficientResources;
3111     }
3112
3113     *bufferHdr = (m_inp_mem_ptr + i);
3114     input = *bufferHdr;
3115     BITMASK_SET(&m_inp_bm_count,i);
3116
3117     input->pBuffer           = (OMX_U8 *)buffer;
3118     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
3119     input->nVersion.nVersion = OMX_SPEC_VERSION;
3120     input->nAllocLen         = m_inp_buf_size;
3121     input->pAppPrivate       = appData;
3122     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
3123     input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i];
3124   }
3125   else
3126   {
3127     eRet = OMX_ErrorInsufficientResources;
3128   }
3129   return eRet;
3130 }
3131
3132
3133 /* ======================================================================
3134 FUNCTION
3135   omx_vdec::UseOutputBuffer
3136
3137 DESCRIPTION
3138   Helper function for Use buffer in the input pin
3139
3140 PARAMETERS
3141   None.
3142
3143 RETURN VALUE
3144   true/false
3145
3146 ========================================================================== */
3147 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
3148                          OMX_IN OMX_HANDLETYPE            hComp,
3149                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3150                          OMX_IN OMX_U32                   port,
3151                          OMX_IN OMX_PTR                   appData,
3152                          OMX_IN OMX_U32                   bytes,
3153                          OMX_IN OMX_U8*                   buffer)
3154 {
3155   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3156   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
3157   unsigned                         i= 0; // Temporary counter
3158
3159   if(!m_out_mem_ptr)
3160   {
3161     DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
3162     output_use_buffer = true;
3163     int nBufHdrSize        = 0;
3164     int nPlatformEntrySize = 0;
3165     int nPlatformListSize  = 0;
3166     int nPMEMInfoSize = 0;
3167     OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
3168     OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
3169     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
3170
3171     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
3172     nBufHdrSize        = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
3173
3174     nPMEMInfoSize      = m_out_buf_count *
3175                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
3176     nPlatformListSize  = m_out_buf_count *
3177                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
3178     nPlatformEntrySize = m_out_buf_count *
3179                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
3180
3181     DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
3182                          sizeof(OMX_BUFFERHEADERTYPE),
3183                          nPMEMInfoSize,
3184                          nPlatformListSize);
3185     DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
3186                          m_out_bm_count);
3187
3188     /*
3189      * Memory for output side involves the following:
3190      * 1. Array of Buffer Headers
3191      * 2. Platform specific information List
3192      * 3. Platform specific Entry List
3193      * 4. PMem Information entries
3194      * 5. Bitmask array to hold the buffer allocation details
3195      * In order to minimize the memory management entire allocation
3196      * is done in one step.
3197      */
3198     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
3199     // Alloc mem for platform specific info
3200     char *pPtr=NULL;
3201     pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
3202                                      nPMEMInfoSize,1);
3203     driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \
3204       calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count);
3205     driver_context.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
3206       calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count);
3207
3208     if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
3209        && driver_context.ptr_respbuffer)
3210     {
3211       bufHdr          =  m_out_mem_ptr;
3212       m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
3213       m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
3214                         (((char *) m_platform_list)  + nPlatformListSize);
3215       m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3216                         (((char *) m_platform_entry) + nPlatformEntrySize);
3217       pPlatformList   = m_platform_list;
3218       pPlatformEntry  = m_platform_entry;
3219       pPMEMInfo       = m_pmem_info;
3220
3221       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
3222
3223       // Settting the entire storage nicely
3224       DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
3225       DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
3226       for(i=0; i < m_out_buf_count ; i++)
3227       {
3228         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
3229         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
3230         // Set the values when we determine the right HxW param
3231         bufHdr->nAllocLen          = bytes;
3232         bufHdr->nFilledLen         = 0;
3233         bufHdr->pAppPrivate        = appData;
3234         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
3235         // Platform specific PMEM Information
3236         // Initialize the Platform Entry
3237         //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
3238         pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
3239         pPlatformEntry->entry      = pPMEMInfo;
3240         // Initialize the Platform List
3241         pPlatformList->nEntries    = 1;
3242         pPlatformList->entryList   = pPlatformEntry;
3243         // Keep pBuffer NULL till vdec is opened
3244         bufHdr->pBuffer            = NULL;
3245
3246         pPMEMInfo->offset          =  0;
3247         pPMEMInfo->pmem_fd = 0;
3248         bufHdr->pPlatformPrivate = pPlatformList;
3249
3250         driver_context.ptr_outputbuffer[i].pmem_fd = -1;
3251
3252         /*Create a mapping between buffers*/
3253         bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i];
3254         driver_context.ptr_respbuffer[i].client_data = (void *) \
3255                                             &driver_context.ptr_outputbuffer[i];
3256         // Move the buffer and buffer header pointers
3257         bufHdr++;
3258         pPMEMInfo++;
3259         pPlatformEntry++;
3260         pPlatformList++;
3261       }
3262     }
3263     else
3264     {
3265       DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
3266                                         m_out_mem_ptr, pPtr);
3267       if(m_out_mem_ptr)
3268       {
3269         free(m_out_mem_ptr);
3270         m_out_mem_ptr = NULL;
3271       }
3272       if(pPtr)
3273       {
3274         free(pPtr);
3275         pPtr = NULL;
3276       }
3277       if(driver_context.ptr_outputbuffer)
3278       {
3279         free(driver_context.ptr_outputbuffer);
3280         driver_context.ptr_outputbuffer = NULL;
3281       }
3282       if(driver_context.ptr_respbuffer)
3283       {
3284         free(driver_context.ptr_respbuffer);
3285         driver_context.ptr_respbuffer = NULL;
3286       }
3287       eRet =  OMX_ErrorInsufficientResources;
3288     }
3289   }
3290
3291   for(i=0; i< m_out_buf_count; i++)
3292   {
3293     if(BITMASK_ABSENT(&m_out_bm_count,i))
3294     {
3295       break;
3296     }
3297   }
3298
3299   if (eRet == OMX_ErrorNone)
3300   {
3301     if(i < m_out_buf_count)
3302     {
3303       driver_context.ptr_outputbuffer[i].pmem_fd = \
3304         open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3305
3306       if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
3307       {
3308         return OMX_ErrorInsufficientResources;
3309       }
3310
3311       if(driver_context.ptr_outputbuffer[i].pmem_fd == 0)
3312       {
3313         driver_context.ptr_outputbuffer[i].pmem_fd = \
3314           open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3315
3316         if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
3317         {
3318           return OMX_ErrorInsufficientResources;
3319         }
3320       }
3321
3322       if(!align_pmem_buffers(driver_context.ptr_outputbuffer[i].pmem_fd,
3323         m_out_buf_size, driver_context.output_buffer.alignment))
3324       {
3325         DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3326         close(driver_context.ptr_outputbuffer[i].pmem_fd);
3327         return OMX_ErrorInsufficientResources;
3328       }
3329
3330       driver_context.ptr_outputbuffer[i].bufferaddr =
3331         (unsigned char *)mmap(NULL,m_out_buf_size,PROT_READ|PROT_WRITE,
3332          MAP_SHARED,driver_context.ptr_outputbuffer[i].pmem_fd,0);
3333
3334       if (driver_context.ptr_outputbuffer[i].bufferaddr == MAP_FAILED)
3335       {
3336         return OMX_ErrorInsufficientResources;
3337       }
3338       driver_context.ptr_outputbuffer[i].offset = 0;
3339       m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset;
3340       m_pmem_info[i].pmem_fd = driver_context.ptr_outputbuffer[i].pmem_fd;
3341
3342       // found an empty buffer at i
3343       *bufferHdr = (m_out_mem_ptr + i );
3344       (*bufferHdr)->pBuffer = buffer;
3345       (*bufferHdr)->pAppPrivate = appData;
3346       BITMASK_SET(&m_out_bm_count,i);
3347     }
3348     else
3349     {
3350       DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
3351       eRet = OMX_ErrorInsufficientResources;
3352     }
3353   }
3354
3355   return eRet;
3356 }
3357
3358 /* ======================================================================
3359 FUNCTION
3360   omx_vdec::UseBuffer
3361
3362 DESCRIPTION
3363   OMX Use Buffer method implementation.
3364
3365 PARAMETERS
3366   <TBD>.
3367
3368 RETURN VALUE
3369   OMX Error None , if everything successful.
3370
3371 ========================================================================== */
3372 OMX_ERRORTYPE  omx_vdec::use_buffer(
3373                          OMX_IN OMX_HANDLETYPE            hComp,
3374                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3375                          OMX_IN OMX_U32                   port,
3376                          OMX_IN OMX_PTR                   appData,
3377                          OMX_IN OMX_U32                   bytes,
3378                          OMX_IN OMX_U8*                   buffer)
3379 {
3380     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3381     if(m_state == OMX_StateInvalid)
3382     {
3383         DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
3384         return OMX_ErrorInvalidState;
3385     }
3386     if(port == OMX_CORE_INPUT_PORT_INDEX)
3387     {
3388       eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3389     }
3390     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
3391     {
3392       eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3393     }
3394     else
3395     {
3396       DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
3397       eRet = OMX_ErrorBadPortIndex;
3398     }
3399     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, eRet);
3400
3401     if(eRet == OMX_ErrorNone)
3402     {
3403       if(allocate_done())
3404       {
3405         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3406         {
3407           // Send the callback now
3408           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3409           post_event(OMX_CommandStateSet,OMX_StateIdle,
3410                              OMX_COMPONENT_GENERATE_EVENT);
3411         }
3412       }
3413       if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
3414       {
3415         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
3416         {
3417           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3418           post_event(OMX_CommandPortEnable,
3419               OMX_CORE_INPUT_PORT_INDEX,
3420               OMX_COMPONENT_GENERATE_EVENT);
3421         }
3422
3423       }
3424       else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
3425       {
3426         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
3427         {
3428           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3429           post_event(OMX_CommandPortEnable,
3430                      OMX_CORE_OUTPUT_PORT_INDEX,
3431                      OMX_COMPONENT_GENERATE_EVENT);
3432           m_event_port_settings_sent = false;
3433         }
3434       }
3435     }
3436     return eRet;
3437 }
3438
3439 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3440 {
3441   unsigned int index = 0;
3442
3443   if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
3444   {
3445     return OMX_ErrorBadParameter;
3446   }
3447
3448   index = bufferHdr - m_inp_mem_ptr;
3449   DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
3450
3451   if (index < m_inp_buf_count && driver_context.ptr_inputbuffer)
3452   {
3453     DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
3454     if (driver_context.ptr_inputbuffer[index].pmem_fd > 0)
3455     {
3456        struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3457        struct vdec_setbuffer_cmd setbuffers;
3458        setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
3459        memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer[index],
3460           sizeof (vdec_bufferpayload));
3461        ioctl_msg.inputparam  = &setbuffers;
3462        ioctl_msg.outputparam = NULL;
3463        int ioctl_r = ioctl (driver_context.video_driver_fd,
3464                             VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
3465        if (ioctl_r < 0)
3466        {
3467           DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
3468        }
3469
3470        DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
3471                     driver_context.ptr_inputbuffer[index].pmem_fd);
3472        DEBUG_PRINT_LOW("\n unmap the input buffer size=%d  address = %d",
3473                     driver_context.ptr_inputbuffer[index].mmaped_size,
3474                     driver_context.ptr_inputbuffer[index].bufferaddr);
3475        munmap (driver_context.ptr_inputbuffer[index].bufferaddr,
3476                driver_context.ptr_inputbuffer[index].mmaped_size);
3477        close (driver_context.ptr_inputbuffer[index].pmem_fd);
3478        driver_context.ptr_inputbuffer[index].pmem_fd = -1;
3479     }
3480   }
3481
3482   return OMX_ErrorNone;
3483 }
3484
3485 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3486 {
3487   unsigned int index = 0;
3488
3489   if (bufferHdr == NULL || m_out_mem_ptr == NULL)
3490   {
3491     return OMX_ErrorBadParameter;
3492   }
3493
3494   index = bufferHdr - m_out_mem_ptr;
3495   DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
3496
3497   if (index < m_out_buf_count && driver_context.ptr_outputbuffer)
3498   {
3499     DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
3500                     driver_context.ptr_outputbuffer[index].bufferaddr);
3501
3502     if (!gate_output_buffers)
3503     {
3504       struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3505       struct vdec_setbuffer_cmd setbuffers;
3506       setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
3507       memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer[index],
3508         sizeof (vdec_bufferpayload));
3509       ioctl_msg.inputparam  = &setbuffers;
3510       ioctl_msg.outputparam = NULL;
3511       DEBUG_PRINT_LOW("\nRelease the Output Buffer");
3512       if (ioctl (driver_context.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
3513             &ioctl_msg) < 0)
3514         DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
3515     }
3516
3517     if (driver_context.ptr_outputbuffer[0].pmem_fd > 0)
3518     {
3519        DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
3520                     driver_context.ptr_outputbuffer[0].pmem_fd);
3521        DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d  address = %d",
3522                     driver_context.ptr_outputbuffer[0].mmaped_size,
3523                     driver_context.ptr_outputbuffer[0].bufferaddr);
3524        munmap (driver_context.ptr_outputbuffer[0].bufferaddr,
3525                driver_context.ptr_outputbuffer[0].mmaped_size);
3526        close (driver_context.ptr_outputbuffer[0].pmem_fd);
3527        driver_context.ptr_outputbuffer[0].pmem_fd = -1;
3528     }
3529   }
3530
3531   return OMX_ErrorNone;
3532
3533 }
3534
3535 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
3536                                          OMX_BUFFERHEADERTYPE **bufferHdr,
3537                                          OMX_U32              port,
3538                                          OMX_PTR              appData,
3539                                          OMX_U32              bytes)
3540 {
3541   OMX_BUFFERHEADERTYPE *input = NULL;
3542   unsigned char *buf_addr = NULL;
3543   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3544   unsigned   i = 0;
3545
3546   /* Sanity Check*/
3547   if (bufferHdr == NULL)
3548   {
3549     return OMX_ErrorBadParameter;
3550   }
3551
3552   if (m_inp_heap_ptr == NULL)
3553   {
3554     m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
3555                      calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
3556     m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
3557                      calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), m_inp_buf_count);
3558
3559     if (m_inp_heap_ptr == NULL)
3560     {
3561       DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
3562       return OMX_ErrorInsufficientResources;
3563     }
3564
3565     h264_scratch.nAllocLen = m_inp_buf_size;
3566     h264_scratch.pBuffer = (OMX_U8 *)malloc (m_inp_buf_size);
3567     h264_scratch.nFilledLen = 0;
3568     h264_scratch.nOffset = 0;
3569
3570     if (h264_scratch.pBuffer == NULL)
3571     {
3572       DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
3573       return OMX_ErrorInsufficientResources;
3574     }
3575
3576     if (m_frame_parser.mutils == NULL)
3577     {
3578        m_frame_parser.mutils = new H264_Utils();
3579
3580        if (m_frame_parser.mutils == NULL)
3581        {
3582          DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
3583          return OMX_ErrorInsufficientResources;
3584        }
3585
3586        m_frame_parser.mutils->initialize_frame_checking_environment();
3587        m_frame_parser.mutils->allocate_rbsp_buffer (m_inp_buf_size);
3588     }
3589   }
3590
3591   /*Find a Free index*/
3592   for(i=0; i< m_inp_buf_count; i++)
3593   {
3594     if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
3595     {
3596       DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
3597       break;
3598     }
3599   }
3600
3601   if (i < m_inp_buf_count)
3602   {
3603     buf_addr = (unsigned char *)malloc (m_inp_buf_size);
3604
3605     if (buf_addr == NULL)
3606     {
3607       return OMX_ErrorInsufficientResources;
3608     }
3609
3610     *bufferHdr = (m_inp_heap_ptr + i);
3611     input = *bufferHdr;
3612     BITMASK_SET(&m_heap_inp_bm_count,i);
3613
3614     input->pBuffer           = (OMX_U8 *)buf_addr;
3615     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
3616     input->nVersion.nVersion = OMX_SPEC_VERSION;
3617     input->nAllocLen         = m_inp_buf_size;
3618     input->pAppPrivate       = appData;
3619     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
3620     DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
3621     eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
3622     DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
3623     /*Add the Buffers to freeq*/
3624     if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL))
3625     {
3626       DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
3627       return OMX_ErrorInsufficientResources;
3628     }
3629   }
3630   else
3631   {
3632     return OMX_ErrorBadParameter;
3633   }
3634
3635   return eRet;
3636
3637 }
3638
3639
3640 /* ======================================================================
3641 FUNCTION
3642   omx_vdec::AllocateInputBuffer
3643
3644 DESCRIPTION
3645   Helper function for allocate buffer in the input pin
3646
3647 PARAMETERS
3648   None.
3649
3650 RETURN VALUE
3651   true/false
3652
3653 ========================================================================== */
3654 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
3655                          OMX_IN OMX_HANDLETYPE            hComp,
3656                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3657                          OMX_IN OMX_U32                   port,
3658                          OMX_IN OMX_PTR                   appData,
3659                          OMX_IN OMX_U32                   bytes)
3660 {
3661
3662   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3663   struct vdec_setbuffer_cmd setbuffers;
3664   OMX_BUFFERHEADERTYPE *input = NULL;
3665   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3666   unsigned   i = 0;
3667   unsigned char *buf_addr = NULL;
3668   int pmem_fd = -1;
3669
3670   if(bytes != m_inp_buf_size)
3671   {
3672     DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",bytes,m_inp_buf_size);
3673     //return OMX_ErrorBadParameter;
3674   }
3675
3676   if(!m_inp_mem_ptr)
3677   {
3678     DEBUG_PRINT_HIGH("\n Allocate i/p buffer case - Header List allocation");
3679     DEBUG_PRINT_LOW("\n Allocating input buffer count %d ",m_inp_buf_count);
3680     DEBUG_PRINT_LOW("\n Size of input buffer is %d",m_inp_buf_size);
3681
3682     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
3683     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
3684
3685     if (m_inp_mem_ptr == NULL)
3686     {
3687       return OMX_ErrorInsufficientResources;
3688     }
3689
3690     driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
3691     calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
3692
3693     if (driver_context.ptr_inputbuffer == NULL)
3694     {
3695       return OMX_ErrorInsufficientResources;
3696     }
3697
3698     for (i=0; i < m_inp_buf_count; i++)
3699     {
3700       driver_context.ptr_inputbuffer [i].pmem_fd = -1;
3701     }
3702   }
3703
3704   for(i=0; i< m_inp_buf_count; i++)
3705   {
3706     if(BITMASK_ABSENT(&m_inp_bm_count,i))
3707     {
3708       DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
3709       break;
3710     }
3711   }
3712
3713   if(i < m_inp_buf_count)
3714   {
3715     DEBUG_PRINT_LOW("\n Allocate input Buffer");
3716     pmem_fd = open ("/dev/pmem_adsp", O_RDWR, O_SYNC);
3717
3718     if (pmem_fd < 0)
3719     {
3720       DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
3721       return OMX_ErrorInsufficientResources;
3722     }
3723
3724     if (pmem_fd == 0)
3725     {
3726       pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3727
3728       if (pmem_fd < 0)
3729       {
3730         DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
3731         return OMX_ErrorInsufficientResources;
3732       }
3733     }
3734
3735     if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
3736       driver_context.input_buffer.alignment))
3737     {
3738       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3739       close(pmem_fd);
3740       return OMX_ErrorInsufficientResources;
3741     }
3742
3743     buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
3744                     MAP_SHARED,pmem_fd,0);
3745
3746     if (buf_addr == MAP_FAILED)
3747     {
3748       DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
3749       return OMX_ErrorInsufficientResources;
3750     }
3751
3752     driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr;
3753     driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd;
3754     driver_context.ptr_inputbuffer [i].buffer_len = m_inp_buf_size;
3755     driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size;
3756     driver_context.ptr_inputbuffer [i].offset = 0;
3757
3758     setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
3759     memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i],
3760             sizeof (vdec_bufferpayload));
3761     ioctl_msg.inputparam  = &setbuffers;
3762     ioctl_msg.outputparam = NULL;
3763
3764     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
3765          &ioctl_msg) < 0)
3766     {
3767       DEBUG_PRINT_ERROR("\n Set Buffers Failed");
3768       return OMX_ErrorInsufficientResources;
3769     }
3770
3771     *bufferHdr = (m_inp_mem_ptr + i);
3772     input = *bufferHdr;
3773     BITMASK_SET(&m_inp_bm_count,i);
3774     DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
3775
3776     input->pBuffer           = (OMX_U8 *)buf_addr;
3777     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
3778     input->nVersion.nVersion = OMX_SPEC_VERSION;
3779     input->nAllocLen         = m_inp_buf_size;
3780     input->pAppPrivate       = appData;
3781     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
3782     input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i];
3783   }
3784   else
3785   {
3786     DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
3787     eRet = OMX_ErrorInsufficientResources;
3788   }
3789   return eRet;
3790 }
3791
3792
3793 /* ======================================================================
3794 FUNCTION
3795   omx_vdec::AllocateOutputBuffer
3796
3797 DESCRIPTION
3798   Helper fn for AllocateBuffer in the output pin
3799
3800 PARAMETERS
3801   <TBD>.
3802
3803 RETURN VALUE
3804   OMX Error None if everything went well.
3805
3806 ========================================================================== */
3807 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
3808                          OMX_IN OMX_HANDLETYPE            hComp,
3809                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3810                          OMX_IN OMX_U32                   port,
3811                          OMX_IN OMX_PTR                   appData,
3812                          OMX_IN OMX_U32                   bytes)
3813 {
3814   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3815   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
3816   unsigned                         i= 0; // Temporary counter
3817   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3818   struct vdec_setbuffer_cmd setbuffers;
3819
3820   if(!m_out_mem_ptr)
3821   {
3822     DEBUG_PRINT_HIGH("\n Allocate o/p buffer case - Header List allocation");
3823     int nBufHdrSize        = 0;
3824     int nPlatformEntrySize = 0;
3825     int nPlatformListSize  = 0;
3826     int nPMEMInfoSize = 0;
3827     int pmem_fd = -1;
3828     unsigned char *pmem_baseaddress = NULL;
3829
3830     OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
3831     OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
3832     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
3833
3834     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
3835     nBufHdrSize        = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
3836
3837     nPMEMInfoSize      = m_out_buf_count *
3838                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
3839     nPlatformListSize  = m_out_buf_count *
3840                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
3841     nPlatformEntrySize = m_out_buf_count *
3842                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
3843
3844     DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
3845                          sizeof(OMX_BUFFERHEADERTYPE),
3846                          nPMEMInfoSize,
3847                          nPlatformListSize);
3848     DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
3849                          m_out_buf_count);
3850
3851     pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3852
3853     if (pmem_fd < 0)
3854     {
3855       DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
3856       return OMX_ErrorInsufficientResources;
3857     }
3858
3859     if(pmem_fd == 0)
3860     {
3861       pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3862
3863       if (pmem_fd < 0)
3864       {
3865         DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
3866         return OMX_ErrorInsufficientResources;
3867       }
3868     }
3869
3870     if(!align_pmem_buffers(pmem_fd, m_out_buf_size * m_out_buf_count,
3871       driver_context.output_buffer.alignment))
3872     {
3873       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3874       close(pmem_fd);
3875       return OMX_ErrorInsufficientResources;
3876     }
3877
3878     pmem_baseaddress = (unsigned char *)mmap(NULL,(m_out_buf_size * m_out_buf_count),
3879                        PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
3880     m_heap_ptr = new VideoHeap (pmem_fd,
3881                                    m_out_buf_size*m_out_buf_count,
3882                                    pmem_baseaddress);
3883
3884
3885     if (pmem_baseaddress == MAP_FAILED)
3886     {
3887       DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",m_out_buf_size);
3888       return OMX_ErrorInsufficientResources;
3889     }
3890     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
3891     // Alloc mem for platform specific info
3892     char *pPtr=NULL;
3893     pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
3894                                      nPMEMInfoSize,1);
3895     driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \
3896       calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count);
3897     driver_context.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
3898       calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count);
3899
3900     if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
3901        && driver_context.ptr_respbuffer)
3902     {
3903       driver_context.ptr_outputbuffer[0].mmaped_size =
3904         (m_out_buf_size * m_out_buf_count);
3905       bufHdr          =  m_out_mem_ptr;
3906       m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
3907       m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
3908                         (((char *) m_platform_list)  + nPlatformListSize);
3909       m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3910                         (((char *) m_platform_entry) + nPlatformEntrySize);
3911       pPlatformList   = m_platform_list;
3912       pPlatformEntry  = m_platform_entry;
3913       pPMEMInfo       = m_pmem_info;
3914
3915       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
3916
3917       // Settting the entire storage nicely
3918       DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
3919       DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
3920       for(i=0; i < m_out_buf_count ; i++)
3921       {
3922         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
3923         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
3924         // Set the values when we determine the right HxW param
3925         bufHdr->nAllocLen          = bytes;
3926         bufHdr->nFilledLen         = 0;
3927         bufHdr->pAppPrivate        = appData;
3928         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
3929         // Platform specific PMEM Information
3930         // Initialize the Platform Entry
3931         //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
3932         pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
3933         pPlatformEntry->entry      = pPMEMInfo;
3934         // Initialize the Platform List
3935         pPlatformList->nEntries    = 1;
3936         pPlatformList->entryList   = pPlatformEntry;
3937         // Keep pBuffer NULL till vdec is opened
3938         bufHdr->pBuffer            = NULL;
3939         bufHdr->nOffset            = 0;
3940
3941         pPMEMInfo->offset          =  m_out_buf_size*i;
3942         pPMEMInfo->pmem_fd = 0;
3943         bufHdr->pPlatformPrivate = pPlatformList;
3944
3945         driver_context.ptr_outputbuffer[i].pmem_fd = pmem_fd;
3946
3947         /*Create a mapping between buffers*/
3948         bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i];
3949         driver_context.ptr_respbuffer[i].client_data = (void *) \
3950                                             &driver_context.ptr_outputbuffer[i];
3951         driver_context.ptr_outputbuffer[i].offset = m_out_buf_size*i;
3952         driver_context.ptr_outputbuffer[i].bufferaddr = \
3953           pmem_baseaddress + (m_out_buf_size*i);
3954
3955         DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",\
3956                      pmem_fd,driver_context.ptr_outputbuffer[i].offset,driver_context.ptr_outputbuffer[i].bufferaddr);
3957         // Move the buffer and buffer header pointers
3958         bufHdr++;
3959         pPMEMInfo++;
3960         pPlatformEntry++;
3961         pPlatformList++;
3962       }
3963     }
3964     else
3965     {
3966       DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
3967                                         m_out_mem_ptr, pPtr);
3968       if(m_out_mem_ptr)
3969       {
3970         free(m_out_mem_ptr);
3971         m_out_mem_ptr = NULL;
3972       }
3973       if(pPtr)
3974       {
3975         free(pPtr);
3976         pPtr = NULL;
3977       }
3978       if(driver_context.ptr_outputbuffer)
3979       {
3980         free(driver_context.ptr_outputbuffer);
3981         driver_context.ptr_outputbuffer = NULL;
3982       }
3983       if(driver_context.ptr_respbuffer)
3984       {
3985         free(driver_context.ptr_respbuffer);
3986         driver_context.ptr_respbuffer = NULL;
3987       }
3988       eRet =  OMX_ErrorInsufficientResources;
3989     }
3990   }
3991
3992   for(i=0; i< m_out_buf_count; i++)
3993   {
3994     if(BITMASK_ABSENT(&m_out_bm_count,i))
3995     {
3996       DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
3997       break;
3998     }
3999   }
4000
4001   if (eRet == OMX_ErrorNone)
4002   {
4003     if(i < m_out_buf_count)
4004     {
4005       m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset;
4006       m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr.get ();
4007       driver_context.ptr_outputbuffer[i].buffer_len = m_out_buf_size;
4008       //driver_context.ptr_outputbuffer[i].mmaped_size = m_out_buf_size;
4009      if(!gate_output_buffers)
4010      {
4011      setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4012      memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i],
4013              sizeof (vdec_bufferpayload));
4014      ioctl_msg.inputparam  = &setbuffers;
4015      ioctl_msg.outputparam = NULL;
4016
4017      DEBUG_PRINT_LOW("\n Set the Output Buffer");
4018      if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4019           &ioctl_msg) < 0)
4020      {
4021        DEBUG_PRINT_ERROR("\n Set output buffer failed");
4022        return OMX_ErrorInsufficientResources;
4023      }
4024      }
4025
4026       // found an empty buffer at i
4027       *bufferHdr = (m_out_mem_ptr + i );
4028       (*bufferHdr)->pBuffer = driver_context.ptr_outputbuffer[i].bufferaddr;
4029       (*bufferHdr)->pAppPrivate = appData;
4030       BITMASK_SET(&m_out_bm_count,i);
4031     }
4032     else
4033     {
4034       DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4035       eRet = OMX_ErrorInsufficientResources;
4036     }
4037   }
4038
4039   return eRet;
4040 }
4041
4042
4043 // AllocateBuffer  -- API Call
4044 /* ======================================================================
4045 FUNCTION
4046   omx_vdec::AllocateBuffer
4047
4048 DESCRIPTION
4049   Returns zero if all the buffers released..
4050
4051 PARAMETERS
4052   None.
4053
4054 RETURN VALUE
4055   true/false
4056
4057 ========================================================================== */
4058 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
4059                                      OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4060                                      OMX_IN OMX_U32                        port,
4061                                      OMX_IN OMX_PTR                     appData,
4062                                      OMX_IN OMX_U32                       bytes)
4063 {
4064     unsigned i = 0;
4065     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4066
4067     DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
4068     if(m_state == OMX_StateInvalid)
4069     {
4070         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4071         return OMX_ErrorInvalidState;
4072     }
4073
4074     if(port == OMX_CORE_INPUT_PORT_INDEX)
4075     {
4076       if (arbitrary_bytes)
4077       {
4078           eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4079       }
4080       else
4081       {
4082         eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4083       }
4084     }
4085     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4086     {
4087       eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
4088     }
4089     else
4090     {
4091       DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4092       eRet = OMX_ErrorBadPortIndex;
4093     }
4094     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
4095     if(eRet == OMX_ErrorNone)
4096     {
4097         if(allocate_done()){
4098             if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4099             {
4100                 // Send the callback now
4101                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4102                 post_event(OMX_CommandStateSet,OMX_StateIdle,
4103                                    OMX_COMPONENT_GENERATE_EVENT);
4104             }
4105         }
4106         if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
4107         {
4108           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4109           {
4110              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4111              post_event(OMX_CommandPortEnable,
4112                         OMX_CORE_INPUT_PORT_INDEX,
4113                         OMX_COMPONENT_GENERATE_EVENT);
4114           }
4115         }
4116         if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
4117             {
4118           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4119           {
4120              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4121                 post_event(OMX_CommandPortEnable,
4122                            OMX_CORE_OUTPUT_PORT_INDEX,
4123                            OMX_COMPONENT_GENERATE_EVENT);
4124                 m_event_port_settings_sent = false;
4125             }
4126         }
4127     }
4128     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4129     return eRet;
4130 }
4131
4132 // Free Buffer - API call
4133 /* ======================================================================
4134 FUNCTION
4135   omx_vdec::FreeBuffer
4136
4137 DESCRIPTION
4138
4139 PARAMETERS
4140   None.
4141
4142 RETURN VALUE
4143   true/false
4144
4145 ========================================================================== */
4146 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
4147                                       OMX_IN OMX_U32                 port,
4148                                       OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4149 {
4150     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4151     unsigned int nPortIndex;
4152
4153     DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4154
4155     if(m_state == OMX_StateIdle &&
4156        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
4157     {
4158         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
4159     }
4160     else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
4161             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
4162     {
4163         DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
4164     }
4165     else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
4166     {
4167         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
4168         post_event(OMX_EventError,
4169                    OMX_ErrorPortUnpopulated,
4170                    OMX_COMPONENT_GENERATE_EVENT);
4171
4172         return eRet;
4173     }
4174     else if (m_state != OMX_StateInvalid)
4175     {
4176         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
4177         post_event(OMX_EventError,
4178                    OMX_ErrorPortUnpopulated,
4179                    OMX_COMPONENT_GENERATE_EVENT);
4180     }
4181
4182     if(port == OMX_CORE_INPUT_PORT_INDEX)
4183     {
4184       /*Check if arbitrary bytes*/
4185       if (!arbitrary_bytes)
4186       {
4187        // check if the buffer is valid
4188         nPortIndex = buffer - m_inp_mem_ptr;
4189       }
4190       else
4191       {
4192          nPortIndex = buffer - m_inp_heap_ptr;
4193       }
4194
4195         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
4196         if(nPortIndex < m_inp_buf_count)
4197         {
4198           // Clear the bit associated with it.
4199           BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
4200
4201           if (arbitrary_bytes)
4202           {
4203             if (m_inp_heap_ptr[nPortIndex].pBuffer)
4204             {
4205               BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
4206               DEBUG_PRINT_LOW("\n Free Heap Buffer index %d",nPortIndex);
4207               free (m_inp_heap_ptr[nPortIndex].pBuffer);
4208               m_inp_heap_ptr[nPortIndex].pBuffer = NULL;
4209             }
4210             if (m_phdr_pmem_ptr[nPortIndex])
4211             {
4212               DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
4213               free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
4214             }
4215           }
4216           else
4217           {
4218             free_input_buffer(buffer);
4219           }
4220
4221           m_inp_bPopulated = OMX_FALSE;
4222
4223           /*Free the Buffer Header*/
4224           if (release_input_done())
4225           {
4226             DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
4227             input_use_buffer = false;
4228             if (arbitrary_bytes)
4229             {
4230               if (m_frame_parser.mutils)
4231               {
4232                 DEBUG_PRINT_LOW("\n Free utils parser");
4233                 delete (m_frame_parser.mutils);
4234                 m_frame_parser.mutils = NULL;
4235               }
4236
4237               if (m_inp_heap_ptr)
4238               {
4239                 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
4240                 free (m_inp_heap_ptr);
4241                 m_inp_heap_ptr = NULL;
4242               }
4243
4244               if (m_phdr_pmem_ptr)
4245               {
4246                 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
4247                 free (m_phdr_pmem_ptr);
4248                 m_phdr_pmem_ptr = NULL;
4249               }
4250             }
4251             if (m_inp_mem_ptr)
4252             {
4253               DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
4254               free (m_inp_mem_ptr);
4255               m_inp_mem_ptr = NULL;
4256             }
4257
4258             if (driver_context.ptr_inputbuffer)
4259             {
4260               DEBUG_PRINT_LOW("\n Free Driver Context pointer");
4261               free (driver_context.ptr_inputbuffer);
4262               driver_context.ptr_inputbuffer = NULL;
4263             }
4264           }
4265
4266         }
4267         else
4268         {
4269             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
4270             eRet = OMX_ErrorBadPortIndex;
4271         }
4272
4273         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
4274            && release_input_done())
4275         {
4276             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
4277             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
4278             post_event(OMX_CommandPortDisable,
4279                        OMX_CORE_INPUT_PORT_INDEX,
4280                        OMX_COMPONENT_GENERATE_EVENT);
4281         }
4282     }
4283     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4284     {
4285         // check if the buffer is valid
4286         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
4287         if(nPortIndex < m_out_buf_count)
4288         {
4289             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
4290             // Clear the bit associated with it.
4291             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
4292             m_out_bPopulated = OMX_FALSE;
4293             free_output_buffer (buffer);
4294
4295             if (release_output_done())
4296             {
4297               DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
4298               output_use_buffer = false;
4299               if (m_out_mem_ptr)
4300               {
4301                 free (m_out_mem_ptr);
4302                 m_out_mem_ptr = NULL;
4303               }
4304               if (driver_context.ptr_respbuffer)
4305               {
4306                 free (driver_context.ptr_respbuffer);
4307                 driver_context.ptr_respbuffer = NULL;
4308               }
4309               if (driver_context.ptr_outputbuffer)
4310               {
4311                 free (driver_context.ptr_outputbuffer);
4312                 driver_context.ptr_outputbuffer = NULL;
4313               }
4314             }
4315         }
4316         else
4317         {
4318             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
4319             eRet = OMX_ErrorBadPortIndex;
4320         }
4321         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
4322            && release_output_done() )
4323         {
4324             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
4325
4326                 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
4327                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
4328                 post_event(OMX_CommandPortDisable,
4329                            OMX_CORE_OUTPUT_PORT_INDEX,
4330                            OMX_COMPONENT_GENERATE_EVENT);
4331         }
4332     }
4333     else
4334     {
4335         eRet = OMX_ErrorBadPortIndex;
4336     }
4337     if((eRet == OMX_ErrorNone) &&
4338        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
4339     {
4340         if(release_done())
4341         {
4342             // Send the callback now
4343             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
4344             post_event(OMX_CommandStateSet, OMX_StateLoaded,
4345                                       OMX_COMPONENT_GENERATE_EVENT);
4346         }
4347     }
4348     return eRet;
4349 }
4350
4351
4352 /* ======================================================================
4353 FUNCTION
4354   omx_vdec::EmptyThisBuffer
4355
4356 DESCRIPTION
4357   This routine is used to push the encoded video frames to
4358   the video decoder.
4359
4360 PARAMETERS
4361   None.
4362
4363 RETURN VALUE
4364   OMX Error None if everything went successful.
4365
4366 ========================================================================== */
4367 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
4368                                            OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4369 {
4370   OMX_ERRORTYPE ret1 = OMX_ErrorNone;
4371   unsigned int nBufferIndex = m_inp_buf_count;
4372
4373   if(m_state == OMX_StateInvalid)
4374   {
4375       DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
4376       return OMX_ErrorInvalidState;
4377   }
4378
4379   if (buffer == NULL)
4380   {
4381     DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
4382     return OMX_ErrorBadParameter;
4383   }
4384
4385   if (arbitrary_bytes)
4386   {
4387     nBufferIndex = buffer - m_inp_heap_ptr;
4388   }
4389   else
4390   {
4391     nBufferIndex = buffer - m_inp_mem_ptr;
4392   }
4393
4394   if (nBufferIndex > m_inp_buf_count )
4395   {
4396     DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
4397     return OMX_ErrorBadParameter;
4398   }
4399
4400   DEBUG_PRINT_LOW("\n ETB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
4401   if (arbitrary_bytes)
4402   {
4403     post_event ((unsigned)hComp,(unsigned)buffer,
4404                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
4405   }
4406   else
4407   {
4408     post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
4409   }
4410   return OMX_ErrorNone;
4411 }
4412
4413 /* ======================================================================
4414 FUNCTION
4415   omx_vdec::empty_this_buffer_proxy
4416
4417 DESCRIPTION
4418   This routine is used to push the encoded video frames to
4419   the video decoder.
4420
4421 PARAMETERS
4422   None.
4423
4424 RETURN VALUE
4425   OMX Error None if everything went successful.
4426
4427 ========================================================================== */
4428 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
4429                                                  OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4430 {
4431   int push_cnt = 0,i=0;
4432   unsigned nPortIndex = 0;
4433   OMX_ERRORTYPE ret = OMX_ErrorNone;
4434   struct vdec_input_frameinfo frameinfo;
4435   struct vdec_bufferpayload *temp_buffer;
4436   struct vdec_ioctl_msg ioctl_msg;
4437   struct vdec_seqheader seq_header;
4438   bool port_setting_changed = true;
4439
4440   /*Should we generate a Aync error event*/
4441   if (buffer == NULL || buffer->pInputPortPrivate == NULL)
4442   {
4443     DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
4444     return OMX_ErrorBadParameter;
4445   }
4446
4447   nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
4448
4449   if (nPortIndex > m_inp_buf_count)
4450   {
4451     DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
4452         nPortIndex);
4453     return OMX_ErrorBadParameter;
4454   }
4455
4456   pending_input_buffers++;
4457
4458   if( input_flush_progress == true || m_ineos_reached == 1)
4459   {
4460     DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
4461     post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
4462                      OMX_COMPONENT_GENERATE_EBD);
4463     return OMX_ErrorNone;
4464   }
4465
4466   if(m_event_port_settings_sent && !arbitrary_bytes)
4467   {
4468     post_event((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
4469     return OMX_ErrorNone;
4470   }
4471
4472   temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
4473
4474   if ((temp_buffer -  driver_context.ptr_inputbuffer) > m_inp_buf_count)
4475   {
4476     return OMX_ErrorBadParameter;
4477   }
4478
4479   DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
4480   /*for use buffer we need to memcpy the data*/
4481   temp_buffer->buffer_len = buffer->nFilledLen;
4482
4483   if (input_use_buffer)
4484   {
4485     if (buffer->nFilledLen <= temp_buffer->buffer_len)
4486     {
4487       memcpy (temp_buffer->bufferaddr,(buffer->pBuffer + buffer->nOffset),
4488               buffer->nFilledLen);
4489     }
4490     else
4491     {
4492       return OMX_ErrorBadParameter;
4493     }
4494
4495   }
4496
4497   if (!arbitrary_bytes && first_frame < 2  && codec_type_parse == CODEC_TYPE_MPEG4)
4498   {
4499
4500     if (first_frame == 0)
4501     {
4502        first_buffer = (unsigned char *)malloc (m_inp_buf_size);
4503        DEBUG_PRINT_LOW("\n Copied the first buffer data size %d ",
4504                     temp_buffer->buffer_len);
4505        first_frame = 1;
4506        memcpy (first_buffer,temp_buffer->bufferaddr,temp_buffer->buffer_len);
4507        first_frame_size = buffer->nFilledLen;
4508        buffer->nFilledLen = 0;
4509        post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
4510                    OMX_COMPONENT_GENERATE_EBD);
4511        return OMX_ErrorNone;
4512     }
4513     else if (first_frame == 1)
4514     {
4515        first_frame = 2;
4516        DEBUG_PRINT_LOW("\n Second buffer copy the header size %d frame size %d",
4517                     first_frame_size,temp_buffer->buffer_len);
4518        memcpy (&first_buffer [first_frame_size],temp_buffer->bufferaddr,
4519                temp_buffer->buffer_len);
4520        first_frame_size += temp_buffer->buffer_len;
4521        memcpy (temp_buffer->bufferaddr,first_buffer,first_frame_size);
4522        temp_buffer->buffer_len = first_frame_size;
4523        free (first_buffer);
4524     }
4525   }
4526
4527   frameinfo.bufferaddr = temp_buffer->bufferaddr;
4528   frameinfo.client_data = (void *) buffer;
4529   frameinfo.datalen = temp_buffer->buffer_len;
4530   frameinfo.flags = 0;
4531   frameinfo.offset = buffer->nOffset;
4532   frameinfo.pmem_fd = temp_buffer->pmem_fd;
4533   frameinfo.pmem_offset = temp_buffer->offset;
4534   frameinfo.timestamp = buffer->nTimeStamp;
4535
4536 #if BITSTREAM_LOG
4537   int bytes_written;
4538   bytes_written = fwrite((const char *)temp_buffer->bufferaddr,
4539                           temp_buffer->buffer_len,1,outputBufferFile1);
4540
4541 #endif
4542
4543   if(!set_seq_header_done)
4544   {
4545     set_seq_header_done = true;
4546     DEBUG_PRINT_HIGH("\n Set Sequence Header");
4547     seq_header.ptr_seqheader = frameinfo.bufferaddr;
4548     seq_header.seq_header_len = frameinfo.datalen;
4549     seq_header.pmem_fd = frameinfo.pmem_fd;
4550     seq_header.pmem_offset = frameinfo.pmem_offset;
4551     ioctl_msg.inputparam = &seq_header;
4552     ioctl_msg.outputparam = NULL;
4553     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_SET_SEQUENCE_HEADER,
4554               &ioctl_msg) < 0)
4555     {
4556       DEBUG_PRINT_ERROR("\n Set Sequence Header Failed");
4557       /*Generate an async error and move to invalid state*/
4558       return OMX_ErrorBadParameter;
4559     }
4560     if(omx_vdec_check_port_settings (&port_setting_changed) != OMX_ErrorNone)
4561     {
4562       DEBUG_PRINT_ERROR("\n Check port setting failed");
4563       return OMX_ErrorBadParameter;
4564     }
4565
4566     if(port_setting_changed)
4567     {
4568       DEBUG_PRINT_HIGH("\n Port settings changed");
4569       m_event_port_settings_sent = true;
4570       m_cb.EventHandler(&m_cmp, m_app_data,OMX_EventPortSettingsChanged,
4571                           OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
4572       DEBUG_PRINT_HIGH("\n EventHandler for Port Setting changed done");
4573       return OMX_ErrorNone;
4574     }
4575     else
4576     {
4577       if(!register_output_buffers())
4578       {
4579         DEBUG_PRINT_ERROR("\n register output failed");
4580         return OMX_ErrorBadParameter;
4581       }
4582       DEBUG_PRINT_HIGH("\n Port settings Not changed");
4583     }
4584   }
4585
4586   if (temp_buffer->buffer_len == 0 || (buffer->nFlags & 0x01))
4587   {
4588     DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
4589     frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
4590     m_ineos_reached = 1;
4591   }
4592
4593   sent_first_frame = true;
4594   DEBUG_PRINT_LOW("\n Decode Input Frame Size %d",frameinfo.datalen);
4595   ioctl_msg.inputparam = &frameinfo;
4596   ioctl_msg.outputparam = NULL;
4597
4598   if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
4599             &ioctl_msg) < 0)
4600   {
4601     /*Generate an async error and move to invalid state*/
4602     return OMX_ErrorBadParameter;
4603   }
4604
4605   return ret;
4606 }
4607
4608 /* ======================================================================
4609 FUNCTION
4610   omx_vdec::FillThisBuffer
4611
4612 DESCRIPTION
4613   IL client uses this method to release the frame buffer
4614   after displaying them.
4615
4616 PARAMETERS
4617   None.
4618
4619 RETURN VALUE
4620   true/false
4621
4622 ========================================================================== */
4623 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
4624                                           OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4625 {
4626
4627   if(m_state == OMX_StateInvalid)
4628   {
4629       DEBUG_PRINT_ERROR("FTB in Invalid State\n");
4630       return OMX_ErrorInvalidState;
4631   }
4632
4633   if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_size))
4634   {
4635     return OMX_ErrorBadParameter;
4636   }
4637
4638   DEBUG_PRINT_LOW("\n FTB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
4639   post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
4640   return OMX_ErrorNone;
4641 }
4642 /* ======================================================================
4643 FUNCTION
4644   omx_vdec::fill_this_buffer_proxy
4645
4646 DESCRIPTION
4647   IL client uses this method to release the frame buffer
4648   after displaying them.
4649
4650 PARAMETERS
4651   None.
4652
4653 RETURN VALUE
4654   true/false
4655
4656 ========================================================================== */
4657 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
4658                          OMX_IN OMX_HANDLETYPE        hComp,
4659                          OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
4660 {
4661   OMX_ERRORTYPE nRet = OMX_ErrorNone;
4662   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4663   OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
4664   struct vdec_fillbuffer_cmd fillbuffer;
4665   struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
4666   struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
4667
4668
4669   if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count) )
4670   {
4671     return OMX_ErrorBadParameter;
4672   }
4673
4674   DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
4675       bufferAdd, bufferAdd->pBuffer);
4676   /*Return back the output buffer to client*/
4677   if( (m_event_port_settings_sent == true) || (m_out_bEnabled != OMX_TRUE)
4678       || output_flush_progress == true || m_outeos_reached == 1)
4679   {
4680     DEBUG_PRINT_LOW("\n Output Buffers return in EOS condition");
4681     buffer->nFlags |= m_outeos_reached;
4682     m_cb.FillBufferDone (hComp,m_app_data,buffer);
4683     return OMX_ErrorNone;
4684   }
4685   pending_output_buffers++;
4686   ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
4687   if (ptr_respbuffer)
4688   {
4689     ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
4690   }
4691
4692   if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
4693   {
4694     return OMX_ErrorBadParameter;
4695   }
4696
4697   memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
4698           sizeof(struct vdec_bufferpayload));
4699   fillbuffer.client_data = bufferAdd;
4700
4701   ioctl_msg.inputparam = &fillbuffer;
4702   ioctl_msg.outputparam = NULL;
4703   if (ioctl (driver_context.video_driver_fd,
4704          VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
4705   {
4706     DEBUG_PRINT_ERROR("\n Decoder frame failed");
4707     m_cb.FillBufferDone (hComp,m_app_data,buffer);
4708     return OMX_ErrorBadParameter;
4709   }
4710
4711   if(gate_input_buffers)
4712   {
4713     gate_input_buffers = false;
4714     if(pdest_frame)
4715     {
4716       /*Push the frame to the Decoder*/
4717       if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
4718       {
4719         return OMX_ErrorBadParameter;
4720       }
4721       frame_count++;
4722       pdest_frame = NULL;
4723     }
4724   }
4725   return OMX_ErrorNone;
4726 }
4727
4728 /* ======================================================================
4729 FUNCTION
4730   omx_vdec::SetCallbacks
4731
4732 DESCRIPTION
4733   Set the callbacks.
4734
4735 PARAMETERS
4736   None.
4737
4738 RETURN VALUE
4739   OMX Error None if everything successful.
4740
4741 ========================================================================== */
4742 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
4743                                            OMX_IN OMX_CALLBACKTYPE* callbacks,
4744                                            OMX_IN OMX_PTR             appData)
4745 {
4746
4747   m_cb       = *callbacks;
4748   DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
4749                m_cb.EventHandler,m_cb.FillBufferDone);
4750   m_app_data =    appData;
4751   return OMX_ErrorNotImplemented;
4752 }
4753
4754 /* ======================================================================
4755 FUNCTION
4756   omx_vdec::ComponentDeInit
4757
4758 DESCRIPTION
4759   Destroys the component and release memory allocated to the heap.
4760
4761 PARAMETERS
4762   <TBD>.
4763
4764 RETURN VALUE
4765   OMX Error None if everything successful.
4766
4767 ========================================================================== */
4768 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
4769 {
4770     int i = 0;
4771     if (OMX_StateLoaded != m_state)
4772     {
4773         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
4774                           m_state);
4775         DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
4776     }
4777     else
4778     {
4779       DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
4780     }
4781
4782     /*Check if the output buffers have to be cleaned up*/
4783     if(m_out_mem_ptr)
4784     {
4785         DEBUG_PRINT_LOW("Freeing the Output Memory\n");
4786         for (i=0; i<m_out_buf_count; i++ )
4787         {
4788           free_output_buffer (&m_out_mem_ptr[i]);
4789         }
4790         if (driver_context.ptr_outputbuffer)
4791         {
4792           free (driver_context.ptr_outputbuffer);
4793           driver_context.ptr_outputbuffer = NULL;
4794         }
4795
4796         if (driver_context.ptr_respbuffer)
4797         {
4798           free (driver_context.ptr_respbuffer);
4799           driver_context.ptr_respbuffer = NULL;
4800         }
4801         free(m_out_mem_ptr);
4802         m_out_mem_ptr = NULL;
4803     }
4804
4805     /*Check if the input buffers have to be cleaned up*/
4806     if(m_inp_mem_ptr)
4807     {
4808         DEBUG_PRINT_LOW("Freeing the Input Memory\n");
4809         for (i=0; i<m_inp_buf_count; i++ )
4810         {
4811           free_input_buffer (&m_inp_mem_ptr[i]);
4812         }
4813
4814         if (driver_context.ptr_inputbuffer)
4815         {
4816           free (driver_context.ptr_inputbuffer);
4817           driver_context.ptr_inputbuffer = NULL;
4818         }
4819
4820         free(m_inp_mem_ptr);
4821         m_inp_mem_ptr = NULL;
4822     }
4823
4824     if(h264_scratch.pBuffer)
4825     {
4826       free(h264_scratch.pBuffer);
4827       h264_scratch.pBuffer = NULL;
4828     }
4829
4830     if(m_platform_list)
4831     {
4832         free(m_platform_list);
4833         m_platform_list = NULL;
4834     }
4835     if(m_vendor_config.pData)
4836     {
4837         free(m_vendor_config.pData);
4838         m_vendor_config.pData = NULL;
4839     }
4840
4841     // Reset counters in mesg queues
4842     m_ftb_q.m_size=0;
4843     m_cmd_q.m_size=0;
4844     m_etb_q.m_size=0;
4845     m_ftb_q.m_read = m_ftb_q.m_write =0;
4846     m_cmd_q.m_read = m_cmd_q.m_write =0;
4847     m_etb_q.m_read = m_etb_q.m_write =0;
4848
4849     DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
4850     (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
4851         NULL);
4852     DEBUG_PRINT_HIGH("\n Close the driver instance");
4853     close(driver_context.video_driver_fd);
4854
4855 #if BITSTREAM_LOG
4856     fclose (outputBufferFile1);
4857 #endif
4858 #ifdef _ANDROID_
4859     //for (i=0; i<m_out_buf_count; i++ )
4860     {
4861        // Clear the strong reference
4862       m_heap_ptr.clear();
4863     }
4864 #endif // _ANDROID_
4865   DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
4866   return OMX_ErrorNone;
4867 }
4868
4869 /* ======================================================================
4870 FUNCTION
4871   omx_vdec::UseEGLImage
4872
4873 DESCRIPTION
4874   OMX Use EGL Image method implementation <TBD>.
4875
4876 PARAMETERS
4877   <TBD>.
4878
4879 RETURN VALUE
4880   Not Implemented error.
4881
4882 ========================================================================== */
4883 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
4884                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4885                                           OMX_IN OMX_U32                        port,
4886                                           OMX_IN OMX_PTR                     appData,
4887                                           OMX_IN void*                      eglImage)
4888 {
4889     DEBUG_PRINT_ERROR("Error : use_EGL_image:  Not Implemented \n");
4890     return OMX_ErrorNotImplemented;
4891 }
4892
4893 /* ======================================================================
4894 FUNCTION
4895   omx_vdec::ComponentRoleEnum
4896
4897 DESCRIPTION
4898   OMX Component Role Enum method implementation.
4899
4900 PARAMETERS
4901   <TBD>.
4902
4903 RETURN VALUE
4904   OMX Error None if everything is successful.
4905 ========================================================================== */
4906 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
4907                                                 OMX_OUT OMX_U8*        role,
4908                                                 OMX_IN OMX_U32        index)
4909 {
4910   OMX_ERRORTYPE eRet = OMX_ErrorNone;
4911
4912   if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
4913   {
4914     if((0 == index) && role)
4915     {
4916       strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
4917       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4918     }
4919     else
4920     {
4921       eRet = OMX_ErrorNoMore;
4922     }
4923   }
4924   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
4925   {
4926     if((0 == index) && role)
4927     {
4928       strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
4929       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4930     }
4931     else
4932     {
4933       DEBUG_PRINT_LOW("\n No more roles \n");
4934       eRet = OMX_ErrorNoMore;
4935     }
4936   }
4937   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
4938   {
4939     if((0 == index) && role)
4940     {
4941       strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
4942       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4943     }
4944     else
4945     {
4946       DEBUG_PRINT_LOW("\n No more roles \n");
4947       eRet = OMX_ErrorNoMore;
4948     }
4949   }
4950   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
4951   {
4952     if((0 == index) && role)
4953     {
4954       strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
4955       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4956     }
4957     else
4958     {
4959       DEBUG_PRINT_LOW("\n No more roles \n");
4960       eRet = OMX_ErrorNoMore;
4961     }
4962   }
4963   else
4964   {
4965     DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
4966     eRet = OMX_ErrorInvalidComponentName;
4967   }
4968   return eRet;
4969 }
4970
4971
4972
4973
4974 /* ======================================================================
4975 FUNCTION
4976   omx_vdec::AllocateDone
4977
4978 DESCRIPTION
4979   Checks if entire buffer pool is allocated by IL Client or not.
4980   Need this to move to IDLE state.
4981
4982 PARAMETERS
4983   None.
4984
4985 RETURN VALUE
4986   true/false.
4987
4988 ========================================================================== */
4989 bool omx_vdec::allocate_done(void)
4990 {
4991   bool bRet = false;
4992   bool bRet_In = false;
4993   bool bRet_Out = false;
4994
4995   bRet_In = allocate_input_done();
4996   bRet_Out = allocate_output_done();
4997
4998   if(bRet_In && bRet_Out)
4999   {
5000       bRet = true;
5001   }
5002
5003   return bRet;
5004 }
5005 /* ======================================================================
5006 FUNCTION
5007   omx_vdec::AllocateInputDone
5008
5009 DESCRIPTION
5010   Checks if I/P buffer pool is allocated by IL Client or not.
5011
5012 PARAMETERS
5013   None.
5014
5015 RETURN VALUE
5016   true/false.
5017
5018 ========================================================================== */
5019 bool omx_vdec::allocate_input_done(void)
5020 {
5021   bool bRet = false;
5022   unsigned i=0;
5023
5024   if (m_inp_mem_ptr == NULL)
5025   {
5026       return bRet;
5027   }
5028   if(m_inp_mem_ptr )
5029   {
5030     for(;i<m_inp_buf_count;i++)
5031     {
5032       if(BITMASK_ABSENT(&m_inp_bm_count,i))
5033       {
5034         break;
5035       }
5036     }
5037   }
5038   if(i==m_inp_buf_count)
5039   {
5040     bRet = true;
5041     DEBUG_PRINT_HIGH("\n Allocate done for all i/p buffers");
5042   }
5043   if(i==m_inp_buf_count && m_inp_bEnabled)
5044   {
5045      m_inp_bPopulated = OMX_TRUE;
5046   }
5047   return bRet;
5048 }
5049 /* ======================================================================
5050 FUNCTION
5051   omx_vdec::AllocateOutputDone
5052
5053 DESCRIPTION
5054   Checks if entire O/P buffer pool is allocated by IL Client or not.
5055
5056 PARAMETERS
5057   None.
5058
5059 RETURN VALUE
5060   true/false.
5061
5062 ========================================================================== */
5063 bool omx_vdec::allocate_output_done(void)
5064 {
5065   bool bRet = false;
5066   unsigned j=0;
5067
5068   if (m_out_mem_ptr == NULL)
5069   {
5070       return bRet;
5071   }
5072
5073   if(m_out_mem_ptr )
5074   {
5075     for(;j<m_out_buf_count;j++)
5076     {
5077       if(BITMASK_ABSENT(&m_out_bm_count,j))
5078       {
5079         break;
5080       }
5081     }
5082   }
5083
5084   if(j==m_out_buf_count)
5085   {
5086     bRet = true;
5087     DEBUG_PRINT_HIGH("\n Allocate done for all o/p buffers");
5088   }
5089
5090   if(j==m_out_buf_count && m_out_bEnabled)
5091   {
5092      m_out_bPopulated = OMX_TRUE;
5093   }
5094   return bRet;
5095 }
5096
5097 /* ======================================================================
5098 FUNCTION
5099   omx_vdec::ReleaseDone
5100
5101 DESCRIPTION
5102   Checks if IL client has released all the buffers.
5103
5104 PARAMETERS
5105   None.
5106
5107 RETURN VALUE
5108   true/false
5109
5110 ========================================================================== */
5111 bool omx_vdec::release_done(void)
5112 {
5113   bool bRet = false;
5114
5115   if(release_input_done())
5116   {
5117     if(release_output_done())
5118     {
5119         bRet = true;
5120     }
5121   }
5122   return bRet;
5123 }
5124
5125
5126 /* ======================================================================
5127 FUNCTION
5128   omx_vdec::ReleaseOutputDone
5129
5130 DESCRIPTION
5131   Checks if IL client has released all the buffers.
5132
5133 PARAMETERS
5134   None.
5135
5136 RETURN VALUE
5137   true/false
5138
5139 ========================================================================== */
5140 bool omx_vdec::release_output_done(void)
5141 {
5142   bool bRet = false;
5143   unsigned i=0,j=0;
5144
5145   DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
5146   if(m_out_mem_ptr)
5147   {
5148       for(;j<m_out_buf_count;j++)
5149       {
5150         if(BITMASK_PRESENT(&m_out_bm_count,j))
5151         {
5152           break;
5153         }
5154       }
5155     if(j==m_out_buf_count)
5156     {
5157       m_out_bm_count = 0;
5158       bRet = true;
5159     }
5160   }
5161   else
5162   {
5163     m_out_bm_count = 0;
5164     bRet = true;
5165   }
5166   return bRet;
5167 }
5168 /* ======================================================================
5169 FUNCTION
5170   omx_vdec::ReleaseInputDone
5171
5172 DESCRIPTION
5173   Checks if IL client has released all the buffers.
5174
5175 PARAMETERS
5176   None.
5177
5178 RETURN VALUE
5179   true/false
5180
5181 ========================================================================== */
5182 bool omx_vdec::release_input_done(void)
5183 {
5184   bool bRet = false;
5185   unsigned i=0,j=0;
5186
5187   DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
5188   if(m_inp_mem_ptr)
5189   {
5190       for(;j<m_inp_buf_count;j++)
5191       {
5192         if( BITMASK_PRESENT(&m_inp_bm_count,j))
5193         {
5194           break;
5195         }
5196       }
5197     if(j==m_inp_buf_count)
5198     {
5199       bRet = true;
5200     }
5201   }
5202   else
5203   {
5204     bRet = true;
5205   }
5206   return bRet;
5207 }
5208
5209 /* ======================================================================
5210 FUNCTION
5211   omx_vdec::omx_vdec_check_port_settings
5212
5213 DESCRIPTION
5214   Parse meta data to check the height and width param
5215   Check the level and profile
5216
5217 PARAMETERS
5218   None.
5219
5220 RETURN VALUE
5221   OMX_ErrorNone, if profile and level are supported
5222   OMX_ErrorUnsupportedSetting, if profile and level are not supported
5223 ========================================================================== */
5224 OMX_ERRORTYPE omx_vdec::omx_vdec_check_port_settings(bool *port_setting_changed)
5225 {
5226     struct vdec_ioctl_msg ioctl_msg;
5227     unsigned int alignment = 0,buffer_size = 0;
5228     OMX_ERRORTYPE eRet = OMX_ErrorNone;
5229
5230     *port_setting_changed = false;
5231     ioctl_msg.inputparam = NULL;
5232     ioctl_msg.outputparam = &driver_context.video_resoultion;
5233     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_PICRES,&ioctl_msg))
5234     {
5235       DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_PICRES in port_setting");
5236       return OMX_ErrorHardware;
5237     }
5238
5239     ioctl_msg.inputparam = NULL;
5240     ioctl_msg.outputparam = &driver_context.output_buffer;
5241     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
5242                &ioctl_msg))
5243     {
5244       DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
5245       return OMX_ErrorHardware;
5246     }
5247     DEBUG_PRINT_HIGH("\n Queried Dimensions H=%d W=%d Act H=%d W=%d",
5248                        driver_context.video_resoultion.frame_height,
5249                        driver_context.video_resoultion.frame_width,
5250                        m_height,m_width);
5251     DEBUG_PRINT_HIGH("\n Queried Buffer ACnt=%d BSiz=%d Act Acnt=%d Bsiz=%d",
5252                        driver_context.output_buffer.actualcount,
5253                        driver_context.output_buffer.buffer_size,
5254                        m_out_buf_count,m_out_buf_size);
5255
5256     DEBUG_PRINT_HIGH("\n Queried stride cuur Str=%d cur scan=%d Act str=%d act scan =%d",
5257                        driver_context.video_resoultion.stride,driver_context.video_resoultion.scan_lines,
5258                        stride,scan_lines);
5259
5260
5261     if(driver_context.video_resoultion.frame_height != m_height ||
5262        driver_context.video_resoultion.frame_width != m_width ||
5263        driver_context.video_resoultion.scan_lines != scan_lines ||
5264        driver_context.video_resoultion.stride != stride ||
5265        driver_context.output_buffer.actualcount != m_out_buf_count ||
5266        driver_context.output_buffer.buffer_size > m_out_buf_size)
5267     {
5268       *port_setting_changed = true;
5269       ioctl_msg.inputparam = &driver_context.output_buffer;
5270       ioctl_msg.outputparam = NULL;
5271
5272       if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
5273                  &ioctl_msg))
5274       {
5275          DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
5276          return OMX_ErrorHardware;
5277       }
5278       m_out_buf_size_recon = driver_context.output_buffer.buffer_size;
5279       m_out_buf_count_recon = driver_context.output_buffer.actualcount;
5280       m_out_buf_count_min_recon = driver_context.output_buffer.mincount;
5281
5282       alignment = driver_context.output_buffer.alignment;
5283       buffer_size = driver_context.output_buffer.buffer_size;
5284       m_out_buf_size_recon =
5285         ((buffer_size + alignment - 1) & (~(alignment - 1)));
5286       m_crop_dy = m_height      = driver_context.video_resoultion.frame_height;
5287       m_crop_dx = m_width       = driver_context.video_resoultion.frame_width;
5288       scan_lines = driver_context.video_resoultion.scan_lines;
5289       stride = driver_context.video_resoultion.stride;
5290       m_port_height             = m_height;
5291       m_port_width              = m_width;
5292     }
5293
5294     return eRet;
5295 }
5296
5297
5298 /* ======================================================================
5299 FUNCTION
5300   omx_vdec::omx_vdec_validate_port_param
5301
5302 DESCRIPTION
5303   Get the PMEM area from video decoder
5304
5305 PARAMETERS
5306   None.
5307
5308 RETURN VALUE
5309   None
5310 ========================================================================== */
5311 OMX_ERRORTYPE omx_vdec::omx_vdec_validate_port_param(int height, int width)
5312 {
5313     OMX_ERRORTYPE ret = OMX_ErrorNone;
5314     long hxw = height*width;
5315     long lmt_hxw = 0;
5316
5317     return ret;
5318 }
5319
5320 static FILE * outputBufferFile = NULL;
5321
5322 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
5323                                OMX_BUFFERHEADERTYPE * buffer)
5324 {
5325   OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
5326
5327   if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count))
5328   {
5329      return OMX_ErrorBadParameter;
5330   }
5331
5332   DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
5333       buffer, buffer->pBuffer);
5334   pending_output_buffers --;
5335
5336   if (buffer->nFlags & 0x01)
5337   {
5338     DEBUG_PRINT_LOW("\n Output EOS has been reached");
5339
5340     m_outeos_reached = 0;
5341     m_ineos_reached = 0;
5342     h264_scratch.nFilledLen = 0;
5343     nal_count = 0;
5344     look_ahead_nal = false;
5345     frame_count = 0;
5346
5347     if (m_frame_parser.mutils)
5348     {
5349       m_frame_parser.mutils->initialize_frame_checking_environment();
5350     }
5351     if (psource_frame)
5352     {
5353       m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
5354       psource_frame = NULL;
5355     }
5356
5357     if (pdest_frame)
5358     {
5359       pdest_frame->nFilledLen = 0;
5360       m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
5361       pdest_frame = NULL;
5362     }
5363     m_frame_parser.flush();
5364   }
5365
5366   DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
5367
5368   if (outputBufferFile == NULL)
5369   {
5370     outputBufferFile = fopen ("/data/output.yuv","wb");
5371   }
5372   if (outputBufferFile)
5373   {
5374     /*fwrite (buffer->pBuffer,1,buffer->nFilledLen,
5375                   outputBufferFile); */
5376   }
5377   /* For use buffer we need to copy the data */
5378   if (m_cb.FillBufferDone)
5379   {
5380     pPMEMInfo  = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5381                    ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
5382                       buffer->pPlatformPrivate)->entryList->entry;
5383     DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
5384     m_cb.FillBufferDone (hComp,m_app_data,buffer);
5385     DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
5386   }
5387   else
5388   {
5389     return OMX_ErrorBadParameter;
5390   }
5391
5392   return OMX_ErrorNone;
5393 }
5394
5395 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
5396                                           OMX_BUFFERHEADERTYPE* buffer)
5397 {
5398
5399     if (buffer == NULL || ((buffer - m_inp_mem_ptr) > m_inp_buf_count))
5400     {
5401        return OMX_ErrorBadParameter;
5402     }
5403
5404     DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
5405         buffer, buffer->pBuffer);
5406     pending_input_buffers--;
5407
5408     if (arbitrary_bytes)
5409     {
5410       if (pdest_frame == NULL && input_flush_progress == false)
5411       {
5412         DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
5413         pdest_frame = buffer;
5414         buffer->nFilledLen = 0;
5415         push_input_buffer (hComp);
5416       }
5417       else
5418       {
5419         DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
5420         buffer->nFilledLen = 0;
5421         if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
5422         {
5423           DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
5424         }
5425       }
5426     }
5427     else if(m_cb.EmptyBufferDone)
5428     {
5429         buffer->nFilledLen = 0;
5430         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
5431     }
5432     return OMX_ErrorNone;
5433 }
5434
5435
5436 int omx_vdec::async_message_process (void *context, void* message)
5437 {
5438   omx_vdec* omx = NULL;
5439   struct vdec_msginfo *vdec_msg = NULL;
5440   OMX_BUFFERHEADERTYPE* omxhdr = NULL;
5441   struct vdec_output_frameinfo *output_respbuf = NULL;
5442
5443   if (context == NULL || message == NULL)
5444   {
5445     DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
5446     return -1;
5447   }
5448   vdec_msg = (struct vdec_msginfo *)message;
5449
5450   omx = reinterpret_cast<omx_vdec*>(context);
5451   switch (vdec_msg->msgcode)
5452   {
5453
5454   case VDEC_MSG_EVT_HW_ERROR:
5455     omx->post_event (NULL,vdec_msg->status_code,\
5456                      OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
5457   break;
5458
5459   case VDEC_MSG_RESP_START_DONE:
5460     omx->post_event (NULL,vdec_msg->status_code,\
5461                      OMX_COMPONENT_GENERATE_START_DONE);
5462   break;
5463
5464   case VDEC_MSG_RESP_STOP_DONE:
5465     omx->post_event (NULL,vdec_msg->status_code,\
5466                      OMX_COMPONENT_GENERATE_STOP_DONE);
5467   break;
5468
5469   case VDEC_MSG_RESP_RESUME_DONE:
5470     omx->post_event (NULL,vdec_msg->status_code,\
5471                      OMX_COMPONENT_GENERATE_RESUME_DONE);
5472   break;
5473
5474   case VDEC_MSG_RESP_PAUSE_DONE:
5475     omx->post_event (NULL,vdec_msg->status_code,\
5476                      OMX_COMPONENT_GENERATE_PAUSE_DONE);
5477   break;
5478
5479   case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
5480     omx->post_event (NULL,vdec_msg->status_code,\
5481                      OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
5482     break;
5483   case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
5484     omx->post_event (NULL,vdec_msg->status_code,\
5485                      OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
5486     break;
5487   case VDEC_MSG_RESP_INPUT_FLUSHED:
5488   case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
5489
5490     omxhdr = (OMX_BUFFERHEADERTYPE* )\
5491               vdec_msg->msgdata.input_frame_clientdata;
5492
5493
5494     if (omxhdr == NULL ||
5495        ((omxhdr - omx->m_inp_mem_ptr) > omx->m_inp_buf_count) )
5496     {
5497        omxhdr = NULL;
5498        vdec_msg->status_code = VDEC_S_EFATAL;
5499     }
5500
5501     omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
5502                      OMX_COMPONENT_GENERATE_EBD);
5503     break;
5504   case VDEC_MSG_RESP_OUTPUT_FLUSHED:
5505   case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
5506     omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data;
5507     DEBUG_PRINT_LOW("\n Got Buffer back from Driver %p omxhdr time stamp = %d " ,omxhdr,vdec_msg->msgdata.output_frame.time_stamp);
5508
5509     if  ( (omxhdr != NULL) &&
5510          ((omxhdr - omx->m_out_mem_ptr)  < omx->m_out_buf_count) &&
5511          (omxhdr->pOutputPortPrivate != NULL) &&
5512          ( ((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
5513              - omx->driver_context.ptr_respbuffer) < omx->m_out_buf_count)
5514          )
5515     {
5516       if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen)
5517       {
5518         omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
5519         omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
5520         omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
5521         omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags & 0x01);
5522
5523         output_respbuf = (struct vdec_output_frameinfo *)\
5524                           omxhdr->pOutputPortPrivate;
5525         output_respbuf->framesize.bottom = \
5526           vdec_msg->msgdata.output_frame.framesize.bottom;
5527         output_respbuf->framesize.left = \
5528           vdec_msg->msgdata.output_frame.framesize.left;
5529         output_respbuf->framesize.right = \
5530           vdec_msg->msgdata.output_frame.framesize.right;
5531         output_respbuf->framesize.top = \
5532           vdec_msg->msgdata.output_frame.framesize.top;
5533         output_respbuf->len = vdec_msg->msgdata.output_frame.len;
5534         output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
5535         output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp;
5536         output_respbuf->flags = vdec_msg->msgdata.output_frame.flags;
5537
5538         /*Use buffer case*/
5539         if (omx->output_use_buffer)
5540         {
5541           if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
5542           {
5543             memcpy ( omxhdr->pBuffer,
5544                      (vdec_msg->msgdata.output_frame.bufferaddr +
5545                       vdec_msg->msgdata.output_frame.offset),
5546                       vdec_msg->msgdata.output_frame.len );
5547           }
5548           else
5549           {
5550             omxhdr->nFilledLen = 0;
5551           }
5552         }
5553       }
5554       else
5555       {
5556         omxhdr->nFilledLen = 0;
5557       }
5558
5559     }
5560     else
5561     {
5562        omxhdr = NULL;
5563        vdec_msg->status_code = VDEC_S_EFATAL;
5564     }
5565
5566     DEBUG_PRINT_LOW("\n Driver returned a output Buffer status %d",
5567                        vdec_msg->status_code);
5568     omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
5569                      OMX_COMPONENT_GENERATE_FBD);
5570     break;
5571   default:
5572     break;
5573   }
5574   return 1;
5575 }
5576
5577 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
5578                                                    OMX_HANDLETYPE hComp,
5579                                                    OMX_BUFFERHEADERTYPE *buffer
5580                                                            )
5581 {
5582   unsigned address,p2,id;
5583   DEBUG_PRINT_LOW("\n Empty this arbitrary");
5584
5585   if (buffer == NULL)
5586   {
5587     return OMX_ErrorBadParameter;
5588   }
5589   DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5590   DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
5591         buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
5592
5593   if( input_flush_progress == true || m_ineos_reached == 1)
5594   {
5595     DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5596     m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
5597     return OMX_ErrorNone;
5598   }
5599
5600   if (psource_frame == NULL)
5601   {
5602     DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
5603     psource_frame = buffer;
5604     DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
5605     push_input_buffer (hComp);
5606   }
5607   else
5608   {
5609     DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
5610     if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
5611     {
5612       return OMX_ErrorBadParameter;
5613     }
5614   }
5615
5616
5617   return OMX_ErrorNone;
5618 }
5619
5620 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
5621 {
5622   unsigned address,p2,id;
5623   OMX_ERRORTYPE ret = OMX_ErrorNone;
5624
5625   if (pdest_frame == NULL || psource_frame == NULL)
5626   {
5627     /*Check if we have a destination buffer*/
5628     if (pdest_frame == NULL)
5629     {
5630       DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
5631       if (m_input_free_q.m_size && !gate_input_buffers)
5632       {
5633         m_input_free_q.pop_entry(&address,&p2,&id);
5634         pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
5635         pdest_frame->nFilledLen = 0;
5636         DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
5637       }
5638     }
5639
5640     /*Check if we have a destination buffer*/
5641     if (psource_frame == NULL)
5642     {
5643       DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
5644       if (m_input_pending_q.m_size && !gate_input_buffers)
5645       {
5646         m_input_pending_q.pop_entry(&address,&p2,&id);
5647         psource_frame = (OMX_BUFFERHEADERTYPE *)address;
5648         DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
5649                 psource_frame->nTimeStamp);
5650         DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
5651         psource_frame->nFlags,psource_frame->nFilledLen);
5652
5653       }
5654     }
5655
5656   }
5657
5658   while ((pdest_frame != NULL) && (psource_frame != NULL)&& !gate_input_buffers)
5659   {
5660     switch (codec_type_parse)
5661     {
5662       case CODEC_TYPE_MPEG4:
5663       case CODEC_TYPE_H263:
5664         ret =  push_input_sc_codec(hComp);
5665       break;
5666       case CODEC_TYPE_H264:
5667         ret = push_input_h264(hComp);
5668       break;
5669       case CODEC_TYPE_VC1:
5670         ret = push_input_vc1(hComp);
5671       break;
5672     }
5673     if (ret != OMX_ErrorNone)
5674     {
5675       DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
5676       omx_report_error ();
5677       break;
5678     }
5679   }
5680
5681   return ret;
5682 }
5683
5684 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
5685 {
5686   OMX_U32 partial_frame = 1;
5687   OMX_BOOL genarte_edb = OMX_TRUE,generate_eos = OMX_TRUE;
5688   unsigned address,p2,id;
5689
5690   DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
5691         psource_frame,psource_frame->nTimeStamp);
5692   if (m_frame_parser.parse_mpeg4_frame(psource_frame,
5693                                        pdest_frame,&partial_frame) == -1)
5694   {
5695     DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
5696     return OMX_ErrorBadParameter;
5697   }
5698
5699   if (partial_frame == 0)
5700   {
5701     DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
5702           pdest_frame->nFilledLen,psource_frame,frame_count);
5703
5704
5705     DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
5706     /*First Parsed buffer will have only header Hence skip*/
5707     if (frame_count == 0)
5708     {
5709       DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
5710       mp4h263_flags = psource_frame->nFlags;
5711       mp4h263_timestamp = psource_frame->nTimeStamp;
5712       frame_count++;
5713     }
5714     else
5715     {
5716       pdest_frame->nTimeStamp = mp4h263_timestamp;
5717       mp4h263_timestamp = psource_frame->nTimeStamp;
5718       pdest_frame->nFlags = mp4h263_flags;
5719       mp4h263_flags  = psource_frame->nFlags;
5720
5721       if(psource_frame->nFilledLen == 0)
5722       {
5723         pdest_frame->nFlags = mp4h263_flags;
5724         generate_eos = OMX_FALSE;
5725       }
5726
5727
5728       /*Push the frame to the Decoder*/
5729       if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
5730       {
5731         return OMX_ErrorBadParameter;
5732       }
5733       if(m_event_port_settings_sent)
5734       {
5735         gate_input_buffers = true;
5736         return OMX_ErrorNone;
5737       }
5738       frame_count++;
5739       pdest_frame = NULL;
5740
5741       if (m_input_free_q.m_size && !gate_input_buffers)
5742       {
5743         m_input_free_q.pop_entry(&address,&p2,&id);
5744         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
5745         pdest_frame->nFilledLen = 0;
5746       }
5747     }
5748   }
5749   else
5750   {
5751     DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
5752     /*Check if Destination Buffer is full*/
5753     if (pdest_frame->nAllocLen ==
5754         pdest_frame->nFilledLen + pdest_frame->nOffset)
5755     {
5756       DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
5757       return OMX_ErrorStreamCorrupt;
5758     }
5759   }
5760
5761   if (psource_frame->nFilledLen == 0)
5762   {
5763     if ((psource_frame->nFlags & 0x01) && generate_eos)
5764     {
5765       if (pdest_frame)
5766       {
5767         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5768         pdest_frame->nFlags = psource_frame->nFlags;
5769         DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
5770                      pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
5771         DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
5772                      pdest_frame->nFilledLen,frame_count++);
5773         /*Push the frame to the Decoder*/
5774         if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
5775         {
5776           return OMX_ErrorBadParameter;
5777         }
5778         frame_count++;
5779         pdest_frame = NULL;
5780       }
5781       else
5782       {
5783         DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
5784         genarte_edb = OMX_FALSE;
5785       }
5786    }
5787     if(genarte_edb)
5788     {
5789       DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
5790       m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
5791       psource_frame = NULL;
5792
5793       if (m_input_pending_q.m_size)
5794       {
5795         DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
5796         m_input_pending_q.pop_entry(&address,&p2,&id);
5797         psource_frame = (OMX_BUFFERHEADERTYPE *) address;
5798         DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
5799                 psource_frame->nTimeStamp);
5800         DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
5801         psource_frame->nFlags,psource_frame->nFilledLen);
5802       }
5803     }
5804    }
5805   return OMX_ErrorNone;
5806 }
5807
5808 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
5809 {
5810   OMX_U32 partial_frame = 1;
5811   unsigned address,p2,id;
5812   OMX_BOOL isNewFrame = OMX_FALSE;
5813   OMX_BOOL genarte_edb = OMX_TRUE;
5814   OMX_BOOL skip_parsing = OMX_FALSE;
5815
5816   if (h264_scratch.pBuffer == NULL)
5817   {
5818     DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
5819     return OMX_ErrorBadParameter;
5820   }
5821   DEBUG_PRINT_LOW("\n Values of h264_scratch.nFilledLen %d look_ahead_nal %d",
5822                     h264_scratch.nFilledLen,look_ahead_nal);
5823   DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
5824   if (h264_scratch.nFilledLen && look_ahead_nal)
5825   {
5826     look_ahead_nal = false;
5827     DEBUG_PRINT_LOW("\n Copy the previous NAL into Buffer %d ",
5828                        h264_scratch.nFilledLen);
5829     if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
5830          h264_scratch.nFilledLen)
5831     {
5832       memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
5833               h264_scratch.pBuffer,h264_scratch.nFilledLen);
5834       pdest_frame->nFilledLen += h264_scratch.nFilledLen;
5835       DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen);
5836       h264_scratch.nFilledLen = 0;
5837     }
5838     else
5839     {
5840       DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5841       return OMX_ErrorBadParameter;
5842     }
5843   }
5844
5845   if(psource_frame->nFlags & 0x01)
5846   {
5847     DEBUG_PRINT_LOW("\n EOS has been reached no parsing required");
5848     skip_parsing = OMX_TRUE;
5849     if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
5850          psource_frame->nFilledLen)
5851     {
5852       memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
5853               (psource_frame->pBuffer+psource_frame->nOffset),
5854               psource_frame->nFilledLen);
5855       pdest_frame->nFilledLen += psource_frame->nFilledLen;
5856       DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen);
5857       psource_frame->nFilledLen = 0;
5858     }
5859     else
5860     {
5861       DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5862       return OMX_ErrorBadParameter;
5863     }
5864   }
5865
5866   if(!skip_parsing)
5867   {
5868     if (nal_length == 0)
5869     {
5870       DEBUG_PRINT_LOW("\n NAL length Zero hence parse using start code");
5871       if (m_frame_parser.parse_mpeg4_frame(psource_frame,
5872           &h264_scratch,&partial_frame) == -1)
5873       {
5874         DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
5875         return OMX_ErrorBadParameter;
5876       }
5877     }
5878     else
5879     {
5880       DEBUG_PRINT_LOW("\n NAL length %d hence parse with NAL length %d",nal_length);
5881       if (m_frame_parser.parse_h264_nallength(psource_frame,
5882           &h264_scratch,&partial_frame) == -1)
5883       {
5884         DEBUG_PRINT_ERROR("\n Error In Parsing NAL Return Error");
5885         return OMX_ErrorBadParameter;
5886       }
5887     }
5888
5889     if (partial_frame == 0)
5890     {
5891
5892       if (nal_count == 0 && h264_scratch.nFilledLen == 0)
5893       {
5894         DEBUG_PRINT_LOW("\n First NAL with Zero Length Hence Skip");
5895         nal_count++;
5896         h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
5897         h264_scratch.nFlags = psource_frame->nFlags;
5898       }
5899       else
5900       {
5901         DEBUG_PRINT_LOW("\n Length of New NAL is %d",h264_scratch.nFilledLen);
5902
5903         m_frame_parser.mutils->isNewFrame(h264_scratch.pBuffer,
5904             h264_scratch.nFilledLen,0,isNewFrame);
5905         nal_count++;
5906
5907         if (!isNewFrame)
5908         {
5909           if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
5910               h264_scratch.nFilledLen)
5911           {
5912             DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
5913                 h264_scratch.nFilledLen);
5914             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
5915                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
5916             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
5917             h264_scratch.nFilledLen = 0;
5918           }
5919           else
5920           {
5921             DEBUG_PRINT_LOW("\n Destination buffer overflow for H264");
5922             return OMX_ErrorBadParameter;
5923           }
5924         }
5925         else
5926         {
5927           look_ahead_nal = true;
5928           pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
5929           pdest_frame->nFlags = h264_scratch.nFlags;
5930           h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
5931           h264_scratch.nFlags = psource_frame->nFlags;
5932
5933           DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
5934                        pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
5935           DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
5936                        pdest_frame->nFilledLen,frame_count++);
5937
5938           if (pdest_frame->nFilledLen == 0)
5939           {
5940             DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
5941             look_ahead_nal = false;
5942             if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
5943                  h264_scratch.nFilledLen)
5944             {
5945               memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
5946                       h264_scratch.pBuffer,h264_scratch.nFilledLen);
5947               pdest_frame->nFilledLen += h264_scratch.nFilledLen;
5948               h264_scratch.nFilledLen = 0;
5949             }
5950             else
5951             {
5952               DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5953               return OMX_ErrorBadParameter;
5954             }
5955           }
5956           else
5957           {
5958             /*Push the frame to the Decoder*/
5959             if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
5960             {
5961               return OMX_ErrorBadParameter;
5962             }
5963             if(m_event_port_settings_sent)
5964             {
5965               gate_input_buffers = true;
5966               return OMX_ErrorNone;
5967             }
5968             //frame_count++;
5969             pdest_frame = NULL;
5970             if (m_input_free_q.m_size && !gate_input_buffers)
5971             {
5972               m_input_free_q.pop_entry(&address,&p2,&id);
5973               pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
5974               DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
5975               pdest_frame->nFilledLen = 0;
5976             }
5977           }
5978         }
5979       }
5980     }
5981     else
5982     {
5983       DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
5984       /*Check if Destination Buffer is full*/
5985       if (h264_scratch.nAllocLen ==
5986           h264_scratch.nFilledLen + h264_scratch.nOffset)
5987       {
5988         DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
5989         return OMX_ErrorStreamCorrupt;
5990       }
5991     }
5992   }
5993
5994   if (psource_frame->nFilledLen == 0)
5995   {
5996     DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
5997
5998     if (psource_frame->nFlags & 0x01)
5999     {
6000       if (pdest_frame)
6001       {
6002         DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6003         if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6004              h264_scratch.nFilledLen)
6005         {
6006           memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6007                   h264_scratch.pBuffer,h264_scratch.nFilledLen);
6008           pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6009           h264_scratch.nFilledLen = 0;
6010         }
6011         else
6012         {
6013           DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
6014           return OMX_ErrorBadParameter;
6015         }
6016         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
6017         pdest_frame->nFlags = psource_frame->nFlags;
6018
6019         DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
6020                      pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6021         DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
6022                      pdest_frame->nFilledLen,frame_count++);
6023         /*Push the frame to the Decoder*/
6024         if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
6025         {
6026           return OMX_ErrorBadParameter;
6027         }
6028           if(m_event_port_settings_sent)
6029           {
6030             gate_input_buffers = true;
6031             return OMX_ErrorNone;
6032           }
6033         frame_count++;
6034         pdest_frame = NULL;
6035       }
6036       else
6037       {
6038         DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
6039                      pdest_frame,h264_scratch.nFilledLen);
6040         genarte_edb = OMX_FALSE;
6041       }
6042     }
6043     if(genarte_edb)
6044     {
6045                 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6046                 psource_frame = NULL;
6047                 if (m_input_pending_q.m_size && !gate_input_buffers)
6048                 {
6049                         DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6050                   m_input_pending_q.pop_entry(&address,&p2,&id);
6051                   psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6052                   DEBUG_PRINT_LOW("\nNext source Buffer flag %d length %d",
6053                   psource_frame->nFlags,psource_frame->nFilledLen);
6054                 }
6055         }
6056   }
6057   return OMX_ErrorNone;
6058 }
6059
6060 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
6061 {
6062     OMX_U8 *buf, *pdest;
6063     OMX_U32 partial_frame = 1;
6064     OMX_U32 buf_len, dest_len;
6065
6066     if(frame_count == 0)
6067     {
6068         DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
6069         if(!m_vendor_config.pData)
6070         {
6071             DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
6072             buf = psource_frame->pBuffer;
6073             buf_len = psource_frame->nFilledLen;
6074
6075             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
6076                 VC1_SP_MP_START_CODE)
6077             {
6078                 m_vc1_profile = VC1_SP_MP_RCV;
6079             }
6080             else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
6081             {
6082                 m_vc1_profile = VC1_AP;
6083             }
6084             else
6085             {
6086                 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
6087                 return OMX_ErrorStreamCorrupt;
6088             }
6089         }
6090         else
6091         {
6092             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
6093                 pdest_frame->nOffset;
6094             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
6095                 pdest_frame->nOffset);
6096
6097             if(dest_len < m_vendor_config.nDataSize)
6098             {
6099                 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
6100                 return OMX_ErrorBadParameter;
6101             }
6102             else
6103             {
6104                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
6105                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
6106             }
6107         }
6108     }
6109
6110     switch(m_vc1_profile)
6111     {
6112         case VC1_AP:
6113             DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
6114             if (push_input_sc_codec(hComp) != OMX_ErrorNone)
6115             {
6116                 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
6117                 return OMX_ErrorBadParameter;
6118             }
6119         break;
6120
6121         case VC1_SP_MP_RCV:
6122         default:
6123             DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
6124             return OMX_ErrorBadParameter;
6125     }
6126     return OMX_ErrorNone;
6127 }
6128
6129 bool omx_vdec::register_output_buffers()
6130 {
6131   struct vdec_ioctl_msg ioctl_msg;
6132   struct vdec_setbuffer_cmd setbuffers;
6133   int i = 0;
6134   unsigned p1 =0,p2 = 0,ident = 0;
6135
6136   for(i=0;i<m_out_buf_count;i++)
6137   {
6138     setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
6139     memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i],
6140             sizeof (vdec_bufferpayload));
6141     ioctl_msg.inputparam  = &setbuffers;
6142     ioctl_msg.outputparam = NULL;
6143
6144     DEBUG_PRINT_LOW("\n Set the Output Buffer");
6145     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
6146          &ioctl_msg) < 0)
6147     {
6148       DEBUG_PRINT_ERROR("\n Set output buffer failed");
6149       return false;
6150     }
6151   }
6152   if(gate_output_buffers)
6153   {
6154     /*Generate FBD for all Buffers in the FTBq*/
6155     pthread_mutex_lock(&m_lock);
6156     DEBUG_PRINT_LOW("\n Initiate Pushing Output Buffers");
6157     while (m_ftb_q.m_size)
6158     {
6159       m_ftb_q.pop_entry(&p1,&p2,&ident);
6160       if(ident == OMX_COMPONENT_GENERATE_FTB )
6161       {
6162         if (fill_this_buffer_proxy ((OMX_HANDLETYPE)p1,
6163                                     (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
6164           {
6165              DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
6166              omx_report_error ();
6167              return false;
6168           }
6169       }
6170       else if (ident == OMX_COMPONENT_GENERATE_FBD)
6171       {
6172         fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
6173       }
6174     }
6175     gate_output_buffers = false;
6176     pthread_mutex_unlock(&m_lock);
6177   }
6178   return true;
6179 }
6180
6181 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
6182                                   OMX_U32 alignment)
6183 {
6184 //TODO: figure out if this is really necessary (PMEM_ALLOCATE_ALIGNED is a
6185 // QCOM extension to pmem
6186   return true;
6187 #if 0
6188   struct pmem_allocation allocation;
6189   allocation.size = buffer_size;
6190   allocation.align = clip2(alignment);
6191   if (allocation.align < 4096)
6192   {
6193     allocation.align = 4096;
6194   }
6195   if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
6196   {
6197     DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver");
6198     return false;
6199   }
6200   return true;
6201 #endif
6202 }
6203