1/*--------------------------------------------------------------------------
2Copyright (c) 2009, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6    * Redistributions of source code must retain the above copyright
7      notice, this list of conditions and the following disclaimer.
8    * Redistributions in binary form must reproduce the above copyright
9      notice, this list of conditions and the following disclaimer in the
10      documentation and/or other materials provided with the distribution.
11    * Neither the name of Code Aurora nor
12      the names of its contributors may be used to endorse or promote
13      products derived from this software without specific prior written
14      permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28/*============================================================================
29                            O p e n M A X   w r a p p e r s
30                             O p e n  M A X   C o r e
31
32  This module contains the implementation of the OpenMAX core.
33
34*//*========================================================================*/
35
36//////////////////////////////////////////////////////////////////////////////
37//                             Include Files
38//////////////////////////////////////////////////////////////////////////////
39
40#include <dlfcn.h>           // dynamic library
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <string.h>
45#include <stdio.h>
46
47#include "qc_omx_core.h"
48#include "omx_core_cmp.h"
49
50#define DEBUG_PRINT_ERROR printf
51#define DEBUG_PRINT       printf
52#define DEBUG_DETAIL      printf
53
54extern omx_core_cb_type core[];
55extern const unsigned int SIZE_OF_CORE;
56
57
58/* ======================================================================
59FUNCTION
60  omx_core_load_cmp_library
61
62DESCRIPTION
63  Loads up the libary name mentioned in the argument
64
65PARAMETERS
66  None
67
68RETURN VALUE
69  Constructor for creating component instances.
70========================================================================== */
71static create_qc_omx_component
72omx_core_load_cmp_library(char *libname, void **handle_ptr)
73{
74  create_qc_omx_component fn_ptr = NULL;
75  if(handle_ptr)
76  {
77    DEBUG_PRINT("Dynamically Loading the library : %s\n",libname);
78    *handle_ptr = dlopen(libname,RTLD_NOW);
79    if(*handle_ptr)
80    {
81      fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn");
82
83      if(fn_ptr == NULL)
84      {
85        DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n",
86                  libname, dlerror());
87        *handle_ptr = NULL;
88      }
89    }
90    else
91    {
92      DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror());
93    }
94  }
95  return fn_ptr;
96}
97
98/* ======================================================================
99FUNCTION
100  OMX_Init
101
102DESCRIPTION
103  This is the first function called by the application.
104  There is nothing to do here since components shall be loaded
105  whenever the get handle method is called.
106
107PARAMETERS
108  None
109
110RETURN VALUE
111  None.
112========================================================================== */
113OMX_API OMX_ERRORTYPE OMX_APIENTRY
114OMX_Init()
115{
116  DEBUG_PRINT("OMXCORE API - OMX_Init \n");
117  /* Nothing to do here ; shared objects shall be loaded at the get handle method */
118  return OMX_ErrorNone;
119}
120
121/* ======================================================================
122FUNCTION
123  get_cmp_index
124
125DESCRIPTION
126  Obtains the  index associated with the name.
127
128PARAMETERS
129  None
130
131RETURN VALUE
132  Error None.
133========================================================================== */
134static int get_cmp_index(char *cmp_name)
135{
136  int rc = -1,i=0;
137  DEBUG_PRINT("before get_cmp_index **********%d\n", rc);
138
139  for(i=0; i< (int)SIZE_OF_CORE; i++)
140  {
141   DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i);
142
143    if(!strcmp(cmp_name, core[i].name))
144    {
145        rc = i;
146        break;
147    }
148  }
149  DEBUG_PRINT("returning index %d\n", rc);
150  return rc;
151}
152
153/* ======================================================================
154FUNCTION
155  clear_cmp_handle
156
157DESCRIPTION
158  Clears the component handle from the component table.
159
160PARAMETERS
161  None
162
163RETURN VALUE
164  None.
165========================================================================== */
166static void clear_cmp_handle(OMX_HANDLETYPE inst)
167{
168  unsigned i = 0,j=0;
169
170  if(NULL == inst)
171     return;
172
173  for(i=0; i< SIZE_OF_CORE; i++)
174  {
175    for(j=0; j< OMX_COMP_MAX_INST; j++)
176    {
177      if(inst == core[i].inst[j])
178      {
179        core[i].inst[j] = NULL;
180        return;
181      }
182    }
183  }
184  return;
185}
186/* ======================================================================
187FUNCTION
188  is_cmp_handle_exists
189
190DESCRIPTION
191  Check if the component handle already exists or not.
192
193PARAMETERS
194  None
195
196RETURN VALUE
197  index pointer if the handle exists
198  negative value otherwise
199========================================================================== */
200static int is_cmp_handle_exists(OMX_HANDLETYPE inst)
201{
202  unsigned i=0,j=0;
203  int rc = -1;
204
205  if(NULL == inst)
206     return rc;
207
208  for(i=0; i< SIZE_OF_CORE; i++)
209  {
210    for(j=0; j< OMX_COMP_MAX_INST; j++)
211    {
212      if(inst == core[i].inst[j])
213      {
214        rc = i;
215        return rc;
216      }
217    }
218  }
219  return rc;
220}
221
222/* ======================================================================
223FUNCTION
224  get_comp_handle_index
225
226DESCRIPTION
227  Gets the index to store the next handle for specified component name.
228
229PARAMETERS
230  cmp_name : Component Name
231
232RETURN VALUE
233  Index of next handle to be stored
234========================================================================== */
235static int get_comp_handle_index(char *cmp_name)
236{
237  unsigned i=0,j=0;
238  int rc = -1;
239  for(i=0; i< SIZE_OF_CORE; i++)
240  {
241    if(!strcmp(cmp_name, core[i].name))
242    {
243      for(j=0; j< OMX_COMP_MAX_INST; j++)
244      {
245        if(NULL == core[i].inst[j])
246        {
247          rc = j;
248          DEBUG_PRINT("free handle slot exists %d\n", rc);
249          return rc;
250        }
251      }
252      break;
253    }
254  }
255  return rc;
256}
257
258/* ======================================================================
259FUNCTION
260  check_lib_unload
261
262DESCRIPTION
263  Check if any component instance is using the library
264
265PARAMETERS
266  index: Component Index in core array.
267
268RETURN VALUE
269  1: Library Unused and can be unloaded.
270  0:  Library used and shouldnt be unloaded.
271========================================================================== */
272static int check_lib_unload(int index)
273{
274  unsigned i=0;
275  int rc = 1;
276
277  for(i=0; i< OMX_COMP_MAX_INST; i++)
278  {
279    if(core[index].inst[i])
280    {
281      rc = 0;
282      DEBUG_PRINT("Library Used \n");
283      break;
284    }
285  }
286  return rc;
287}
288/* ======================================================================
289FUNCTION
290  is_cmp_already_exists
291
292DESCRIPTION
293  Check if the component already exists or not. Used in the
294  management of component handles.
295
296PARAMETERS
297  None
298
299RETURN VALUE
300  Error None.
301========================================================================== */
302static int is_cmp_already_exists(char *cmp_name)
303{
304  unsigned i    =0,j=0;
305  int rc = -1;
306  for(i=0; i< SIZE_OF_CORE; i++)
307  {
308    if(!strcmp(cmp_name, core[i].name))
309    {
310      for(j=0; j< OMX_COMP_MAX_INST; j++)
311      {
312        if(core[i].inst[j])
313        {
314          rc = i;
315          DEBUG_PRINT("Component exists %d\n", rc);
316          return rc;
317        }
318      }
319      break;
320    }
321  }
322  return rc;
323}
324
325/* ======================================================================
326FUNCTION
327  get_cmp_handle
328
329DESCRIPTION
330  Get component handle.
331
332PARAMETERS
333  None
334
335RETURN VALUE
336  Error None.
337========================================================================== */
338void* get_cmp_handle(char *cmp_name)
339{
340  unsigned i    =0,j=0;
341
342  DEBUG_PRINT("get_cmp_handle \n");
343  for(i=0; i< SIZE_OF_CORE; i++)
344  {
345    if(!strcmp(cmp_name, core[i].name))
346    {
347      for(j=0; j< OMX_COMP_MAX_INST; j++)
348      {
349        if(core[i].inst[j])
350        {
351          DEBUG_PRINT("get_cmp_handle match\n");
352          return core[i].inst[j];
353        }
354      }
355    }
356  }
357  DEBUG_PRINT("get_cmp_handle returning NULL \n");
358  return NULL;
359}
360
361/* ======================================================================
362FUNCTION
363  OMX_DeInit
364
365DESCRIPTION
366  DeInitialize all the the relevant OMX components.
367
368PARAMETERS
369  None
370
371RETURN VALUE
372  Error None.
373========================================================================== */
374OMX_API OMX_ERRORTYPE OMX_APIENTRY
375OMX_Deinit()
376{
377  int err;
378  unsigned i=0,j=0;
379  OMX_ERRORTYPE eRet;
380
381  /* Free the dangling handles here if any */
382  for(i=0; i< SIZE_OF_CORE; i++)
383  {
384    for(j=0; j< OMX_COMP_MAX_INST; j++)
385    {
386      if(core[i].inst[j])
387      {
388        DEBUG_PRINT("OMX DeInit: Freeing handle for %s\n",
389                     core[i].name);
390
391        /* Release the component and unload dynmaic library */
392        eRet = OMX_FreeHandle(core[i].inst[j]);
393        if(eRet != OMX_ErrorNone)
394          return eRet;
395      }
396    }
397  }
398  return OMX_ErrorNone;
399}
400
401/* ======================================================================
402FUNCTION
403  OMX_GetHandle
404
405DESCRIPTION
406  Constructs requested component. Relevant library is loaded if needed.
407
408PARAMETERS
409  None
410
411RETURN VALUE
412  Error None  if everything goes fine.
413========================================================================== */
414
415 OMX_API OMX_ERRORTYPE OMX_APIENTRY
416OMX_GetHandle(OMX_OUT OMX_HANDLETYPE*     handle,
417              OMX_IN OMX_STRING    componentName,
418              OMX_IN OMX_PTR             appData,
419              OMX_IN OMX_CALLBACKTYPE* callBacks)
420{
421  OMX_ERRORTYPE  eRet = OMX_ErrorNone;
422  int cmp_index = -1;
423  int hnd_index = -1;
424
425  DEBUG_PRINT("OMXCORE API :  Get Handle %x %s %x\n",(unsigned) handle,
426                                                     componentName,
427                                                     (unsigned) appData);
428  if(handle)
429  {
430    struct stat sd;
431
432    *handle = NULL;
433    if(stat("/dev/pmem_adsp",&sd) != 0)
434        return OMX_ErrorInsufficientResources;
435
436    cmp_index = get_cmp_index(componentName);
437
438    if(cmp_index >= 0)
439    {
440       DEBUG_PRINT("getting fn pointer\n");
441
442      // dynamically load the so
443      core[cmp_index].fn_ptr =
444        omx_core_load_cmp_library(core[cmp_index].so_lib_name,
445                                  &core[cmp_index].so_lib_handle);
446
447      if(core[cmp_index].fn_ptr)
448      {
449        // Construct the component requested
450        // Function returns the opaque handle
451        void* pThis = (*(core[cmp_index].fn_ptr))();
452        if(pThis)
453        {
454          void *hComp = NULL;
455          hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
456          if((eRet = qc_omx_component_init(hComp, core[cmp_index].name)) !=
457                           OMX_ErrorNone)
458          {
459              DEBUG_PRINT("Component not created succesfully\n");
460              return eRet;
461
462          }
463          qc_omx_component_set_callbacks(hComp,callBacks,appData);
464          hnd_index = get_comp_handle_index(componentName);
465          if(hnd_index >= 0)
466          {
467            core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
468          }
469          else
470          {
471            DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
472            return OMX_ErrorInsufficientResources;
473          }
474          DEBUG_PRINT("Component %x Successfully created\n",(unsigned)*handle);
475        }
476        else
477        {
478          eRet = OMX_ErrorInsufficientResources;
479          DEBUG_PRINT("Component Creation failed\n");
480        }
481      }
482      else
483      {
484        eRet = OMX_ErrorNotImplemented;
485        DEBUG_PRINT("library couldnt return create instance fn\n");
486      }
487
488    }
489    else
490    {
491      eRet = OMX_ErrorNotImplemented;
492      DEBUG_PRINT("ERROR: Already another instance active  ;rejecting \n");
493    }
494  }
495  else
496  {
497    eRet =  OMX_ErrorBadParameter;
498    DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
499  }
500  return eRet;
501}
502/* ======================================================================
503FUNCTION
504  OMX_FreeHandle
505
506DESCRIPTION
507  Destructs the component handles.
508
509PARAMETERS
510  None
511
512RETURN VALUE
513  Error None.
514========================================================================== */
515OMX_API OMX_ERRORTYPE OMX_APIENTRY
516OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
517{
518  OMX_ERRORTYPE eRet = OMX_ErrorNone;
519  int err = 0, i = 0;
520  DEBUG_PRINT("OMXCORE API :  Free Handle %x\n",(unsigned) hComp);
521
522  // 0. Check that we have an active instance
523  if((i=is_cmp_handle_exists(hComp)) >=0)
524  {
525    // 1. Delete the component
526    if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
527    {
528        /* Unload component library */
529    if( ((unsigned int)i < SIZE_OF_CORE) && core[i].so_lib_handle)
530    {
531           if(check_lib_unload(i))
532           {
533              DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
534                                  core[i].name);
535              err = dlclose(core[i].so_lib_handle);
536              if(err)
537              {
538                  DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
539                                     err,core[i].name);
540              }
541              core[i].so_lib_handle = NULL;
542           }
543    }
544    clear_cmp_handle(hComp);
545    }
546    else
547    {
548    DEBUG_PRINT(" OMX_FreeHandle failed on %x\n",(unsigned) hComp);
549        return eRet;
550    }
551  }
552  else
553  {
554    DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
555  }
556  return OMX_ErrorNone;
557}
558/* ======================================================================
559FUNCTION
560  OMX_SetupTunnel
561
562DESCRIPTION
563  Not Implemented.
564
565PARAMETERS
566  None
567
568RETURN VALUE
569  None.
570========================================================================== */
571OMX_API OMX_ERRORTYPE OMX_APIENTRY
572OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
573                OMX_IN OMX_U32             outputPort,
574                OMX_IN OMX_HANDLETYPE  inputComponent,
575                OMX_IN OMX_U32              inputPort)
576{
577  /* Not supported right now */
578  DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
579  return OMX_ErrorNotImplemented;
580}
581/* ======================================================================
582FUNCTION
583  OMX_GetContentPipe
584
585DESCRIPTION
586  Not Implemented.
587
588PARAMETERS
589  None
590
591RETURN VALUE
592  None.
593========================================================================== */
594OMX_API OMX_ERRORTYPE
595OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
596                   OMX_IN OMX_STRING        uri)
597{
598  /* Not supported right now */
599  DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
600  return OMX_ErrorNotImplemented;
601}
602
603/* ======================================================================
604FUNCTION
605  OMX_GetComponentNameEnum
606
607DESCRIPTION
608  Returns the component name associated with the index.
609
610PARAMETERS
611  None
612
613RETURN VALUE
614  None.
615========================================================================== */
616OMX_API OMX_ERRORTYPE OMX_APIENTRY
617OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
618                      OMX_IN  OMX_U32          nameLen,
619                      OMX_IN  OMX_U32            index)
620{
621  OMX_ERRORTYPE eRet = OMX_ErrorNone;
622  DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %x %d %d\n",(unsigned) componentName
623                                                              ,(unsigned)nameLen
624                                                              ,(unsigned)index);
625  if(index < SIZE_OF_CORE)
626  {
627    #ifdef _ANDROID_
628    strlcpy(componentName, core[index].name,nameLen);
629    #else
630    strncpy(componentName, core[index].name,nameLen);
631    #endif
632  }
633  else
634  {
635    eRet = OMX_ErrorNoMore;
636  }
637  return eRet;
638}
639
640/* ======================================================================
641FUNCTION
642  OMX_GetComponentsOfRole
643
644DESCRIPTION
645  Returns the component name which can fulfill the roles passed in the
646  argument.
647
648PARAMETERS
649  None
650
651RETURN VALUE
652  None.
653========================================================================== */
654OMX_API OMX_ERRORTYPE
655OMX_GetComponentsOfRole(OMX_IN OMX_STRING      role,
656                        OMX_INOUT OMX_U32* numComps,
657                        OMX_INOUT OMX_U8** compNames)
658{
659  OMX_ERRORTYPE eRet = OMX_ErrorNone;
660  unsigned i,j,namecount=0;
661
662  printf(" Inside OMX_GetComponentsOfRole \n");
663
664  /*If CompNames is NULL then return*/
665  if (compNames == NULL)
666  {
667      if (numComps == NULL)
668      {
669          eRet = OMX_ErrorBadParameter;
670      }
671      else
672  {
673    *numComps          = 0;
674    for (i=0; i<SIZE_OF_CORE;i++)
675    {
676      for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
677      {
678        if(!strcmp(role,core[i].roles[j]))
679        {
680                  (*numComps)++;
681              }
682            }
683          }
684      }
685      return eRet;
686  }
687
688  if(numComps)
689  {
690      namecount = *numComps;
691
692      if (namecount == 0)
693      {
694          return OMX_ErrorBadParameter;
695      }
696
697    *numComps          = 0;
698
699    for (i=0; i<SIZE_OF_CORE;i++)
700    {
701      for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
702      {
703        if(!strcmp(role,core[i].roles[j]))
704          {
705            #ifdef _ANDROID_
706            strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
707            #else
708            strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
709            #endif
710          (*numComps)++;
711          break;
712        }
713      }
714          if (*numComps == namecount)
715          {
716          break;
717        }
718    }
719  }
720  else
721  {
722    eRet = OMX_ErrorBadParameter;
723  }
724
725  printf(" Leaving OMX_GetComponentsOfRole \n");
726  return eRet;
727}
728/* ======================================================================
729FUNCTION
730  OMX_GetRolesOfComponent
731
732DESCRIPTION
733  Returns the primary role of the components supported.
734
735PARAMETERS
736  None
737
738RETURN VALUE
739  None.
740========================================================================== */
741OMX_API OMX_ERRORTYPE
742OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
743                        OMX_INOUT OMX_U32* numRoles,
744                        OMX_OUT OMX_U8** roles)
745{
746  /* Not supported right now */
747  OMX_ERRORTYPE eRet = OMX_ErrorNone;
748  unsigned i,j,numofroles = 0;;
749  DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
750
751  if (roles == NULL)
752  {
753      if (numRoles == NULL)
754      {
755         eRet = OMX_ErrorBadParameter;
756      }
757      else
758      {
759         *numRoles = 0;
760         for(i=0; i< SIZE_OF_CORE; i++)
761         {
762           if(!strcmp(compName,core[i].name))
763           {
764             for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
765             {
766                (*numRoles)++;
767             }
768             break;
769           }
770         }
771
772      }
773      return eRet;
774  }
775
776  if(numRoles)
777  {
778    if (*numRoles == 0)
779    {
780        return OMX_ErrorBadParameter;
781    }
782
783    numofroles = *numRoles;
784    *numRoles = 0;
785    for(i=0; i< SIZE_OF_CORE; i++)
786    {
787      if(!strcmp(compName,core[i].name))
788      {
789        for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
790        {
791          if(roles && roles[*numRoles])
792          {
793            #ifdef _ANDROID_
794            strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
795            #else
796            strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
797            #endif
798          }
799          (*numRoles)++;
800          if (numofroles == *numRoles)
801          {
802              break;
803          }
804        }
805        break;
806      }
807    }
808  }
809  else
810  {
811    DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
812    eRet = OMX_ErrorBadParameter;
813  }
814  return eRet;
815}
816
817OMX_API OMX_BOOL
818OMXConfigParser(
819    OMX_PTR aInputParameters,
820    OMX_PTR aOutputParameters)
821{
822    OMX_BOOL Status = OMX_TRUE;
823    VideoOMXConfigParserOutputs *aOmxOutputParameters;
824    OMXConfigParserInputs *aOmxInputParameters;
825    aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
826    aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
827
828    aOmxOutputParameters->width = 176; //setting width to QCIF
829    aOmxOutputParameters->height = 144; //setting height to QCIF
830
831    //TODO
832    //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
833    //sent in ETB so for now setting the defalut values . Going farward we can call
834    //QC parser here.
835    if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
836    {
837       aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
838       aOmxOutputParameters->level = 0;  // minimum supported h264 level
839    }
840    else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
841    {
842       aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
843       aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
844    }
845
846    return Status;
847}
848