NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

OpenMax Development Guide

From Texas Instruments Wiki
Jump to: navigation, search

OpenMax Overview

OpenMAX™ is a royalty-free, cross-platform API that provides comprehensive streaming media codec and application portability by enabling accelerated multimedia components to be developed, integrated and programmed across multiple operating systems and silicon platforms. The OpenMAX API will be shipped with processors to enable library and codec implementers to rapidly and effectively make use of the full acceleration potential of new silicon - regardless of the underlying hardware architecture.

OpenMax layers.JPG

For more information on OpenMax go to www.khronos.org.

Getting Started With OpenMax Development on the DM814x/DM816x

The DM814x/DM816x DaVinci™ Digital Media Processors are highly-integrated, programmable platforms that leverage TI's DaVinci™ technology to meet the processing needs of the following applications: Video Encode/Decode/Transcode/Transrate, Video Security, Video Conferencing, Video Infrastructure, Media Server, and Digital Signage.

This highly integrated SoC introduces a fair amount of complexity from an application development view. Complexities that require addressing are:

  1. Multi-core interprocess communication => indepth understanding of IPC hardware and software
  2. Configuration/Control of Video Accelerators => high level of register and software programming
  3. Memory Manangement => partitioning, alloc/dealloc, queuing/de-queuing

To address these challenges TI has implemented the OpenMax development framework to allow for a standardized and user friendly API. It is the elementary application development framework to configure and control TI's HDVPSS, C67x DSP, and codec accelerators.

The OpenMax implementation simplifies the multi-processor architecture so that developers can create applications entirely on the A8 processor. Other multimedia frameworks (i.e. Gstreamer and Andriod) can leverage OpenMax components and use them simply as plug-ins into their existing frameworks.

OpenMax Components

Each functional block (HW, SW, or a combination) that is required to implement a particular multimedia function, such as video capture and video encode, is represented as a COMPONENT. COMPONENTS are represented as object oriented classes; where base functionality is inherited from the OMX_BASE class and standard APIs are extended to suit the COMPONENT. Available TI OpenMax Components

Video Capture De-Interlacer Noise Filter Video Encoder Video Decoder Scaler Video Display
OMX_VFCC DEI NF VENC VDEC SC VFDC

Instantiating Components

The basic function of a component is to:

  1. Transition to states as directed by the application (i.e. LOAD, IDLE, EXECUTE, PAUSE).
  2. Accept other non-state related commands from the application (i.e. enable/disable ports).
  3. receive input buffers that contain, for example, video or audio frames
  4. receive output buffers where the results of the filtering process is stored
  5. perform filtering on the incoming buffers and store results in output buffers
  6. notify application that input buffer usage is complete
  7. notify application that output buffer has been filled with results and is complete

The process flow described above occurs in a distributed manner by which requests originate on the A8, but the actual processing often occurs on separate processors, in parallel. Also the notification of various completion events occur asynchronous. So the use of callback functions is implementated as part of the OpenMax framework to facilitate the asynchronous flow between the application and components.

The callbacks are provided when the component instance (or handle) is created. As shown in the code snippet below, the input callback structure instance is named "videodeccallbacks", which is set to:

<syntaxhighlight lang='c'> OMX_CALLBACKTYPE videodeccallbacks = {

   .EventHandler = EventHandler,
   .EmptyBufferDone = EmptyBufferDone,
   .FillBufferDone = FillBufferDone

}; </syntaxhighlight>

For the definition of each callback function refer to the complete Code example.

Before any operations can be performed on a particular component, an instance of the component must be created. The following code snippet shows an example of creating an video decode instance.

<syntaxhighlight lang='c'> OMX_HANDLETYPE vdecHandle;

OMX_Init(); OMX_GetHandle(&vdecHandle, // returned pointer to a vdec handle

             "OMX.TI.DUCATI.VIDDEC",  // lookup string for determine the returned component type
              NULL,                   // application date for the component instance
              &videodeccallbacks);    // list of callbacks upon complete of event

</syntaxhighlight>

Note: OMX_Init() - Initiatizes the OMX framework. This MUST be called once before calling any OMX APIs

So then an application writer creates instances of specific COMPONENTS that are required to implement a particular usecase. In the usecase which requires 1) H.264 decode of 1080p frames 2) followed by video down scaling to 720p 3) and finally display to monitor, OMX_GetHandle() must be invoked to create an instance of each.

Component Instances1.jpg

The smaller squares shown in the diagram represent the ports for each component.

Configuring Component I/O Ports

Component attributes, such as port attributes, are assigned to default values during instantiation. The default settings (obtained using OMX_GetParameter()) may not always match what is intended for a particular scenario. Therefore, before transitioning to the OMX_StateIdle state the desired port settings must be set (using OMX_SetParameter method()), followed by port enable (using OMX_SendCommand()). Most components have an input port (except vfcc), which takes as input, buffers to be emptied or consumed, and an output port (except vfdc), which takes as input buffers where the filtered results are stored.

Typical ports settings are


  • Frame Width
  • Frame Height
  • Color Format
  • Number of buffers

Note: in the Code example OMX_GetParameter() is implemented as a macro named OMX_PORT_GET_DEFINITION which invokes OMX_GetParameter() with input parameter nParamIndex set to OMX_IndexParamPortDefinition; similiar was done for OMX_SetParameter() where the marco name is OMX_PORT_SET_DEFINITION.

Buffer Management

The Standard Non-Tunneling design has been implemented for components. This means that the application is notified by the component when the component is done with using a buffer.

The buffer allocation method choosen is application level buffer allocations. So it is the responsibility of the application to allocate buffers and submit them to the individual input/output ports of components.

Often the product of a particular component (i.e. filtered results from the output port), is required as input to the next component in the chain. In this case, the application doesn't need to allocate input buffers for the next component in the chain. Instead, the OMX_UseBuffer() API can be used to pass a pointer to the address of the previous components output buffer as shown in the diagram below.

SNT flow.JPG


Once the buffers have been allocated the component can be transitioned to the OMX_StateExecuting state.

OpenMax APIs

Each TI OMX COMPONENT implements the following methods:

Choosing an Multimedia Development Framework

OpenMax(OMX), Gstreamer(GST), and Android are frameworks that enable application level development of multimedia applications. While this page is dedicated to providing guidance on OMX development, the following document can be used as a guide for selecting the appropriate development framework File:OMX Android GST Comparison.pdf.