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 のうち128MBをAVコーデックミドルウェアに割り当てる必要があります。AVコーデックミドルウェアドライバが追加された Linuxカーネル 3.4-at6 以降では、デフォルトでLinuxカーネルが管理するメモリを、512MB品では 384MBに、1GB品では 896MBに制限しています。
このように、多くのプロセッサが協調動作をすることで、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 - マルチメディアフレームワーク15.3.1. 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コマンドを使うことで調べることができます。
15.3.2. GStreamerのパイプラインの画像を生成する
ここでは、GStreamerのパイプライン画像(図15.5「GStreamerのパイプライン例」)を生成する手順について説明します。
ATDEにGraphvizをインストール
GStreamerから出力されるdotファイルから、パイプラインの画像を生成するためのアプリケーションをATDEにインストールします。
dotファイルを作成
Armadillo上で以下のコマンドを実行しdotファイルを作成します。GST_DEBUG_DUMP_DOT_DIR= で、dotファイル出力ディレクトリの指定を追加できます。
本コマンドを実行するためには、再生する動画ファイル(big-buck-bunny-30sec-fullhd.mp4 )が格納されたSDカードをマウントしておくなど準備が必要です。
本コマンドを実行する手順については「AVコーデックミドルウェア」を確認してください
gst-launchは状態変化ごとのdotファイルを出力するため、出力ディレクトリには複数のdotファイルが出力されます。
dotファイルからパイプライン画像を生成
SDカードに保存されたdotファイルをATDEにコピーし、以下のコマンドでdotファイルからパイプライン画像を生成します。
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 を読み出すことで確認できます。
この章はAVコーデックミドルウェアのエンコーダーが有効になっていることを前提に書かれています。
「有効化/無効化」を参照し、エンコーダーを有効化してください。
ビデオ(映像)とオーディオ(音声)データを一つのファイルにまとめる(多重化する)ためのフォーマットをコンテナフォーマットと言います。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.14「ビデオをエンコードしてコンテナに格納する」に示します。MP4コンテナに格納する場合、qtmuxエレメントを使用します。
画像の入力ソースとして、様々なパターンの画像を様々なフォーマットで生成できるvideotestsrcを使用しています。acmh264encエレメントは、入力フォーマットとしてNV12形式のみを受付ますので、acmh264encの入力側のケイパビリティを指定しています[]。videotestsrcは指定されたフォーマットで画像を出力します。
また、パイプライン停止時にEOSイベントを発行するように、gst-launch-1.0コマンドに-eオプションを付けています。エンコードを終了するには、Ctrl-Cでgst-launch-1.0コマンドを停止してください。
オーディオのみをMP4コンテナに格納するパイプラインの例を図15.15「オーディオをエンコードしてコンテナに格納する」に示します。ここでも、様々なパターンのオーディオデータを生成できるaudiotestsrcを使用しています。audiotestsrcが出力するフォーマットと、acmaacencが受け付けられるフォーマットを合わせるため、ケイパビリティを指定しているのはビデオの場合と同じです。
ビデオとオーディオを同時にMP4コンテナに格納するパイプラインの例を図15.16「ビデオとオーディオをエンコードしてコンテナに格納する」に示します。
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.21「フレームレートを指定する」のように指定すると、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.5.2.4. 入力画像サイズの制限とオフセットの指定
acmh264encエレメントへの入力画像サイズには、下記の制限があります。
入力画像幅: 80~1920画素(2の倍数であること) 入力画像高さ: 80~1088ライン(2の倍数であること) 入力画像幅 × 入力画像高さは32の倍数であること
また、acmh264encエレメントのx-offsetプロパティとy-offsetプロパティを使うことで、入力画像の一部だけをエンコードできます。x-offsetとy-offsetプロパティには下記の制限があります。
図15.22「オフセットを指定する」のように指定すると、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.5.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.27「オフセットを指定する」のように指定すると、640×480サイズの入力画像のうち、中央の320×240サイズだけエンコードを行います。ajpegencエレメントの出力サイズを設定するために、出力側のケイパビリティも指定している点に注意してください。
| |
|