OpenMAX IL Programming

This topic describes how to develop a custom IL client application that directly uses the OpenMAX IL API to control codec components.

Determine Role Support

Before loading a component, the IL client must verify that the OMX core supports the required role. Call OMX_GetRolesOfComponent to enumerate the roles supported by a given component name. If no component supports the given role, the output parameter for OMX_GetRolesOfComponent is 0.

The following diagram shows the role support determination workflow.
Figure 1. Role Support Determination Workflow

Load Component

After confirming role support, the IL client loads the component by calling OMX_GetHandle. This call dynamically loads the component library and initializes the component into the Loaded state. The client also registers callback functions — FillBufferDone, EmptyBufferDone, and EventHandler — to receive asynchronous notifications from the component.

The following diagram shows the component loading workflow.
Figure 2. Component Loading Workflow

Component Handshake

After acquiring the component handle, the IL client must initialize and configure the component by retrieving and setting port definitions.

  1. Call OMX_GetParameter with OMX_IndexVideoInit to retrieve the number of ports supported by the component and the base port index.

  2. The component returns the port count and base index.

  3. For each port, call OMX_GetParameter to retrieve port configuration, including preferred buffer size and number of buffers.

  4. Call OMX_SetParameter to configure each port with the desired settings (either the retrieved defaults or custom values).

The following diagram shows the component handshake workflow.
Figure 3. Component Handshake Workflow

Configure Decoder Parameters

The OMX IL component accepts codec-specific parameters beyond the mandatory port configuration, such as input frame dimensions, target frame rate, and target bit rate.

  1. Call OMX_GetParameter to retrieve the current parameter configuration.

  2. Call OMX_SetParameter with the appropriate OMX_Index to set custom parameters. This must be done before sending any input data via OMX_EmptyThisBuffer.

The following diagram shows the decoder parameter configuration workflow.
Figure 4. Decoder Parameter Configuration Workflow

Color Format Configuration

The decoder supports a proprietary color format and requires an additional configuration step:
  1. Query the component for supported color formats in a loop until the component returns OMX_ErrorNoMore.

  2. Index 0 is reserved for YUV420PackedSemiPlanar (NV12) — this is the default color format used to configure the component.

The following diagram shows the decoder color format configuration workflow.
Figure 5. Decoder Color Format Configuration Workflow

Allocate Buffer

After the component is configured, the IL client allocates buffers to transition the component from the Loaded state to the Idle state. Hardware components use physical memory for output buffers to interface with the VPU, so the client uses the AllocateBuffer model for the output port.

  1. Initiate the Loaded-to-Idle state transition.

  2. On the input port, call OMX_UseBuffer or OMX_AllocateBuffer for each input buffer in a loop.

  3. On the output port, call OMX_UseBuffer or OMX_AllocateBuffer for each output buffer in a loop.

  4. After all buffers are successfully allocated on both ports, the component generates the OMX_EventCmdComplete event for the Loaded-to-Idle transition, delivered via EventHandlerCallback.

The following diagram shows the buffer allocation workflow.
Figure 6. Buffer Allocation Workflow

Configure Dynamic Port

After buffer allocation, the IL client may need to reconfigure ports dynamically — for example, when the decoder detects a resolution change in the bitstream. The dynamic port configuration workflow allows the client to disable, reconfigure, and re-enable ports at runtime.

The following diagram shows the dynamic port configuration workflow.
Figure 7. Dynamic Port Configuration Workflow

Process Data

When the component is in the Executing state, the IL client can start sending input bitstream for processing.
  1. Transition the component from Idle to Executing.

  2. Wait for OMX_EventCmdComplete confirming the state transition.

  3. Call OMX_FillThisBuffer with output buffers to hold the decoded YUV data.

  4. Call OMX_EmptyThisBuffer with input bitstream data to be decoded.

  5. The component generates EmptyBufferDone callbacks (input buffer consumed) and FillBufferDone callbacks (output buffer filled) to notify the client.

Figure 8. Data Processing Workflow

De-initialize

To de-initialize the OpenMAX core, the IL client must free all active components by transitioning them through the Executing → Idle → Loaded state sequence and releasing all buffers.
  1. Transition the component from Executing to Idle.

  2. Wait for all buffers to be returned by the component via EmptyBufferDone and FillBufferDone callbacks.

  3. The component generates OMX_EventCmdComplete for the Executing-to-Idle transition.

  4. Transition the component from Idle to Loaded.

  5. Free all input and output buffers using OMX_FreeBuffer.

  6. Wait for OMX_EventCmdComplete for the Idle-to-Loaded transition.

  7. Call OMX_FreeHandle to release the component handle.

  8. Call OMX_DeInit to de-initialize the OMX core.

The following diagram shows the de-initialization workflow.
Figure 9. De-Initialization Workflow