Upto: Table of Contents of full book "Programming the Raspberry Pi GPU"

OpenMAX Components on the Raspberry Pi

OpenMAX uses components as the objects in its processing model. There is a large list of standard components. The Broadcom implementation on the Raspberry Pi only has a subset of these, plus some others. This chapter shows how to list the available components and get some of their properties.

Resources

Files

Files used are here

OpenMAX IL components

OpenMAX IL in 1.1.2 lists a number of standard components, including a decoder, an encoder, a mixer, a reader, a renderer, a writer, a capturer and a processor. An IL client gets such a component by calling OMX_GetHandle(), passing in the name of the component. This is a problem: the components do not have a standard name. The 1.1.2 specification says:

Since components are requested by name, a naming convention is defined. OpenMAX IL component names are zero terminated strings with the following format: “OMX.<vendor_name>.<vendor_specified_convention>”. For example:
OMX.CompanyABC.MP3Decoder.productXYZ
No standardization among component names is dictated across different vendors.

The Broadcom OpenMAX IL components used on the Raspberry Pi are documented at VMCS-X OpenMAX IL Components. For example, that page shows a visualisation component as

This has two audio ports (green), an input port 140 and an output port 141, a timer port (yellow), number 143 and a video output port (red), number 142. Clicking on this component shows further details including the parameters that can be queried or set.

The detail view also shows the name of the component, which is used to lookup the component. For the visualisation component, its name is OMX.broadcom.visualisation.

Getting a list of components

There is a simple way of programmatically getting the supported components. First initialise the OpenMAX system by OMX_init() and then make calls to OMX_ComponentNameEnum(). For successive index values it returns a unique name each time, until it finally returns an error value of OMX_ErrorNoMore.

Each component may support a number of roles. These are given by OMX_GetRolesOfComponent. The Broadcom version has zero roles for each component so it isn't useful for the RPi.

The program is listcomponents.c:


#include <stdio.h>
#include <stdlib.h>

#include <OMX_Core.h>

#include <bcm_host.h>

OMX_ERRORTYPE err;

void listroles(char *name) {
    int n;
    OMX_U32 numRoles;
    OMX_U8 *roles[32];

    /* get the number of roles by passing in a NULL roles param */
    err = OMX_GetRolesOfComponent(name, &numRoles, NULL);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "Getting roles failed\n", 0);
	exit(1);
    }
    printf("  Num roles is %d\n", numRoles);
    if (numRoles > 32) {
	printf("Too many roles to list\n");
	return;
    }

    /* now get the roles */
    for (n = 0; n < numRoles; n++) {
	roles[n] = malloc(OMX_MAX_STRINGNAME_SIZE);
    }
    err = OMX_GetRolesOfComponent(name, &numRoles, roles);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "Getting roles failed\n", 0);
	exit(1);
    }
    for (n = 0; n < numRoles; n++) {
	printf("    role: %s\n", roles[n]);
	free(roles[n]);
    }

    /* This is in version 1.2
    for (i = 0; OMX_ErrorNoMore != err; i++) {
	err = OMX_RoleOfComponentEnum(role, name, i);
	if (OMX_ErrorNone == err) {
	    printf("   Role of omponent is %s\n", role);
	}
    } 
    */   
}

int main(int argc, char** argv) {

    int i;
    unsigned char name[OMX_MAX_STRINGNAME_SIZE];

    bcm_host_init();

    err = OMX_Init();
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_Init() failed\n", 0);
	exit(1);
    }

    err = OMX_ErrorNone;
    for (i = 0; OMX_ErrorNoMore != err; i++) {
	err = OMX_ComponentNameEnum(name, OMX_MAX_STRINGNAME_SIZE, i);
	if (OMX_ErrorNone == err) {
	    printf("Component is %s\n", name);
	    listroles(name);
	}
    }
    printf("No more components\n");

    exit(0);
}

      

The Makefile for this program is

	
INCLUDES=-I /opt/vc/include/IL -I /opt/vc/include -I /opt/vc/include/interface/vcos/pthreads
CFLAGS=
LIBS=-L /opt/vc/lib -l openmaxil -l bcm_host

listcomponents: listcomponents.c
	cc $(CFLAGS) $(INCLUDES) -o listcomponents listcomponents.c $(LIBS)
	
      

and it is run by

	
./listcomponents
	
      

The Raspberry Pi reports a large number of components but does not define a role for any of them:

        
Component is OMX.broadcom.audio_capture
  Num roles is 0
Component is OMX.broadcom.audio_decode
  Num roles is 0
Component is OMX.broadcom.audio_encode
  Num roles is 0
Component is OMX.broadcom.audio_render
  Num roles is 0
Component is OMX.broadcom.audio_mixer
  Num roles is 0
Component is OMX.broadcom.audio_splitter
  Num roles is 0
Component is OMX.broadcom.audio_processor
  Num roles is 0
Component is OMX.broadcom.camera
  Num roles is 0
Component is OMX.broadcom.clock
  Num roles is 0
Component is OMX.broadcom.coverage
  Num roles is 0
Component is OMX.broadcom.egl_render
  Num roles is 0
Component is OMX.broadcom.image_fx
  Num roles is 0
Component is OMX.broadcom.image_decode
  Num roles is 0
Component is OMX.broadcom.image_encode
  Num roles is 0
Component is OMX.broadcom.image_read
  Num roles is 0
Component is OMX.broadcom.image_write
  Num roles is 0
Component is OMX.broadcom.read_media
  Num roles is 0
Component is OMX.broadcom.resize
  Num roles is 0
Component is OMX.broadcom.source
  Num roles is 0
Component is OMX.broadcom.text_scheduler
  Num roles is 0
Component is OMX.broadcom.transition
  Num roles is 0
Component is OMX.broadcom.video_decode
  Num roles is 0
Component is OMX.broadcom.video_encode
  Num roles is 0
Component is OMX.broadcom.video_render
  Num roles is 0
Component is OMX.broadcom.video_scheduler
  Num roles is 0
Component is OMX.broadcom.video_splitter
  Num roles is 0
Component is OMX.broadcom.visualisation
  Num roles is 0
