SoCビデオ処理支援機能を使った Androidマルチメディア

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