SoCビデオ処理支援機能を使った Androidマルチメディア処理改善の試み 松原 克弥 株式会社イーゲル 2009.12.18 背景:現状の確認 SHプロセッサでAndroid 1.5が動いた!でも… お、遅い… 特に ビデオ再生が … 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 2 SoCアクセラレーションH/W SH-MobileR2(SH7723)の仕様 (プレスリリース資料より抜粋) 多種多様な on-chip デバイス! 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 3 Android マルチメディア処理の最適化 マルチメディア処理をアクセラレーションH/Wへオフロード – ビデオデコード – 色変換 – 回転、拡大縮小、クリッピング メインライン機能 Linux UIOを使って、ユーザ空間からデ バイス利用(制御) 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 4 Linux UIO(User-space I/O) ユーザ空間からデバイスを直接制御する ユーザ空間からデバイスを直接制御する ための汎用フレームワーク ための汎用フレームワーク mmap()によるI/Oメモリへのアクセス 連続物理メモリの確保とアクセス read()による割り込み通知の受信 ユーザ空間での他カーネル機能との 連携不可 デバイス共有のための仕組みなし 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み メモリコピー の削減 コンテキスト スイッチの削減 5 UIOアーキテクチャ アプリケーション ユーザ空間 UIO userspace driver read() カーネル空間 mmap() UIO core UIO kernel driver 割り込み I/Oメモリ(レジスタ) ハードウェア 2009/12/18 デバイス CELF Jamboree #31/ Androidマルチメディア処理改善の試み 6 Android マルチメディアフレームワーク 出典: http://developer. android.com/gui de/basics/whatis-android.html 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 7 Android マルチメディアフレームワーク Media Framework – – – – Packet Video社が開発したマルチメディアエンジン OpenCOREを採用 メディアプレーヤ、AVデコード/エンコードエンジン Androidでは、mediaserverプロセスとして動作 コードツリーでは、/external/opencoreに配置 Surface Flinger – フレームバッファ(描画面)の管理 – コードツリーでは、frameworks/base/libs/{surfaceflinger、 ui}に配置 Display Driver – Linux fbdevを使用 – フレームバッファの提供(mmap)とフリップの制御 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 8 ビデオ再生の内部処理フロー 描画処理部 (Surface Flinger) メディア処理部 (Media Server) SD Car d Demux H.264 Video Frame File Input デ コ ー ド YV12 Image 色 変換 RGB16 Image 回転 拡大 縮小 SH RGB16 RGB16 FB FB Audio Device 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 9 H/Wへオフロードする処理 1. ビデオデコード 2. 色変換 3. 回転・拡大縮小・クリッピング 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 10 1. ビデオデコードのオフロード 描画処理部 (Surface Flinger) メディア処理部 (Media Server) SD Car d Demux H.264 Video Frame File Input デ コ ー ド YV12 Image 色 変換 RGB16 Image 回転 拡大 縮小 SH RGB16 RGB16 FB FB Audio Device 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 11 OpenCOREコーデックプラグイン 仕様:OpenMAX IL OpenCOREでは、コーデック処理モジュールの OpenCOREでは、コーデック処理モジュールの インタフェースにOpenMAX インタフェースにOpenMAXILコンポーネント仕様を採用 ILコンポーネント仕様を採用 OpenMAX – Khronosグループによって、マルチメディア処理向けのAPI規格 として策定 – ILが統合ライブラリレイヤ、DLがハードウェアレイヤのインタ フェース規格 – 最新仕様は、1.1.2 – http://www.khronos.org/openmax/ 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 12 OpenCOREが求めるOpenMAX ILコ ンポーネント仕様 PV OpenMAX ILコンポーネントラッパーが必要 – コンストラクタ – デストラクタ – OMX_GetHandle()等のAPI コードツリー(/external/opencore/doc)にドキュメントあり – OMX Core Integration Guide – OpenMAX Call Sequences 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 13 VPU UIOカーネルドライバ CONFIG_UIO_PDRV_GENIRQ – – – – – UIO共通の割り込みドライバ 自動割り込み停止 writeシステムコールによる割り込み制御(禁止/許可) 割り込み共有には非対応 2.6.27でマージ済み static staticstruct structplatform_device platform_devicevpu_device vpu_device=={ { .name =="uio_pdrv_genirq", .name "uio_pdrv_genirq", .id = 0, .id = 0, .dev = .dev ={ { .platform_data ==&vpu_platform_data, .platform_data &vpu_platform_data, },}, .resource ==vpu_resources, .resource vpu_resources, .num_resources = ARRAY_SIZE(vpu_resources), .num_resources = ARRAY_SIZE(vpu_resources), };}; 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 14 VPU UIOカーネルドライバ static staticstruct structuio_info uio_infovpu_platform_data vpu_platform_data=={ { .name .name=="VPU5", "VPU5", .version = .version ="0", "0", .irq = 60, .irq = 60, };}; static staticstruct structresource resourcevpu_resources[] vpu_resources[]=={ { [0] [0]=={ { .name .name =="VPU", "VPU", .start .start ==0xfe900000, 0xfe900000, .end .end ==0xfe902807, 0xfe902807, .flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM, },}, [1] [1]=={ { /*/*place placeholder holderfor forcontiguous contiguousmemory memory*/*/ },}, };}; 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 15 VPUミドルウェア libshcodecs:VPUを使ったエンコード/デコードを支援 するミドルウェア omxil-sh:SH アクセラレーションH/Wを使ったコーデック エンジンを実現するOpenMAX ILコンポーネント – Bellagio OpenMAX ILがベース 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 16 BellagioとOpenCOREとの接続 準拠しているOpenMAX ILバージョンの差異 – Android 1.5のOpenCOREはOpenMAX IL 1.0 – Bellagio OpenMAX ILは1.1 ⇒OpenCOREが使っている部分に差異がないので、定義を変更 OpenMAX ILコンポーネントの追加 – PV OMXILラッパを実装する必要あり – BellagioとOpenCORE OMXILの差異 ⇒dlopen()によるコンポーネントコードの差し替え ⇒デストラクタは省略(プロセスまるごとkill) • Zygoteが自動的に再起動 注)正しい実装ではありません。 真似しないでください。 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 17 OpenMAX ILコンポーネントの変更 @@ @@-42,7 -42,7+86,80 +86,80@@ @@OSCL_EXPORT_REF OSCL_EXPORT_REFOMX_ERRORTYPE OMX_ERRORTYPE AvcOmxComponentFactory(OMX_OUT AvcOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* OMX_HANDLETYPE*pHa pHa OpenmaxAvcAO* OpenmaxAvcAO*pOpenmaxAOType; pOpenmaxAOType; OMX_ERRORTYPE OMX_ERRORTYPEStatus; Status; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ int int(*q)(stLoaderComponentType (*q)(stLoaderComponentType**); **); pp==dlopen dlopen("/system/lib/bellagio/libomxshvpudec.so", ("/system/lib/bellagio/libomxshvpudec.so",RTLD_NOW); RTLD_NOW); qq==(int(*)(stLoaderComponentType (int(*)(stLoaderComponentType**)) **)) dlsym dlsym(p, (p,"omx_component_library_Setup"); "omx_component_library_Setup"); nn==qq(NULL); (NULL); stLoaderComponentType stLoaderComponentTyped[n], d[n],*dd[n]; *dd[n]; int inti;i; unsigned unsignedint intj;j; OMX_ERRORTYPE OMX_ERRORTYPEe; e; OMX_COMPONENTTYPE OMX_COMPONENTTYPE*c; *c; 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 18 OpenMAX ILコンポーネントの変更 ++ ++ ++ ++ for for(i(i==0; 0;i i<<n; n;i++) i++) dd[i] dd[i]==&d[i]; &d[i]; qq(dd); (dd); cc==new newOMX_COMPONENTTYPE; OMX_COMPONENTTYPE; … … ++ ++ ++ ee==d[i].constructor d[i].constructor(c, (c,(OMX_STRING) (OMX_STRING) "OMX.st.video_decoder.avc.shvpu"); "OMX.st.video_decoder.avc.shvpu"); *pHandle *pHandle==(OMX_HANDLETYPE (OMX_HANDLETYPE*)c; *)c; pOpenmaxAOType pOpenmaxAOType==(OpenmaxAvcAO*) (OpenmaxAvcAO*)OSCL_NEW(OpenmaxAvcAO, OSCL_NEW(OpenmaxAvcAO,()); ()); 注)正しい実装ではありません。真似しないでください。 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 19 2. 色変換のオフロード メディア処理部 (Media Server) SD Car d Demux H.264 Video Frame File Input デ コ ー ド 描画処理部 (Surface Flinger) YV12 Image 色 変換 RGB16 Image 回転 拡大 縮小 SH RGB16 RGB16 FB FB Audio Device 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 20 OpenCOREがサポートする カラーフォーマット OpenCOREでは… デコード出力はYUV(YV12)のみを想定 – This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes. – OpenMAX IL仕様では、コンポーネントが出力する色フォーマッ トを通知できる仕組みがあるが、OpenCOREがシカト 画面出力はRGB565を想定 アクセラレーションH/Wの出力はNV12がメジャー – YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples. 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 21 OpenCORE内の色変換処理 ビデオ画像の色変換処理はOpenCORE(mediaserver) 内で実施 – external/opencore/codecs_v2/utilities/colorconvert – external/opencore/android/android_surface_output.cpp iColorConverter iColorConverter==ColorConvert16::NewL(); ColorConvert16::NewL(); iColorConverter->Init(displayWidth, iColorConverter->Init(displayWidth,displayHeight, displayHeight,frameWidth, frameWidth,displayWidth, displayWidth, displayHeight, displayWidth, CCROTATE_NONE); displayHeight, displayWidth, CCROTATE_NONE); iColorConverter->SetMemHeight(frameHeight); iColorConverter->SetMemHeight(frameHeight); iColorConverter->SetMode(1); iColorConverter->SetMode(1); … … iColorConverter->Convert(aData, iColorConverter->Convert(aData,static_cast<uint8*>(mFrameHeap->base()) static_cast<uint8*>(mFrameHeap->base())++ mFrameBuffers[mFrameBufferIndex]); mFrameBuffers[mFrameBufferIndex]); 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 22 色変換処理の差し替え - - iColorConverter->Convert(aData, iColorConverter->Convert(aData,static_cast<uint8*>(mFrameHeap->base()) static_cast<uint8*>(mFrameHeap->base())++ -mFrameBuffers[mFrameBufferIndex]); mFrameBuffers[mFrameBufferIndex]); ++ shveu_operation(veuIndex, shveu_operation(veuIndex, ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ pSrcY, pSrcY,pSrcC, pSrcC, displayWidth, displayWidth,displayHeight, displayHeight,frameWidth, frameWidth, SHVEU_YCbCr420, SHVEU_YCbCr420, pDstRGB, pDstRGB,pDstDummy, pDstDummy, displayWidth, displayWidth,displayHeight, displayHeight,displayWidth, displayWidth, SHVEU_RGB565, SHVEU_RGB565, SHVEU_NO_ROT); SHVEU_NO_ROT); memcpy(static_cast<uint8*>(mFrameHeap->base()) memcpy(static_cast<uint8*>(mFrameHeap->base())++ mFrameBuffers[mFrameBufferIndex], mFrameBuffers[mFrameBufferIndex], vDstRGB, vDstRGB,frameSize); frameSize); 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 23 3. 回転・拡大縮小・クリッピング のオフロード 描画処理部 (Surface Flinger) メディア処理部 (Media Server) SD Car d Demux H.264 Video Frame File Input デ コ ー ド YV12 Image 色 変換 RGB16 Image 回転 拡大 縮小 SH RGB16 RGB16 FB FB Audio Device 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 24 SurfaceFlingerの処理 画面サイズ&向きにあわせるための回転・拡大縮小・クリッ ピングを実施 – SurfaceFlingerに渡るまでは一定サイズ(ビデオは、元ビデオサ イズ、カメラは320x240のような固定)で描画 ⇒色変換と同様にビデオ画像処理機能(VEU)へオフロード 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 25 SurfaceFlinger描画プラグイン 仕様:copybit アクセラレーションH/Wへオフロードするためのプラグイン 起動時に配置されていると自動ロード&リンク – /system/lib/hw/copybit.boardname.so hardware/libhardware/include/hardware/copybit.h struct structcopybit_device_t copybit_device_t{ { struct structhw_device_t hw_device_tcommon; common; int (*set_parameter)(struct int (*set_parameter)(structcopybit_device_t copybit_device_t*dev, *dev,int intname, name,int intvalue); value); int int(*get)(struct (*get)(structcopybit_device_t copybit_device_t*dev, *dev,int intname); name); int (*blit)(struct copybit_device_t *dev, struct int (*blit)(struct copybit_device_t *dev, structcopybit_image_t copybit_image_tconst const*dst, *dst, struct copybit_image_t const *src, struct copybit_region_t const struct copybit_image_t const *src, struct copybit_region_t const*region); *region); int (*stretch)(struct copybit_device_t *dev, struct copybit_image_t const *dst, int (*stretch)(struct copybit_device_t *dev, struct copybit_image_t const *dst, struct structcopybit_image_t copybit_image_tconst const*src, *src,struct structcopybit_rect_t copybit_rect_tconst const*dst_rect, *dst_rect, struct structcopybit_rect_t copybit_rect_tconst const*src_rect, *src_rect, struct structcopybit_region_t copybit_region_tconst const*region); *region); };}; 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 26 改善した処理フロー 描画処理部 (Surface Flinger) メディア処理部 (Media Server) H.264 H.264 Video Video Frame Frame SD Card Demux File Input YV12 YV12 Image Image RGB16 RGB16 Image Image PV OMXIL 色変換 Copy Bit OMXILSH libshveu libshveu libshcodecs SH H.264 Video Frame Audio Device 2009/12/18 RGB16 Input Data NV12 RGB16 Image RGB16 Image (rotated) NV12 Image VPU RGB16 RGB16 FB FB Rotated RGB16 VEU CELF Jamboree #31/ Androidマルチメディア処理改善の試み VEU Resized RGB16 (Full Screen) VEU 27 最適化の効果 より大きなサイズのビデオでも再生がなめらかに copybitによりカメラプレビューも改善 copybit 適用後 適用前 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 28 Android on SHに必要なコードは ここからダウンロードできます。 Android patches for Renesas SH https://review.source.android.com/#dashboard,10018 93 libshcodecs http://github.com/kfish/libshcodecs omxil-sh http://github.com/kfish/omxil-sh libshveu http://github.com/kfish/libshveu 2009/12/18 CELF Jamboree #31/ Androidマルチメディア処理改善の試み 29
© Copyright 2024 Paperzz