Component is OMX.broadcom.write_media
  Num roles is 0
Component is OMX.broadcom.write_still
  Num roles is 0
No more components
        
      

Getting a handle to a component

Before you can do anything with a component (apart from getting its name above), you need to get a handle to it. The call OMX_GetHandle takes four parameters:

For example,

	
err = OMX_GetHandle(&handle, componentName,
			// the next two fields are discussed later 
			NULL, &callbacks);
	
      

Port information

Ports are the means by which a component communicates, where clients pass data into a port's input buffers and receive processed data back from a port's output buffers.

OpenMAX uses an OMX_PARAM_PORTDEFINITIONTYPE struct to keep port information. This is a complex structure, found in the OMX_Component.h file and in Section 3.1.2.12 of the 1.1.2 specification.

All of the OpenMAX structures, just like this one, have as their first field the size of the structure and as the second field the version of OpenMAX that is being used. Before any struct is used, these must be initialised. It is also a good idea to ensure the structure is zeroed out

	
struct OMX_PARAM_PORTDEFINITIONTYPE portdef;
memset(&portdef, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
portdef.nVersion.nVersion = OMX_VERSION;
	`
      

The next most important parameter is the index number of the port we are interested in. One way of finding this is from the documentation discussed in a previous section. For example, if we were querying the video port of the visualisation component, we would specify this video port by

	
portdef.nPortIndex = 142;
	
      

There are other ways, which are discussed later when we look at particular port types.

Each port has buffers. Information about these buffers is stored in the next set of fields

	
OMX_U32 nBufferCountActual;    /** The actual number of buffers allocated on this port */
OMX_U32 nBufferCountMin;       /** The minimum number of buffers this port requires */
OMX_U32 nBufferSize;           /** Size, in bytes, for buffers to be used for this channel */
	
      

Ports have a state flag as to whether they are enabled or disabled. Components also have state and there is interaction between port state and component state - and it's not nice. This will be dealt with in more detail in a later chapter. For now, you often toggle this between OMX_TRUE and OMX_FALSE:


OMX_BOOL bEnabled;

The last important fields deal with the type of port. Firstly, there is the direction: either OMX_DirInput or OMX_DirOutput.

	
OMX_DIRTYPE eDir;
	
      

Next is whether it is an audio (OMX_PortDomainAudio), video (OMX_PortDomainVideo), image (OMX_PortDomainImage) or other (OMX_PortDomainOther) port:

	
OMX_PORTDOMAINTYPE eDomain
	
      

Finally, there is a union corresponding to each of these domains:

	
union {
    OMX_AUDIO_PORTDEFINITIONTYPE audio;
    OMX_VIDEO_PORTDEFINITIONTYPE video;
    OMX_IMAGE_PORTDEFINITIONTYPE image;
    OMX_OTHER_PORTDEFINITIONTYPE other;
} format;
	
      

Getting and setting parameters

OpenMAX has a standard way of getting and setting parameter information for all types such as the OMX_PARAM_PORTDEFINITIONTYPE above. A handle to a component is required; this will have come from a call to OMX_GetHandle() earlier. Then for each type of struct there is a corresponding index value. For the OMX_PARAM_PORTDEFINITIONTYPE, the index is OMX_IndexParamPortDefinition, with a similar pattern for other data types. (Strangely, the index OMX_IndexParamPortDefinition doesn't seem to be individually documented in the 1.1.2 specification. Oh well, it works anyway.)

A call to set a parameter value is described in Section 3.2.2.8 of the 1.1.2 Specification and is

	
OMX_GetParameter(handle, 
	         <index>, 
	         <struct_address>);
	
      

as in

	
OMX_GetParameter(handle, 
 	         OMX_IndexParamPortDefinition, 
	         &portdef);
	
      

while setting a parameter described in Section 3.2.2.9 of the 1.1.2 Specification and is done by

	
OMX_SetParameter(handle, 
	         <index>, 
	         <struct_address>);
	
      

Getting port information

We can now combine the last three sections to give a program to get the information about a particular port on a component and print it out. The program is portinfo.c which takes a component name and a port index as parameters:


#include <stdio.h>
#include <stdlib.h>

#include <OMX_Core.h>
#include <OMX_Component.h>

#include <bcm_host.h>

// OMX_ERRORTYPE err;

OMX_ERRORTYPE get_port_info(OMX_HANDLETYPE handle,
			    OMX_PARAM_PORTDEFINITIONTYPE *portdef) {
    return  OMX_GetParameter(handle, 
			     OMX_IndexParamPortDefinition, 
			     portdef);

}

void print_port_info(OMX_PARAM_PORTDEFINITIONTYPE *portdef) {
    char *domain;

    printf("Port %d\n", portdef->nPortIndex);
    if (portdef->eDir ==  OMX_DirInput) {
	printf("  is input port\n");
    } else {
	printf("  is output port\n");
    }

    switch (portdef->eDomain) {
    case OMX_PortDomainAudio: domain = "Audio"; break;
    case OMX_PortDomainVideo: domain = "Video"; break;
    case OMX_PortDomainImage: domain = "Image"; break;
    case OMX_PortDomainOther: domain = "Other"; break;
    }
    printf("  Domain is %s\n", domain);

    printf("  Buffer count %d\n", portdef->nBufferCountActual);
    printf("  Buffer minimum count %d\n", portdef->nBufferCountMin);
    printf("  Buffer size %d bytes\n", portdef->nBufferSize);
}

OMX_CALLBACKTYPE callbacks  = { .EventHandler = NULL,
                                .EmptyBufferDone = NULL,
                                .FillBufferDone = NULL
};

int main(int argc, char** argv) {

    int i;
    char componentName[128]; // min space required see /opt/vc/include/IL/OMX_Core.h
                             // thanks to Peter Maersk-Moller
    OMX_ERRORTYPE err;
    OMX_HANDLETYPE handle;
    OMX_PARAM_PORTDEFINITIONTYPE portdef;
    OMX_VERSIONTYPE specVersion, compVersion;
    OMX_UUIDTYPE uid;
    int portindex;

    if (argc < 3) {
	fprintf(stderr, "Usage: %s component-name port-index\n", argv[0]);
	exit(1);
    }
    strncpy(componentName, argv[1], 128);
    portindex = atoi(argv[2]);

    bcm_host_init();

    err = OMX_Init();
    if(err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_Init() failed\n", 0);
	exit(1);
    }
    /** Ask the core for a handle to the component
     */
    err = OMX_GetHandle(&handle, componentName,
			// the next two fields are discussed later 
			NULL, &callbacks);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_GetHandle failed\n", 0);
	exit(1);
    }

    // Get some version info
    err = OMX_GetComponentVersion(handle, componentName, 
				  &compVersion, &specVersion, 
				  &uid);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_GetComponentVersion failed\n", 0);
	exit(1);
    }
    printf("Component name: %s version %d.%d, Spec version %d.%d\n",
	   componentName, compVersion.s.nVersionMajor,
	   compVersion.s.nVersionMinor,
	   specVersion.s.nVersionMajor,
	   specVersion.s.nVersionMinor);

    memset(&portdef, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    portdef.nVersion.nVersion = OMX_VERSION;
    portdef.nPortIndex = portindex;

    if (get_port_info(handle, &portdef) == OMX_ErrorNone) {
	print_port_info(&portdef);
    }
 
    exit(0);
}

      

When this is run say by

	
./portinfo  OMX.broadcom.image_decode 320
	
      

it results in

	
Component name: OMX.broadcom.image_decode:12 version 0.0, Spec version 1.1
Port 320
  is input port
  Domain is Image
  Buffer count 3
  Buffer minimum count 2
  Buffer size 81920 bytes
	
      

Getting information about specific types of port

In the last section we specified the port of a component explicitly. We aren't likely to sit there with the specification handy, just to input port numbers. We want to be able to determine valid port numbers programmatically.

Unfortunately, we can't just ask for a list of valid ports. What we can do is ask for a list of audio ports, a list of video ports, a list of image ports and a list of valid other ports.

Getting such a list is done using a new data structure, the OMX_PORT_PARAM_TYPE . This is described in the file OMX_Core.h and is pretty simple

	
typedef struct OMX_PORT_PARAM_TYPE {
    OMX_U32 nSize;              /** size of the structure in bytes */
    OMX_VERSIONTYPE nVersion;   /** OMX specification version information */
    OMX_U32 nPorts;             /** The number of ports for this component */
    OMX_U32 nStartPortNumber;   /** first port number for this type of port */
} OMX_PORT_PARAM_TYPE; 
	
      

This structure is filled using a call to OMX_GetParameter as usual, but with an index appropriate to the port type you want. These are

as in

	
OMX_PORT_PARAM_TYPE param;

err = OMX_GetParameter(handle, 
                       OMX_IndexParamVideoInit, 
                       &param);
	
      

to get the video ports. Note that within each type of port, the values are consecutive. For example the video_splitter has five video ports starting at 250, so the port numbers are 250 through 254.

Note that all that this does is to get the range of port numbers for a particular type of port. If the number of ports returned is zero, there are no ports of this type. Also, to get actual information about each port you still have to make a call to

	
OMX_PARAM_PORTDEFINITIONTYPE portdef;

OMX_GetParameter(handle, 
	         OMX_IndexParamPortDefinition, 
		 &portdef)
	
      

Detailed audio port information

Each type of port (audio, video, image or other) has a data structure for information specific to that type. For an audio port, the type is OMX_AUDIO_PORTDEFINITIONTYPE and similar for the other types.

For an audio port, this information is returned as one of the union types in the OMX_PARAM_PORTDEFINITIONTYPE and can be filled in a call to

	
OMX_GetParameter(handle, 
	         OMX_IndexParamPortDefinition, 
		 &portdef)
	
      

as in the previous program.

The information we want is the audio port information within the general port information. This part of the structure is

	
portdef.format.audio
	
      

(remember, the audio port information is in a union with tag format and field audio).

The OMX_AUDIO_PORTDEFINITIONTYPE type is described in Section 4.1.5 of the 1.1.2 specification and has two important fields

	
OMX_STRING cMIMEType;
OMX_AUDIO_CODINGTYPE eEncoding;
	
      

On the RPi, the MIMEType is NULL which it shouldn't really be. I don't think it will get fixed.

The encoding is an enumerated data type. There are a large number of possible values, given in Section 4.1.3 of the 1.1.2 specification. The types include PCM (pulse code modulated), AAC, MP3, Vorbis and WMA. These are also defined in the header file /opt/vc/include/IL/OMX_Audio.h

Here is where it gets a bit more interesting: that header file not only defines the "standard" OMX audio coding types but also defines an extra set: FLAC, DDP, DTS etc (none of which I have heard of). They are defined as part of the OMX_AUDIO_CODINGTYPE enumeration, in the "Reserved region for introducing Vendor Extensions". In other words, perfectly legitimate, but not standardised.

Using the OMX_PARAM_PORTDEFINITIONTYPE we get from querying the port for general information we can query for the audio types supported by

	
void getAudioPortInformation(int nPort, OMX_PARAM_PORTDEFINITIONTYPE sPortDef) {
    printf("Port %d requires %d buffers\n", nPort, sPortDef.nBufferCountMin); 
    printf("Port %d has min buffer size %d bytes\n", nPort, sPortDef.nBufferSize); 
    
    if (sPortDef.eDir == OMX_DirInput) {
	printf("Port %d is an input port\n", nPort);
    } else {
	printf("Port %d is an output port\n",  nPort);
    }
    switch (sPortDef.eDomain) {
    case OMX_PortDomainAudio:
	printf("Port %d is an audio port\n", nPort);
	printf("Port mimetype %s\n",
	       sPortDef.format.audio.cMIMEType);

	switch (sPortDef.format.audio.eEncoding) {
	case OMX_AUDIO_CodingPCM:
	    printf("Port encoding is PCM\n");
	    break; 
	case OMX_AUDIO_CodingVORBIS:
	    printf("Port encoding is Ogg Vorbis\n");
	    break; 
	case OMX_AUDIO_CodingMP3:
	    printf("Port encoding is MP3\n");
	    break; 
	default:
	    printf("Port encoding is not PCM or MP3 or Vorbis, is %d\n",
		   sPortDef.format.audio.eEncoding);
	}
	getSupportedAudioFormats(nPort);

	break;
	/* could put other port types here */
    default:
	printf("Port %d is not an audio port\n",  nPort);
    }    
}
	
      

But now we can go much deeper. If the port can support MP3 data, what variations on MP3 does it support? For example, MP3 files can have different sampling rates (48khz, 44.1khz, etc), number of bits per sample (16, 24, etc) and number of channels (1, 2, 5, etc). These can all be queried by - deep breath! - another set of data types.

The first type is the OMX_AUDIO_PARAM_PORTFORMATTYPE (see Section 4.1.6 of the 1.1.2 specification). It is quite simple

	
typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE {
    OMX_U32 nSize;
    OMX_VERSIONTYPE nVersion;
    OMX_U32 nPortIndex;
    OMX_U32 nIndex;
    OMX_AUDIO_CODINGTYPE eEncoding;
} OMX_AUDIO_PARAM_PORTFORMATTYPE;
	
      

The first two fields are common to all OpenMAX structs, size and version. The third is the port index we are looking at. The fifth is the encoding: PCM, MP3, Vorbis, etc. The new one is the fourth: the index.

We know from the OMX_PARAM_PORTDEFINITIONTYPE field portdef.format.audio.eEncoding that the port will support a single audio type such as PCM. But it may also support more, such as MP3 or AAC. That's what the index is for, for the different types of audio data. The index starts at zero, and keeps increasing until we get an error trying to get parameters with that index value.

So we start with a struct of type OMX_PARAM_PORTDEFINITIONTYPE and set the index to zero. We then keep asking for parameters with an OMX_IndexParamAudioPortFormat index to OMX_GetParameter. Each time round we increase the index by one until OMX_GetParameter returns an error. On each iteration, we get a new supported audio type.

For example, on the RPi. the audio_render component has one input port which suports PCM and DDT data. We will see the code in just a minute.

Well, if we now know that PCM is supported, we can give further and ask for what parameters it supports. Before doing that, here is the code to list the formats and call for this further level of detail:

	
void getSupportedAudioFormats(int indentLevel, int portNumber) {
    OMX_AUDIO_PARAM_PORTFORMATTYPE sAudioPortFormat;

    setHeader(&sAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
    sAudioPortFormat.nIndex = 0;
    sAudioPortFormat.nPortIndex = portNumber;

    printf("Supported audio formats are:\n");
    for(;;) {
        err = OMX_GetParameter(handle, 
                               OMX_IndexParamAudioPortFormat, 
                               &sAudioPortFormat);
        if (err == OMX_ErrorNoMore) {
	    printf("No more formats supported\n");
	    return;
        }

	/* This shouldn't occur, but does with Broadcom library */
	if (sAudioPortFormat.eEncoding == OMX_AUDIO_CodingUnused) {
	     printf("No coding format returned\n");
	     return;
	}

	switch (sAudioPortFormat.eEncoding) {
	case OMX_AUDIO_CodingPCM:
	    printf("Supported encoding is PCM\n");
	    getPCMInformation(portNumber);
	    break; 
	case OMX_AUDIO_CodingVORBIS:
	    printf("Supported encoding is Ogg Vorbis\n");
	    break; 
	case OMX_AUDIO_CodingMP3:
	    printf("Supported encoding is MP3\n");
	    getMP3Information(portNumber);
	    break;
#ifdef RASPBERRY_PI
	case OMX_AUDIO_CodingFLAC:
	    printf("Supported encoding is FLAC\n");
	    break; 
	case OMX_AUDIO_CodingDDP:
	    printf("Supported encoding is DDP\n");
	    break; 
	case OMX_AUDIO_CodingDTS:
	    printf("Supported encoding is DTS\n");
	    break; 
	case OMX_AUDIO_CodingWMAPRO:
	    printf("Supported encoding is WMAPRO\n");
	    break; 
	case OMX_AUDIO_CodingATRAC3:
	    printf("Supported encoding is ATRAC3\n");
	    break;
	case OMX_AUDIO_CodingATRACX:
	    printf("Supported encoding is ATRACX\n");
	    break;
	case OMX_AUDIO_CodingATRACAAL:
	    printf("Supported encoding is ATRACAAL\n");
	    break;
#endif
	case OMX_AUDIO_CodingAAC:
	    printf("Supported encoding is AAC\n");
	    break; 
	case OMX_AUDIO_CodingWMA:
	    printf("Supported encoding is WMA\n");
	    break;
	case OMX_AUDIO_CodingRA:
	    printf("Supported encoding is RA\n");
	    break; 
	case OMX_AUDIO_CodingAMR:
	    printf("Supported encoding is AMR\n");
	    break; 
	case OMX_AUDIO_CodingEVRC:
	    printf("Supported encoding is EVRC\n");
	    break;
	case OMX_AUDIO_CodingG726:
	    printf("Supported encoding is G726\n");
	    break;
	case OMX_AUDIO_CodingMIDI:
	    printf("Supported encoding is MIDI\n");
	    break;
	default:
	    printf("Supported encoding is not PCM or MP3 or Vorbis, is 0x%X\n",
		  sAudioPortFormat.eEncoding);
	}
        sAudioPortFormat.nIndex++;
    }
}
	
      

So to finally get down to the detail level, we need to look at the functions we define such as getPCMInformation, getMP3Information, etc.

We shall just look at PCM. Other types can be looked at in a similar way. Section 4.1.7 of the 1.1.2 specification defines the struct OMX_AUDIO_PARAM_PCMMODETYPE:

	
typedef struct OMX_AUDIO_PARAM_PCMMODETYPE {
    OMX_U32 nSize;
    OMX_VERSIONTYPE nVersion;
    OMX_U32 nPortIndex;
    OMX_U32 nChannels;
    OMX_NUMERICALDATATYPE eNumData;
    OMX_ENDIANTYPE eEndian;
    OMX_BOOL bInterleaved;
    OMX_U32 nBitPerSample;
    OMX_U32 nSamplingRate;
    OMX_AUDIO_PCMMODETYPE ePCMMode;
    OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS];
} OMX_AUDIO_PARAM_PCMMODETYPE;
	
      

The index to lookup this struct is OMX_IndexParamAudioPcm. (The full list of indices and data types for audio is in Table 4.2, for video is Table 4-45 and Table 4-65 for images.)

Code to get this information is

	
void getPCMInformation(int portNumber) {
    /* assert: PCM is a supported mode */
    OMX_AUDIO_PARAM_PCMMODETYPE sPCMMode;

    /* set it into PCM format before asking for PCM info */
    if (setEncoding(portNumber, OMX_AUDIO_CodingPCM) != OMX_ErrorNone) {
	fprintf(stderr, "Error in setting coding to PCM\n");
	return;
    }
       
    setHeader(&sPCMMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
    sPCMMode.nPortIndex = portNumber;
    err = OMX_GetParameter(handle, OMX_IndexParamAudioPcm, &sPCMMode);
    if(err != OMX_ErrorNone){
	printf("PCM mode unsupported\n");
    } else {
	printf("  PCM default sampling rate %d\n", sPCMMode.nSamplingRate);
	printf("  PCM default bits per sample %d\n", sPCMMode.nBitPerSample);
	printf("  PCM default number of channels %d\n", sPCMMode.nChannels);
    }      
}
	
      

A program to dump all of this type of information is info.c

/**
   Based on code
   Copyright (C) 2007-2009 STMicroelectronics
   Copyright (C) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
   under the LGPL
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>

#include <OMX_Core.h>
#include <OMX_Component.h>
#include <OMX_Types.h>
#include <OMX_Audio.h>

#ifdef RASPBERRY_PI
#include <bcm_host.h>
#endif

OMX_ERRORTYPE err;
OMX_HANDLETYPE handle;
OMX_VERSIONTYPE specVersion, compVersion;

OMX_CALLBACKTYPE callbacks;

#define indent {int n = 0; while (n++ < indentLevel*2) putchar(' ');}

static void setHeader(OMX_PTR header, OMX_U32 size) {
    /* header->nVersion */
    OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)(header + sizeof(OMX_U32));
    /* header->nSize */
    *((OMX_U32*)header) = size;

    /* for 1.2
       ver->s.nVersionMajor = OMX_VERSION_MAJOR;
       ver->s.nVersionMinor = OMX_VERSION_MINOR;
       ver->s.nRevision = OMX_VERSION_REVISION;
       ver->s.nStep = OMX_VERSION_STEP;
    */
    ver->s.nVersionMajor = specVersion.s.nVersionMajor;
    ver->s.nVersionMinor = specVersion.s.nVersionMinor;
    ver->s.nRevision = specVersion.s.nRevision;
    ver->s.nStep = specVersion.s.nStep;
}

void printState() {
    OMX_STATETYPE state;
    err = OMX_GetState(handle, &state);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "Error on getting state\n");
	exit(1);
    }
    switch (state) {
    case OMX_StateLoaded: fprintf(stderr, "StateLoaded\n"); break;
    case OMX_StateIdle: fprintf(stderr, "StateIdle\n"); break;
    case OMX_StateExecuting: fprintf(stderr, "StateExecuting\n"); break;
    case OMX_StatePause: fprintf(stderr, "StatePause\n"); break;
    case OMX_StateWaitForResources: fprintf(stderr, "StateWiat\n"); break;
    default:  fprintf(stderr, "State unknown\n"); break;
    }
}

OMX_ERRORTYPE setEncoding(int portNumber, OMX_AUDIO_CODINGTYPE encoding) {
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;

    setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    sPortDef.nPortIndex = portNumber;
    sPortDef.nPortIndex = portNumber;
    err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
    if(err != OMX_ErrorNone){
        fprintf(stderr, "Error in getting OMX_PORT_DEFINITION_TYPE parameter\n",
 0);
        exit(1);
    }

    sPortDef.format.audio.eEncoding = encoding;
    sPortDef.nBufferCountActual = sPortDef.nBufferCountMin;

    err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
    return err;
}

void getPCMInformation(int indentLevel, int portNumber) {
    /* assert: PCM is a supported mode */
    OMX_AUDIO_PARAM_PCMMODETYPE sPCMMode;

    /* set it into PCM format before asking for PCM info */
    if (setEncoding(portNumber, OMX_AUDIO_CodingPCM) != OMX_ErrorNone) {
	fprintf(stderr, "Error in setting coding to PCM\n");
	return;
    }
       
    setHeader(&sPCMMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
    sPCMMode.nPortIndex = portNumber;
    err = OMX_GetParameter(handle, OMX_IndexParamAudioPcm, &sPCMMode);
    if(err != OMX_ErrorNone){
	indent printf("PCM mode unsupported\n");
    } else {
	indent printf("  PCM default sampling rate %d\n", sPCMMode.nSamplingRate);
	indent printf("  PCM default bits per sample %d\n", sPCMMode.nBitPerSample);
	indent printf("  PCM default number of channels %d\n", sPCMMode.nChannels);
    }      

    /*
    setHeader(&sAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
    sAudioPortFormat.nIndex = 0;
    sAudioPortFormat.nPortIndex = portNumber;
    */

    
}
void getMP3Information(int indentLevel, int portNumber) {
    /* assert: MP3 is a supported mode */
    OMX_AUDIO_PARAM_MP3TYPE sMP3Mode;

    /* set it into MP3 format before asking for MP3 info */
    if (setEncoding(portNumber, OMX_AUDIO_CodingMP3) != OMX_ErrorNone) {
	fprintf(stderr, "Error in setting coding to MP3\n");
	return;
    }
    
    setHeader(&sMP3Mode, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
    sMP3Mode.nPortIndex = portNumber;
    err = OMX_GetParameter(handle, OMX_IndexParamAudioMp3, &sMP3Mode);
    if(err != OMX_ErrorNone){
	indent printf("MP3 mode unsupported\n");
    } else {
	indent printf("  MP3 default sampling rate %d\n", sMP3Mode.nSampleRate);
	indent printf("  MP3 default bits per sample %d\n", sMP3Mode.nBitRate);
	indent printf("  MP3 default number of channels %d\n", sMP3Mode.nChannels);
    }   
}

void getSupportedImageFormats(int indentLevel, int portNumber) {
    OMX_IMAGE_PARAM_PORTFORMATTYPE sImagePortFormat;

    setHeader(&sImagePortFormat, sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE));
    sImagePortFormat.nIndex = 0;
    sImagePortFormat.nPortIndex = portNumber;

#ifdef LIM
    printf("LIM doesn't set image formats properly\n");
    return;
#endif

    indent printf("Supported image formats are:\n");
    indentLevel++;
    for(;;) {
        err = OMX_GetParameter(handle, OMX_IndexParamImagePortFormat, &sImagePortFormat);
        if (err == OMX_ErrorNoMore) {
	    indent printf("No more formats supported\n");
	    return;
        }

	/* This shouldn't occur, but does with Broadcom library */
	if (sImagePortFormat.eColorFormat == OMX_IMAGE_CodingUnused) {
	     indent printf("No coding format returned\n");
	     return;
	}

	indent printf("Image format compression format 0x%X\n", 
		      sImagePortFormat.eCompressionFormat);
	indent printf("Image format color encoding 0x%X\n", 
		      sImagePortFormat.eColorFormat);
	sImagePortFormat.nIndex++;
    }
}

void getSupportedVideoFormats(int indentLevel, int portNumber) {
    OMX_VIDEO_PARAM_PORTFORMATTYPE sVideoPortFormat;

    setHeader(&sVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    sVideoPortFormat.nIndex = 0;
    sVideoPortFormat.nPortIndex = portNumber;

#ifdef LIM
    printf("LIM doesn't set video formats properly\n");
    return;
#endif

    indent printf("Supported video formats are:\n");
    for(;;) {
        err = OMX_GetParameter(handle, OMX_IndexParamVideoPortFormat, &sVideoPortFormat);
        if (err == OMX_ErrorNoMore) {
	    indent printf("No more formats supported\n");
	    return;
        }

	/* This shouldn't occur, but does with Broadcom library */
	if (sVideoPortFormat.eColorFormat == OMX_VIDEO_CodingUnused) {
	     indent printf("No coding format returned\n");
	     return;
	}

	indent printf("Video format encoding 0x%X\n", 
		      sVideoPortFormat.eColorFormat);
	sVideoPortFormat.nIndex++;
    }
}

void getSupportedAudioFormats(int indentLevel, int portNumber) {
    OMX_AUDIO_PARAM_PORTFORMATTYPE sAudioPortFormat;

    setHeader(&sAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
    sAudioPortFormat.nIndex = 0;
    sAudioPortFormat.nPortIndex = portNumber;

#ifdef LIM
    printf("LIM doesn't set audio formats properly\n");
    return;
#endif

    indent printf("Supported audio formats are:\n");
    for(;;) {
        err = OMX_GetParameter(handle, OMX_IndexParamAudioPortFormat, &sAudioPortFormat);
        if (err == OMX_ErrorNoMore) {
	    indent printf("No more formats supported\n");
	    return;
        }

	/* This shouldn't occur, but does with Broadcom library */
	if (sAudioPortFormat.eEncoding == OMX_AUDIO_CodingUnused) {
	     indent printf("No coding format returned\n");
	     return;
	}

	switch (sAudioPortFormat.eEncoding) {
	case OMX_AUDIO_CodingPCM:
	    indent printf("Supported encoding is PCM\n");
	    getPCMInformation(indentLevel+1, portNumber);
	    break; 
	case OMX_AUDIO_CodingVORBIS:
	    indent printf("Supported encoding is Ogg Vorbis\n");
	    break; 
	case OMX_AUDIO_CodingMP3:
	    indent printf("Supported encoding is MP3\n");
	    getMP3Information(indentLevel+1, portNumber);
	    break;
#ifdef RASPBERRY_PI
	case OMX_AUDIO_CodingFLAC:
	    indent printf("Supported encoding is FLAC\n");
	    break; 
	case OMX_AUDIO_CodingDDP:
	    indent printf("Supported encoding is DDP\n");
	    break; 
	case OMX_AUDIO_CodingDTS:
	    indent printf("Supported encoding is DTS\n");
	    break; 
	case OMX_AUDIO_CodingWMAPRO:
	    indent printf("Supported encoding is WMAPRO\n");
	    break; 
	case OMX_AUDIO_CodingATRAC3:
	    indent printf("Supported encoding is ATRAC3\n");
	    break;
	case OMX_AUDIO_CodingATRACX:
	    indent printf("Supported encoding is ATRACX\n");
	    break;
	case OMX_AUDIO_CodingATRACAAL:
	    indent printf("Supported encoding is ATRACAAL\n");
	    break;
#endif
	case OMX_AUDIO_CodingAAC:
	    indent printf("Supported encoding is AAC\n");
	    break; 
	case OMX_AUDIO_CodingWMA:
	    indent printf("Supported encoding is WMA\n");
	    break;
	case OMX_AUDIO_CodingRA:
	    indent printf("Supported encoding is RA\n");
	    break; 
	case OMX_AUDIO_CodingAMR:
	    indent printf("Supported encoding is AMR\n");
	    break; 
	case OMX_AUDIO_CodingEVRC:
	    indent printf("Supported encoding is EVRC\n");
	    break;
	case OMX_AUDIO_CodingG726:
	    indent printf("Supported encoding is G726\n");
	    break;
	case OMX_AUDIO_CodingMIDI:
	    indent printf("Supported encoding is MIDI\n");
	    break;

	    /*
	case OMX_AUDIO_Coding:
	    indent printf("Supported encoding is \n");
	    break;
	    */
	default:
	    indent printf("Supported encoding is not PCM or MP3 or Vorbis, is 0x%X\n",
		  sAudioPortFormat.eEncoding);
	}
        sAudioPortFormat.nIndex++;
    }
}



void getAudioPortInformation(int indentLevel, int nPort, OMX_PARAM_PORTDEFINITIONTYPE sPortDef) {
    indent printf("Port %d requires %d buffers\n", nPort, sPortDef.nBufferCountMin); 
    indent printf("Port %d has min buffer size %d bytes\n", nPort, sPortDef.nBufferSize); 
    
    if (sPortDef.eDir == OMX_DirInput) {
	indent printf("Port %d is an input port\n", nPort);
    } else {
	indent printf("Port %d is an output port\n",  nPort);
    }
    switch (sPortDef.eDomain) {
    case OMX_PortDomainAudio:
	indent printf("Port %d is an audio port\n", nPort);
	indent printf("Port mimetype %s\n",
	       sPortDef.format.audio.cMIMEType);

	switch (sPortDef.format.audio.eEncoding) {
	case OMX_AUDIO_CodingPCM:
	    indent printf("Port encoding is PCM\n");
	    break; 
	case OMX_AUDIO_CodingVORBIS:
	    indent printf("Port encoding is Ogg Vorbis\n");
	    break; 
	case OMX_AUDIO_CodingMP3:
	    indent printf("Port encoding is MP3\n");
	    break; 
	default:
	    indent printf("Port encoding is not PCM or MP3 or Vorbis, is %d\n",
		   sPortDef.format.audio.eEncoding);
	}
	getSupportedAudioFormats(indentLevel+1, nPort);

	break;
	/* could put other port types here */
    default:
	indent printf("Port %d is not an audio port\n",  nPort);
    }    
}

void getAllAudioPortsInformation(int indentLevel) {
    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;

    int startPortNumber;
    int nPorts;
    int n;

    setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));

    err = OMX_GetParameter(handle, OMX_IndexParamAudioInit, &param);
    if(err != OMX_ErrorNone){
	fprintf(stderr, "Error in getting audio OMX_PORT_PARAM_TYPE parameter\n", 0);
	return;
    }
    indent printf("Audio ports:\n");
    indentLevel++;

    startPortNumber = param.nStartPortNumber;
    nPorts = param.nPorts;
    if (nPorts == 0) {
	indent printf("No ports of this type\n");
	return;
    }

    indent printf("Ports start on %d\n", startPortNumber);
    indent printf("There are %d open ports\n", nPorts);


    for (n = 0; n < nPorts; n++) {
	setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	sPortDef.nPortIndex = startPortNumber + n;
	err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
	if(err != OMX_ErrorNone){
	    fprintf(stderr, "Error in getting OMX_PORT_DEFINITION_TYPE parameter\n", 0);
	    exit(1);
	}
	indent printf("Port %d has %d buffers of size %d\n",
		      sPortDef.nPortIndex,
		      sPortDef.nBufferCountActual,
		      sPortDef.nBufferSize);
	indent printf("Direction is %s\n", 
		      (sPortDef.eDir == OMX_DirInput ? "input" : "output"));
	getAudioPortInformation(indentLevel+1, startPortNumber + n, sPortDef);
    }
}

void getAllVideoPortsInformation(int indentLevel) {
    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
    int startPortNumber;
    int nPorts;
    int n;

    setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));

    err = OMX_GetParameter(handle, OMX_IndexParamVideoInit, &param);
    if(err != OMX_ErrorNone){
	fprintf(stderr, "Error in getting video OMX_PORT_PARAM_TYPE parameter\n", 0);
	return;
    }

    printf("Video ports:\n");
    indentLevel++;

    startPortNumber = param.nStartPortNumber;
    nPorts = param.nPorts;
    if (nPorts == 0) {
	indent printf("No ports of this type\n");
	return;
    }

    indent printf("Ports start on %d\n", startPortNumber);
    indent printf("There are %d open ports\n", nPorts);


    for (n = 0; n < nPorts; n++) {
	setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	sPortDef.nPortIndex = startPortNumber + n;
	err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
	if(err != OMX_ErrorNone){
	    fprintf(stderr, "Error in getting OMX_PORT_DEFINITION_TYPE parameter\n", 0);
	    exit(1);
	}
	//getVideoPortInformation(indentLevel+1, startPortNumber + n, sPortDef);
	indent printf("Port %d has %d buffers (minimum %d) of size %d\n",
		      sPortDef.nPortIndex,
		      sPortDef.nBufferCountActual,
		      sPortDef.nBufferCountMin,
		      sPortDef.nBufferSize);
	indent printf("Direction is %s\n", 
		      (sPortDef.eDir == OMX_DirInput ? "input" : "output"));
	
	getSupportedVideoFormats(indentLevel+1,  startPortNumber + n);
    }
}

void getAllImagePortsInformation(int indentLevel) {
    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
    int startPortNumber;
    int nPorts;
    int n;

    setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));

    err = OMX_GetParameter(handle, OMX_IndexParamImageInit, &param);
    if(err != OMX_ErrorNone){
	fprintf(stderr, "Error in getting image OMX_PORT_PARAM_TYPE parameter\n", 0);
	return;
    }
    printf("Image ports:\n");
    indentLevel++;

    startPortNumber = param.nStartPortNumber;
    nPorts = param.nPorts;
    if (nPorts == 0) {
	indent printf("No ports of this type\n");
	return;
    }

    indent printf("Ports start on %d\n", startPortNumber);
    indent printf("There are %d open ports\n", nPorts);



    for (n = 0; n < nPorts; n++) {
	setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	sPortDef.nPortIndex = startPortNumber + n;
	err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
	if(err != OMX_ErrorNone){
	    fprintf(stderr, "Error in getting OMX_PORT_DEFINITION_TYPE parameter\n", 0);
	    exit(1);
	}

	indent printf("Port %d has %d buffers (minimum %d) of size %d\n",
		      sPortDef.nPortIndex,
		      sPortDef.nBufferCountActual,
		      sPortDef.nBufferCountMin,
		      sPortDef.nBufferSize);
	indent printf("Direction is %s\n", 
		      (sPortDef.eDir == OMX_DirInput ? "input" : "output"));

	//getImagePortInformation(indentLevel+1, startPortNumber + n, sPortDef);
	getSupportedImageFormats(indentLevel+1,  startPortNumber + n);
    }
}

void getAllOtherPortsInformation(int indentLevel) {
    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
    int startPortNumber;
    int nPorts;
    int n;

    setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));

    err = OMX_GetParameter(handle, OMX_IndexParamOtherInit, &param);
    if(err != OMX_ErrorNone){
	fprintf(stderr, "Error in getting other OMX_PORT_PARAM_TYPE parameter\n", 0);
	exit(1);
    }
    printf("Other ports:\n");
    indentLevel++;

    startPortNumber = param.nStartPortNumber;
    nPorts = param.nPorts;
    if (nPorts == 0) {
	indent printf("No ports of this type\n");
	return;
    }

    indent printf("Ports start on %d\n", startPortNumber);
    indent printf("There are %d open ports\n", nPorts);

    indent printf("Port %d has %d buffers of size %d\n",
		  sPortDef.nPortIndex,
		  sPortDef.nBufferCountActual,
		  sPortDef.nBufferSize);
    indent printf("Direction is %s\n", 
		  (sPortDef.eDir == OMX_DirInput ? "input" : "output"));
}

void getAllPortsInformation(int indentLevel) {
    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
    int startPortNumber;
    int nPorts;
    int n;

    setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));

    err = OMX_GetParameter(handle, OMX_IndexParamVideoInit, &param);
    if(err != OMX_ErrorNone){
	fprintf(stderr, "Error in getting video OMX_PORT_PARAM_TYPE parameter\n", 0);
	return;
    }

    printf("Video ports:\n");
    indentLevel++;

    startPortNumber = param.nStartPortNumber;
    nPorts = param.nPorts;
    if (nPorts == 0) {
	indent printf("No ports of this type\n");
	return;
    }

    indent printf("Ports start on %d\n", startPortNumber);
    indent printf("There are %d open ports\n", nPorts);

    for (n = 0; n < nPorts; n++) {
	setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	sPortDef.nPortIndex = startPortNumber + n;
	err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
	if(err != OMX_ErrorNone){
	    fprintf(stderr, "Error in getting OMX_PORT_DEFINITION_TYPE parameter\n", 0);
	    exit(1);
	}
	indent printf("Port %d has %d buffers of size %d\n",
		      sPortDef.nPortIndex,
		      sPortDef.nBufferCountActual,
		      sPortDef.nBufferSize);
	indent printf("Direction is %s\n", 
		      (sPortDef.eDir == OMX_DirInput ? "input" : "output"));
	switch (sPortDef.eDomain) {
	case  OMX_PortDomainVideo:
	    indent printf("Domain is video\n");
	    getSupportedVideoFormats(indentLevel+1,  startPortNumber + n);
	    break;
	case  OMX_PortDomainImage:
	    indent printf("Domain is image\n");
	    getSupportedImageFormats(indentLevel+1,  startPortNumber + n);
	    break;
	case  OMX_PortDomainAudio:
	    indent printf("Domain is audio\n");
	    getSupportedAudioFormats(indentLevel+1,  startPortNumber + n);
	    break;
	case  OMX_PortDomainOther:
	    indent printf("Domain is other\n");
	    // getSupportedOtherFormats(indentLevel+1,  startPortNumber + n);
	    break;
	}
	//getVideoPortInformation(indentLevel+1, startPortNumber + n, sPortDef);
	/*
	if (sPortDef.eDomain == OMX_PortDomainVideo)
	    getSupportedVideoFormats(indentLevel+1,  startPortNumber + n);
	else
	    indent printf("Not a video port\n");
	*/
    }
}

int main(int argc, char** argv) {

    OMX_PORT_PARAM_TYPE param;
    OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
    OMX_AUDIO_PORTDEFINITIONTYPE sAudioPortDef;
    OMX_AUDIO_PARAM_PORTFORMATTYPE sAudioPortFormat;
    OMX_AUDIO_PARAM_PCMMODETYPE sPCMMode;

#ifdef RASPBERRY_PI
    //char *componentName = "OMX.broadcom.audio_mixer";
    //char *componentName = "OMX.broadcom.audio_mixer";
    char *componentName = "OMX.broadcom.video_render";
#else
#ifdef LIM
    char *componentName = "OMX.limoi.alsa_sink";
#else
    char *componentName = "OMX.st.volume.component";
#endif
#endif
    unsigned char name[128]; /* spec says 128 is max name length */
    OMX_UUIDTYPE uid;
    int startPortNumber;
    int nPorts;
    int n;

    /* ovveride component name by command line argument */
    if (argc == 2) {
	componentName = argv[1];
    }

# ifdef RASPBERRY_PI
    bcm_host_init();
# endif

    err = OMX_Init();
    if(err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_Init() failed\n", 0);
	exit(1);
    }
    /** Ask the core for a handle to the volume control component
     */
    err = OMX_GetHandle(&handle, componentName, NULL /*app private data */, &callbacks);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_GetHandle failed\n", 0);
	exit(1);
    }
    err = OMX_GetComponentVersion(handle, name, &compVersion, &specVersion, &uid);
    if (err != OMX_ErrorNone) {
	fprintf(stderr, "OMX_GetComponentVersion failed\n", 0);
	exit(1);
    }
    printf("Component name: %s version %d.%d, Spec version %d.%d\n",
	   name, compVersion.s.nVersionMajor,
	   compVersion.s.nVersionMinor,
	   specVersion.s.nVersionMajor,
	   specVersion.s.nVersionMinor);

    /** Get  ports information */
    //getAllPortsInformation(0);

    
    getAllAudioPortsInformation(0);
    getAllVideoPortsInformation(0);
    getAllImagePortsInformation(0);
    getAllOtherPortsInformation(0);
   

    exit(0);
}

      

Conclusion

In this chapter we have looked at how to get information about OpenMAX components. So far it isn't hard, just extremely voluminous due to the complexities and variations among all the components supported.


      

Copyright © Jan Newmarch, jan@newmarch.name
Creative Commons License
" Programming AudioVideo on the Raspberry Pi GPU " by Jan Newmarch is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License .
Based on a work at https://jan.newmarch.name/RPi/ .

If you like this book, please contribute using PayPal

Or Flattr me:
Flattr this book