AV コーデックミドルウェアは、Armadillo-800 シリーズでマルチメディア処理 (H.264/AVC 動画・AAC 音声・JPEG 画像の変換処理) をスムーズかつ効率的に行うためのミドルウェアです。Armadillo-800シリーズに搭載されているアプリケーションプロセッサー「R-Mobile A1」には、メインの ARM コア以外にリアルタイム制御用の SH-4Aコアとマルチメディア処理専用プロセッサが搭載されています。マルチメディア処理は、多くの場合システムに負荷をかけることが多く、メイン CPU で処理をするとシステム全体のパフォーマンスが低下します。AV コーデックミドルウェアを利用することで、メイン CPUのパフォーマンスを落すことなく、マルチメディアの処理を行うことができるようになります。
上図に示すように、AV コーデックミドルウェアを使う場合には R-Mobile A1 に搭載されている以下の専用プロセッサは SH 側で管理されます。
AVコーデックミドルウェアが対応しているフォーマットは以下の通りです。
デコーダーが対応しているフォーマット エンコーダーが対応しているフォーマット
マルチメディアは、比較的大きなデータを扱います。そのためマルチメディア処理を行う専用プロセッサや管理する SHもメインメモリを利用する必要があります。AV コーデックミドルウェアを利用する時には、Armadillo-800シリーズに搭載されているDDR3 SDRAM 512MBのうち128MBをAVコーデックミドルウェアに割り当てる必要があります。AVコーデックミドルウェアドライバが追加されたlinux-3.4-at6以降では、デフォルトでLinuxカーネルが管理するメモリを384MBに制限しています。
このように、多くのプロセッサが協調動作をすることで、Armadillo-800 シリーズではH.264/AVC 動画やAAC音声などのマルチメディアデータをスムーズかつ効率的に扱うことができます。
さらにAVコーデックミドルウェアは、アプリケーションプログラムからマルチメディアデータを容易に扱えるよう、Linuxで標準のマルチメディアフレームワークGStreamer [http://gstreamer.freedesktop.org/]に対応しています。
GStreamer は、エレメントと呼ばれる処理単位を繋ぎ合わせパイプラインを作成することで、複雑な要求に対応できるマルチメディアフレームワークです。MP4ファイルを扱うエレメントや、様々な画像フォーマットを変換するエレメントなどが標準で用意されているため、このフレームワークを活用することで、様々なフォーマットのマルチメディアデータを統一的な操作で、簡単に扱うことができます。
表15.1
AACデコーダー仕様
符号化方式
|
|
ビットレート
|
|
入力フォーマット
|
|
入力チャネル
|
|
出力チャネル
|
1チャネルか2チャネル (ダウンミックス対応)
|
サンプリング周波数
|
|
表15.2
H.264/AVCデコーダー仕様
最大ビットレート |
40M bit/sec
[]
| 入力フォーマット | Video Elementary Stream | 出力フォーマット |
| サポートプロファイル/レベル |
| プロファイル共通非サポートツール |
| ピクチャ構造 |
| エントロピー符号化 | CAVLC / CABAC | ピクチャタイプ | I / P / B ピクチャ | マルチスライス | サポート。1フレームあたりの最大スライス数は68スライスまで(画像サイズ1920x1080の場合、1スライス/1マクロブロックライン相当) | マルチリファレンス | サポート | マルチシーケンス |
サポート。ただし、シーケンスを通じて以下の条件満すこと
画像サイズ、フレームレートが変化しないこと
エンコード時のビットレート設定が同じであること
| マルチストリーム | 非サポート | データ・パーティショニング | 非サポート | 画像サイズ |
| 画像の拡大・縮小 | 幅、高さともに拡大: 最大16倍まで、縮小: 最少1/16まで |
表15.3
AACエンコーダー仕様
準拠規格
|
|
ビットレート
|
16k ~ 288k bps、VBR
[]
|
対応チャネル
|
1チャネル(モノラル)
2チャネル (ステレオ、デュアルモノラル)
|
入力フォーマット
|
16bit PCM
|
入力サンプリング周波数
|
8k/11.025k/12k/16k/22.05k/24k/32k/44.1k/48k Hz
|
出力フォーマット
|
AAC-LC(RAW形式、ADTS形式)
|
表15.4
H.264/AVC エンコーダー仕様
最大ビットレート |
40M bit/sec
[]
| 最大フレームレート |
水平画像サイズ1280以下かつ垂直画像サイズ720以下の場合
上記以外
| 最大参照フレーム | 2フレーム | 入力画像サイズ |
画像幅
画像高さ
| 入力フォーマット | YUV420 | 出力フォーマット | Video Elementary Stream | プロファイル/レベル |
条件により自動で選択
| プロファイル共通非サポートツール |
ASO (Arbitrary Slice Order) FMO (Flexible Macroblock Ordering) RS (Redundant Slice) MBAFF (Macroblock-Adaptive Frame-Field) coding Weighted Prediction
| ピクチャ構造 |
フレーム構造 (プログレッシブシーケンス)
| エントロピー符号化 |
Baseline Profileの場合
Main ProfileまたはHigh Profileの場合
| 動き探索範囲 |
水平
垂直
サブサンプリング
| ピクチャタイプ | I / P / B ピクチャ | イントラMBリフレッシュ |
サポート
[]
| イントラ予測方式 | 4×4、8×8、16×16画素単位イントラ予測 | 変換方式 | 4×4、8×8整数変換 | マルチスライス | 非サポート | マルチリファレンス | 非サポート | 階層エンコード | 非サポート | マルチシーケンス | 非サポート | マルチストリーム | 非サポート | リエントラント対応 | なし |
15.3. GStreamer - マルチメディアフレームワーク
GStreamerは、オープンソースのマルチメディアフレームワークです。小さなコアライブラリに様々な機能をプラグインとして追加できるようになっており、多彩な形式のデータを扱うことができます。GStreamerで扱うことができるデータフォーマットの一例を下記に示します。
コンテナフォーマット: mp4, avi, mpeg-ps/ts, mkv/webm, ogg 動画コーデック: H.264/AVC, Vorbis 音声コーデック: AAC, Theora, wav 画像フォーマット: JPEG, PNG, BMP ストリーミング: http, rtp
GStreamerでは、マルチメディアデータをストリームとして扱います。ストリームを流すパイプラインの中に、エレメントと呼ばれる処理単位を格納し、それらをグラフ構造で繋ぎ合わせることで、デコードやエンコードなどの処理を行います。例えば、図15.4「GStreamerの実行例」に示すコマンドを実行した場合のパイプラインは図15.5「GStreamerのパイプライン例」となります。
| |
---|
拡大してご覧ください。
|
GStreamerのパイプラインは、シェルスクリプトのパイプ構文の構造に似ています。GStreamerの各エレメントとシェルスクリプト内のコマンドを対比することができます。構文的な違いとして、GStreamerのパイプラインは「! 」を使って各エレメントを繋ぎますが、シェルスクリプトは「| 」を使います。
シェルスクリプトで使うコマンドが引数を取るように、GStreamerのエレメントも引数を取ることができます。この引数は、「プロパティ」と呼ばれます。
各エレメントは、データの入出力の口となる「パッド(pad)」を持っています。実際にエレメント同士を繋いでいるのはパッドです。パッドにはデータを次のエレメントに渡す「ソースパッド(source pad)」とデータを受け取る「シンクパッド(sink pad)」が存在します。図中の「src 」と書かれた小さな箱と「sink 」と書かれた小さな箱がそれぞれに該当します。
パッドは自分が出力可能な、または入力可能なフォーマットを知っています。これを「ケイパビリティー (Capability)」と言います。パッドは、パイプラインが作られる時に繋がる相手パッドが持っているケイパビリティーを確認します。お互いのケイバビリティーが一致しない場合はデータの受け渡しができませんので、エラーとなり、最終的にパイプライン生成自体がエラーとなります。
ソースパッドしか持たないエレメントを「ソースエレメント」、シンクパッドしか持たないエレメントを「シンクエレメント」と呼びます。図中左端にある「filesrc0」がソースエレメントで、右端の「alsasink0」「acmfbdevsink」の2 つがシンクエレメントになります。マルチメディアデータは、一番左側のソースエレメントから右端のシンクエレメントに流れることで形を変えていき、最終的に動画や音声として再生されることになります。
上記例は、GStreamerのデバッグ/プロトタイピング用のコマンドラインツールであるgst-launch-1.0を使って説明しましたが、GStreamerはライブラリとして提供されているため、GStreamerを使ったマルチメディア機能を自作のアプリケーションプログラムに組み込むことができます。APIやアプリケーション開発マニュアルは、gstreamer.freedesktop.orgのDocumentationページ[http://gstreamer.freedesktop.org/documentation/]から参照することができます。
AVコーデックミドルウェア用のエレメントには、下記のものがあります[]。以降の章では、これらのエレメントの使い方を中心に説明します。
環境にインストールされているエレメント一覧を取得したり、各エレメントの取れるケイパビリティや指定可能なプロパティはgst-inspect-1.0コマンドを使うことで調べることができます。
AVコーデックミドルウェアは、SHで動作するファームウェアと、Linux上で動作するデバイスドライバが協調して機能します。そのため、AVコーデックミドルウェアを有効化するには、SHにファームウェアをロードさせた後、ドライバをロードする必要があります。
SHファームウェアのロードとドライバのロードを行うには、/sys/devices/platform/acm.0/codec に"encoder"または"decoder"という文字列を書き込みます。AVコーデックミドルウェアを無効化する場合は、"none"という文字列を書き込みます。
標準状態では、起動時に/etc/config/rc.local でAVコーデックミドルウェアを有効化しています。Armadillo-810の場合エンコーダーが、Armadillo-840の場合はデコーダーが有効になります。詳細は「/etc/config/rc.local」を参照してください。
AVコーデックミドルウェアの現在の状態は、/sys/devices/platform/acm.0/codec を読み出すことで確認できます。
ビデオ(映像)とオーディオ(音声)データを一つのファイルにまとめる(多重化する)ためのフォーマットをコンテナフォーマットと言います。H.264/AVCとAACを格納可能なコンテナフォーマットには、MP4(MPEG-4 Part 14)、AVI(Audio Video Interface)、Matroskaなどがあります。また、MPEG2 TS(MPEG-2 Transport Stream)やMPEG2 PS(MPEG-2 Program Stream)は、拡張規格でH.264/AVCとAACに対応しています。
GStreamerでは、コンテナに格納されたビデオやオーディオのデータを取り出す場合、デマルチプレクサエレメントを使用します。
MP4コンテナからビデオとオーディオを取り出し再生するパイプラインの例として、図15.4「GStreamerの実行例」で示したコマンドラインを再掲します。MP4コンテナからビデオやオーディオを取り出す場合、qtdemuxエレメントを使用します。
qtdemuxエレメントは、MP4コンテナに格納されているデータストリームごとに動的にソースパッドを作成します。ビデオ用に動的に生成されたパッドにはvideo_N という名前が、オーディオ用に生成されたパッドにはaudio_N という名前がつきます。
パッド名は省略して、下記のように記述することもできます。GStreamerでは、エレメント同士を接続(リンク)する際に、お互いのソースパッド(出力)とシンクパッド(入力)が受け渡しできるフォーマット(ケイパビリティ)が一致するかネゴシエーションを行い、ケイパビリティが一致した場合だけパッドがリンクされます。queueエレメントはバッファリングを行うためのエレメントで、どのようなフォーマットのデータも受け渡しでき、シンクパッドとソースパッドのケイパビリティは同じものになります。そのため、qtdemuxが動的に生成したオーディオ用のパッドにはオーディオを扱うacmaacdecにリンクされているqueueエレメントのシンクパッドが、ビデオ用のパッドにはビデオを扱うacmh264decエレメントがリンクされているqueueエレメントのシンクパッドがリンクされます。
ビデオだけやオーディオだけを再生したい場合は、下記のように書くこともできます。この場合、qtdemuxのnameプロパティも省略されていますが、qtdemuxが動的に生成したパッドのうち、後続するエレメントが受け取れるパッドだけがリンクした状態となります。
ビデオの出力先は、acmfbdevsinkのdeviceプロパティにフレームバッファのデバイスファイル名を指定することで変更できます。deviceプロパティを指定しなかった場合、/dev/fb0 を使用します。
acmh264decエレメントの出力側ケイパビリティにwidthとheightを指定することで、デコードした画像を拡大/縮小して表示することもできます。800×480サイズのビデオをFull HDサイズに拡大して表示する場合のパイプラインは図15.20「ビデオを拡大する」となります。
同様に、縮小して表示することもできます。acmh264decは、出力側のケイパビリティに合わせてR-Mobile A1のVIOを使用して出力画像の拡大/縮小を行うため、ARM CPU側の負荷なく拡大/縮小を行うことができます。
大きなディスプレイに小さな動画を表示したい場合など、出力画像と表示するディスプレイの幅が一致していない場合、acmh264decエレメントのstrideプロパティを指定する必要があります。800×480サイズの動画をそのままのサイズでFull HDサイズのHDMIディスプレイに表示する場合は、下記のコマンドになります。strideには出力先の幅を指定してください。
x-offsetとy-offsetプロパティを使うことで、任意の位置に画像を表示することもできます。下記のコマンドを実行すると、Full HDサイズのディスプレイの右下に800×480サイズの動画が表示されます。
stride、x-offset、y-offsetの関係を図15.24「ストライドとオフセットの関係」に示します。Full HDサイズのディスプレイの右下に800×480サイズの動画を表示する場合、x-offset=1920-800=1120、y-offset=1080-480=600として計算できます。
オーディオの出力先は、alsasinkのdeviceプロパティにALSAデバイス名を指定することで変更できます。deviceプロパティを指定しなかった場合、hw:0 を使用します。
Armadillo-840のHDMIオーディオインターフェース(Armadillo-840: CON3)は、signed 16bit little endian、interleaved、48kHz、2ch PCMのみ出力可能です。入力ファイルに含まれるオーディオがそれ以外のフォーマットやサンプリング周波数の場合、変換して出力する必要があります。オーディオフォーマットの変換にはaudioconvertエレメントを、サンプリング周波数の変換にはaudioresampleエレメントを使います。
ビデオ(映像)とオーディオ(音声)データを一つのファイルにまとめる(多重化する)ためのフォーマットをコンテナフォーマットと言います。H.264/AVCとAACを格納可能なコンテナフォーマットには、MP4(MPEG-4 Part 14)、AVI(Audio Video Interface)、Matroskaなどがあります。また、MPEG2 TS(MPEG-2 Transport Stream)やMPEG2 PS(MPEG-2 Program Stream)は、拡張規格でH.264/AVCとAACに対応しています。
GStreamerでは、ビデオやオーディオのデータをコンテナに格納する場合、マルチプレクサエレメントを使用します。
ビデオのみをMP4コンテナに格納するパイプラインの例を図15.28「ビデオをエンコードしてコンテナに格納する」に示します。MP4コンテナに格納する場合、qtmuxエレメントを使用します。
画像の入力ソースとして、様々なパターンの画像を様々なフォーマットで生成できるvideotestsrcを使用しています。acmh264encエレメントは、入力フォーマットとしてNV12形式のみを受付ますので、acmh264encの入力側のケイパビリティを指定しています[]。videotestsrcは指定されたフォーマットで画像を出力します。
また、パイプライン停止時にEOSイベントを発行するように、gst-launch-1.0コマンドに-eオプションを付けています。エンコードを終了するには、Ctrl-Cでgst-launch-1.0コマンドを停止してください。
オーディオのみをMP4コンテナに格納するパイプラインの例を図15.29「オーディオをエンコードしてコンテナに格納する」に示します。ここでも、様々なパターンのオーディオデータを生成できるaudiotestsrcを使用しています。audiotestsrcが出力するフォーマットと、acmaacencが受け付けられるフォーマットを合わせるため、ケイパビリティを指定しているのはビデオの場合と同じです。
ビデオとオーディオを同時にMP4コンテナに格納するパイプラインの例を図15.30「ビデオとオーディオをエンコードしてコンテナに格納する」に示します。
qtmuxエレメントは、入力されるビデオとオーディオそれぞれに対して、動的にシンクパッドを作成します。ビデオ用に動的に生成されたパッドにはvideo_N という名前が、オーディオ用に生成されたパッドにはaudio_N という名前がつきます。
パッド名は省略して、下記のように記述することもできます。GStreamerでは、エレメント同士を接続(リンク)する際に、お互いのソースパッド(出力)とシンクパッド(入力)が受け渡しできるフォーマット(ケイパビリティ)が一致するかネゴシエーションを行い、ケイパビリティが一致した場合だけパッドがリンクされます。queueエレメントはバッファリングを行うためのエレメントで、どのようなフォーマットのデータも受け渡しでき、シンクパッドとソースパッドのケイパビリティは同じものになります。そのため、qtmuxが動的に生成したオーディオ用のパッドにはオーディオを扱うacmaacencにリンクされているqueueエレメントのソースパッドが、ビデオ用のパッドにはビデオを扱うacmh264encエレメントがリンクされているqueueエレメントのソースシンクパッドがリンクされます。
v4l2srcエレメントを使うことで、V4L2(Video for Linux 2)デバイスとして実装されているカメラデバイスから画像を取得できます。どのデバイスから画像を取得するかは、v4l2srcエレメントのdeviceプロパティにデバイスファイル名を指定することで変更できます。Armadillo-810 カメラモデルの場合、Armadillo-810 カメラモジュール01 (Bコネクタ用)のデバイスファイルは/dev/video1 となります。
UVC対応USBカメラなども同様にv4l2srcで扱うことができます。どのデバイスファイルが、どのカメラに対応しているかは/sys/class/video4linux/videoN /name で確認できます。Armadillo-810 カメラモジュールなど、R-Mobile A1のCEUに接続されたカメラの場合、"sh_mobile_ceu.N "と表示されます。UVC対応USBカメラの場合、"USB Camera"などと表示されます。
USBカメラによってはNV12フォーマットで出力できない場合もあります。そのような場合は、videoconvertエレメントを使うことで画像フォーマットを変更できます。
Armadillo-810 カメラモジュール01 (Bコネクタ用)からの入力画像は、30fps固定となっています。しかし、そこまでフレームレートが必要ない場合、もっと低いフレームレートでエンコードすることもできます。フレームレートの変更には、videorateエレメントを使います。図15.35「フレームレートを指定する」のように指定すると、15fpsでエンコードを行います。
acmh264encエレメントのプロパティを指定することで、エンコード品質を調整できます。エンコード品質に影響するacmh264encエレメントのプロパティを下記に示します。
表15.5 エンコード品質に影響するacmh264encエレメントのプロパティ プロパティ | 意味 | 最小値 | 最大値 | デフォルト値 |
---|
bitrate | 目標平均ビットレート[bit/sec] | 16,000 | 40,000,000 | 8,000,000 | max-frame-size | 最大フレームサイズ[][byte] | 0 | 5,000,000 | 0(推奨値[]を使用) | rate-control-mode |
0: 固定ビットレート(ピクチャスキップあり) 1: 固定ビットレート(ピクチャスキップなし) 2: 可変ビットレート(ピクチャスキップなし)
| 0 | 2 | 2 | max-gop-length |
最大GOP長
0: ストリームの先頭のみIピクチャ 1: 全てIピクチャ 2以上: 指定されたGOP長でGOPを生成
| 0 | 120 | 30 | b-pic-mode |
Bピクチャモード
0: Bピクチャを使用しない 1~3: BピクチャをNフレーム挿入[]
| 0 | 3 | 3 |
15.6.2.4. 入力画像サイズの制限とオフセットの指定
acmh264encエレメントへの入力画像サイズには、下記の制限があります。
入力画像幅: 80~1920画素(2の倍数であること) 入力画像高さ: 80~1088ライン(2の倍数であること) 入力画像幅 × 入力画像高さは32の倍数であること
また、acmh264encエレメントのx-offsetプロパティとy-offsetプロパティを使うことで、入力画像の一部だけをエンコードできます。x-offsetとy-offsetプロパティには下記の制限があります。
図15.36「オフセットを指定する」のように指定すると、640×480サイズの入力画像のうち、中央の320×240サイズだけエンコードを行います。acmh264encエレメントの出力サイズを設定するために、出力側のケイパビリティも指定している点に注意してください。
alsasrcエレメントを使うことで、ALSA(Advanced Linux Sound Architecture)デバイスとして実装されているオーディオデバイスから録音できます。どのデバイスから音声を取得するかは、alsasrcエレメントのdeviceプロパティにALSAデバイス名を指定することで変更できます。Armadillo-840 液晶モデルの場合、Armadillo-840 拡張ボード01 (Cコネクタ用)のマイク入力インターフェース(CON5)に対応するALSAデバイスはhw:1 となります。
音声入力となることができるALSAデバイスの一覧は、 arecord -lコマンドで調べられます。card N の番号を、alsasrcのdeviceプロパティに指定してください。
acmaacencエレメントのプロパティを指定することで、エンコード品質を調整できます。エンコード品質に影響するacmaacencエレメントのプロパティを下記に示します。
表15.6 エンコード品質に影響するacmaacencエレメントのプロパティ プロパティ | 意味 | 最小値 | 最大値 | デフォルト値 |
---|
bitrate | 目標平均ビットレート[bit/sec] | 16,000 | 288,000 | 64,000 | enable-cbr |
固定ビットレート有効
| 0 | 1 | 0 |
Armadillo-810 カメラモジュール01 (Bコネクタ用)のカメラデバイスから取得した画像をJPEGとして保存する場合、下記コマンドを実行します。10フレームの画像を取得し、output0.jpeg ~ output9.jpeg の10枚のJPEG画像が生成されます。画像取得開始からカメラのAGC(Auto Gain Control)、AWB(Auto White Balance)の効果が十分に反映されるまでに 6 フレーム程度かかりますので、output0.jpeg ~ output5.jpeg は色合い、明るさが激しく変化します。
最後の 1 フレームだけ取得したい場合は、 multifilesinkエレメントにmax-files=1プロパティを指定してください。
下記コマンドを実行すると、JPEGエンコードした画像をMotion JPEGとしてmovファイルに格納することができます。
acmjpegencエレメントのqualityプロパティを指定することで、エンコード品質を調整できます。0~100でエンコード品質を指定します。値が小さいほど画像が荒くなりますが、画像サイズは小さくなります。デフォルト値は75に設定されています。
15.6.4.3. 入出力画像サイズの制限とオフセットの指定
acmjpegencエレメントへの入出力画像サイズには、下記の制限があります。
入力画像幅: 16~1920画素(8の倍数であること) 入力画像高さ: 16~1072ライン(16の倍数であること) 出力画像幅: 16~1920画素(4の倍数であること) 出力画像高さ: 16~1072ライン(4の倍数であること)
また、acmjpegencエレメントのx-offsetプロパティとy-offsetプロパティを使うことで、入力画像の一部だけをエンコードできます。x-offsetとy-offsetプロパティには、下記の制限があります。
図15.41「オフセットを指定する」のように指定すると、640×480サイズの入力画像のうち、中央の320×240サイズだけエンコードを行います。ajpegencエレメントの出力サイズを設定するために、出力側のケイパビリティも指定している点に注意してください。
| |
|