アーキテクチャ#
MediaCodec のデコーダーは現在、OMX と Codec2 の 2 つの方法があり、Android は現在、OMX を全面的に置き換えています。
OMX#
オープンメディアアクセラレーション層(Open Media Acceleration、略称は OpenMAX)。組み込みおよびモバイルデバイス上のマルチメディアアプリケーションで音声、映像、画像をキャプチャおよび表示するための無料のクロスプラットフォーム抽象ソフトウェア層です。
レイヤー#
OpenMAX AL (アプリケーションレイヤー)#
OpenMAX-AL は、アプリケーションとマルチメディアミドルウェア間の標準化されたインターフェースを提供し、マルチメディアミドルウェアは期待される API 機能を実行するために必要なサービスを提供します。
The OpenMAX AL 1.1 Reference Guide.
OpenMAX IL (統合レイヤー)#
OpenMAX IL(統合レイヤー)API は、標準化されたメディアコンポーネントインターフェースを定義し、開発者とプラットフォームプロバイダーがハードウェアまたはソフトウェアで実装されたマルチメディアコーデックと統合および通信できるようにします。
OpenMAX DL (開発レイヤー)#
OpenMAX-DL が定義する API には、チップベンダーが新しいプロセッサ上で実装および最適化できる包括的な音声、映像、画像機能のセットが含まれ、コーデックベンダーがさまざまなコーデック機能を書くために使用します。
Android 実装#
主に OpenMax IL レイヤーを実装します:
- コーデックドライバー
- OpenMax IL レイヤーの標準ヘッダーファイルに基づいて異なる機能のコンポーネントを実装し、Android は後に OpenMax の適応層インターフェースをラップして、マルチメディアエンジンが呼び出せるようにします。
OpenMAX IL インターフェースと実装#
// frameworks/native/headers/media_plugin/media/openmax
OMX_Types.h: OpenMax IL のデータ型定義
OMX_Core.h: OpenMax IL コア API
OMX_Compoenet.h: OpenMax IL コンポーネント関連の API
OMX_Audio.h: 音声関連の定数とデータ構造
OMX_IVCommon.h: 画像と映像の共通の定数とデータ構造
OMX_Image.h: 画像関連の定数とデータ構造
OMX_Video.h: 映像関連の定数とデータ構造
OMX_Other.h: その他のデータ構造(av 同期)
OMX_Index.h: OpenMax IL 定義のデータ構造インデックス
OMX_ContentPipe.h コンテンツのパイプ定義
重点的に見るべきは OMX_Compoenet.h
の OMX_COMPONENTTYPE 構造体です。
typedef struct OMX_COMPONENTTYPE
{
/* 構造体のサイズ */
OMX_U32 nSize;
/* バージョン番号 */
OMX_VERSIONTYPE nVersion;
/* コンポーネントのプライベートデータポインタ */
OMX_PTR pComponentPrivate;
/* IL クライアントが設定したポインタ、プライベートデータを保存し、すべてのコールバック関数に返す */
OMX_PTR pApplicationPrivate;
/* コンポーネントのバージョンを取得 */
OMX_ERRORTYPE (*GetComponentVersion)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STRING pComponentName,
OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
OMX_OUT OMX_UUIDTYPE* pComponentUUID);
/* コマンドを送信 */
OMX_ERRORTYPE (*SendCommand)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData);
/* パラメータを取得 */
OMX_ERRORTYPE (*GetParameter)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure);
/* パラメータを設定 */
OMX_ERRORTYPE (*SetParameter)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentParameterStructure);
/* 設定を取得 */
OMX_ERRORTYPE (*GetConfig)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
/* 設定を設定 */
OMX_ERRORTYPE (*SetConfig)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure);
/* OMX 構造のインデックスに変換 */
OMX_ERRORTYPE (*GetExtensionIndex)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_STRING cParameterName,
OMX_OUT OMX_INDEXTYPE* pIndexType);
/* コンポーネントの現在の状態を取得 */
OMX_ERRORTYPE (*GetState)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState);
/* 別のコンポーネントに接続するためのもの */
OMX_ERRORTYPE (*ComponentTunnelRequest)(
OMX_IN OMX_HANDLETYPE hComp,
OMX_IN OMX_U32 nPort,
OMX_IN OMX_HANDLETYPE hTunneledComp,
OMX_IN OMX_U32 nTunneledPort,
OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup);
/* 特定のポートでバッファを使用 */
OMX_ERRORTYPE (*UseBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN OMX_U32 nSizeBytes,
OMX_IN OMX_U8* pBuffer);
/* 特定のポートでバッファを割り当て */
OMX_ERRORTYPE (*AllocateBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN OMX_U32 nSizeBytes);
/* 特定のポートのバッファを解放 */
OMX_ERRORTYPE (*FreeBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/* コンポーネントにこのバッファを消費させる */
OMX_ERRORTYPE (*EmptyThisBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/* コンポーネントにこのバッファを埋めさせる */
OMX_ERRORTYPE (*FillThisBuffer)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
/* コールバック関数を設定 */
OMX_ERRORTYPE (*SetCallbacks)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData);
/* コンポーネントを非初期化 */
OMX_ERRORTYPE (*ComponentDeInit)(
OMX_IN OMX_HANDLETYPE hComponent);
/* EGL イメージを使用 */
OMX_ERRORTYPE (*UseEGLImage)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN void* eglImage);
OMX_ERRORTYPE (*ComponentRoleEnum)(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_U8 *cRole,
OMX_IN OMX_U32 nIndex);
} OMX_COMPONENTTYPE;
OpenMAX アダプタ層#
// frameworks/av/media/libmedia/include/media/IOMX.h
class IOMXNode : public IInterface {
public:
DECLARE_HYBRID_META_INTERFACE(OMXNode, IOmxNode);
typedef IOMX::buffer_id buffer_id;
virtual status_t freeNode() = 0;
virtual status_t sendCommand(
OMX_COMMANDTYPE cmd, OMX_S32 param) = 0;
virtual status_t getParameter(
OMX_INDEXTYPE index, void *params, size_t size) = 0;
virtual status_t setParameter(
OMX_INDEXTYPE index, const void *params, size_t size) = 0;
virtual status_t getConfig(
OMX_INDEXTYPE index, void *params, size_t size) = 0;
virtual status_t setConfig(
OMX_INDEXTYPE index, const void *params, size_t size) = 0;
virtual status_t setPortMode(
OMX_U32 port_index, IOMX::PortMode mode) = 0;
virtual status_t prepareForAdaptivePlayback(
OMX_U32 portIndex, OMX_BOOL enable,
OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0;
virtual status_t configureVideoTunnelMode(
OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
virtual status_t getGraphicBufferUsage(
OMX_U32 port_index, OMX_U32* usage) = 0;
virtual status_t setInputSurface(
const sp<IOMXBufferSource> &bufferSource) = 0;
virtual status_t allocateSecureBuffer(
OMX_U32 port_index, size_t size, buffer_id *buffer,
void **buffer_data, sp<NativeHandle> *native_handle) = 0;
virtual status_t useBuffer(
OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) = 0;
virtual status_t freeBuffer(
OMX_U32 port_index, buffer_id buffer) = 0;
virtual status_t fillBuffer(
buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) = 0;
virtual status_t emptyBuffer(
buffer_id buffer, const OMXBuffer &omxBuf,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) = 0;
virtual status_t getExtensionIndex(
const char *parameter_name,
OMX_INDEXTYPE *index) = 0;
virtual status_t dispatchMessage(const omx_message &msg) = 0;
};
MediaCodec#
MediaCodec を初期化
ACodec の状態図#
OMX アーキテクチャはこの状態図に基づいて関連操作を完了します。