Jetson Multimedia APIによる動画エンコード:第1話 エンコーダーの使い方

本連載は、Jetson Multimedia APIを利用した様々な動画のエンコードについて、全3話にわたって解説します。

第1話である本記事は、 Jetson Multimedia APIで提供されるビデオエンコーダーの使い方についてです。

 

[Jetson Multimedia APIによる動画エンコード]

 第1話 エンコーダーの使い方

 第2話 Libargus(CSI)カメラを入力とするエンコード

 第3話 スライスエンコード

はじめに

NVIDIA社Jetsonモジュールには動画エンコード専用のハードウェアアクセラレーターが内蔵されています。このアクセラレーターにより、CPUは負荷の大きい動画エンコード処理から解放されます。
Jetsonで動画エンコードを実行する一般的な方法はGStreamerを使う方法で、こちらについては別の記事で紹介しています。

Jetsonビデオ処理プログラミング 第6話 動画エンコード

 

GStreamerは、音声ストリームとの多重化や、配信、ビデオ解析なども容易に実現でき、また、多チャンネル化も容易です。しかし、より細かい制御や、より低遅延を求めたい場合もあり、その場合は、GStreamerより下の階層に位置するJetson Multimedia APIの利用が有効なときがあります。

V4L2 Video Encoder

Jetson Multimedia APIで提供されるビデオエンコーダーはVideo for Linux 2(V4L2)準拠です。つまり、NVIDIA社製プラットフォーム固有のNVENCには依存しない(もしくは、依存を極力避けた)アプリケーションの開発が可能です。ただし、Jetson Multimedia APIでは、そのV4L2 Video Encoderに対して、ラッパークラスとその周辺クラスが用意されて、より使いやすいAPIも同時に提供されています。

Jetson Multimedia APIの提供するラッパークラスの位置づけ
Jetson Multimedia APIの提供するラッパークラスの位置づけ

このラッパークラスであるNvVideoEncoderの使い方を説明する01_video_encodeサンプルコードがJetson Multimedia APIに含まれています。

本記事ではこのサンプルコードの内容をベースに、NvVideoEncoderの使い方を解説します。

サンプルコードの試し方

自由にサンプルコードを変更できるよう、まずは、Jetson Multimedia API一式をユーザーディレクトリーへコピーしましょう。

cd ~
cp -r /usr/src/jetson_multimedia_api/ ./

すべてのサンプルコードをビルドします。

cd jetson_multimedia_api
make

エンコーダーのサンプルプログラムはYUVファイルを入力としますが、この種類のテスト用入力ファイルが存在しないため、まずは、テスト用入力ファイルを生成することから始めます。テスト用H.264ファイルはJetson Multimedia APIに付属するため、これをデコードしてYUVファイルを生成することとします。

cd samples/00_video_decode
./video_decode H264 --disable-rendering -o test.nv12 ../../data/Video/sample_outdoor_car_1080p_10fps.h264

上記でYUVファイルは生成できましたが、YUVファイルには多くの形式が存在します。上記で生成できたのは、NV12形式ですが、今度は、これをエンコーダーサンプルプログラムが対応可能なYUV420形式へ変換します。

cd ../07_video_convert/
./video_convert ../00_video_decode/test.nv12 1920 1080 NV12 test.yu12. 1920 1080 YUV420

以上でテスト用入力ファイルが生成できました。エンコーダーサンプルプログラムを実行してみましょう。

cd ../01_video_encode/
./video_encode ../07_video_convert/test.yu12.0 1920 1080 H264 output.h264

エンコードされたビットストリームはoutput.h264に保存されました。これを再生して正しくエンコードできているか確認してみます。

nvgstplayer-1.0 -i output.h264

上記のフローを図にすると以下のとおりです。

サンプルプログラム実行フロー
サンプルプログラム実行フロー

エンコーダーの利用手順

最後に、01_video_encodeサンプルプログラムの内容から、エンコーダーの利用手順をまとめてみます。

アプリケーション・スレッド

1. 入力YUVファイルのオープン
2. 出力ビットストリームファイルのオープン
3. NvVideoEncoderオブジェクトの生成
4. キャプチャープレーン(エンコーダーの出力側)の設定(ビデオコーデックの選択 H.264/H.265/VP8/VP9、エンコードされるフレームのサイズなど)
5. アウトプットプレーン(エンコーダーの入力側)の設定(入力画像形式と入力フレームサイズ)
6. その他のエンコード設定
7. アウトプットプレーンのストリーミングを開始
8. キャプチャープレーンのストリーミングを開始
9. キャプチャープレーン・デキュー・コールバック関数を登録
10. キャプチャープレーン・デキュー・スレッドを起動
11. キャプチャープレーンに空のバッファーを入れる(キュー)
12. ファイルからYUVデータをバッファーへ読み出し、そのバッファーをアプトプットプレーンへ入れる(キュー)


以下、入力YUVファイルの内容をすべてエンコードするまで繰り返し
13. アウトプットプレーンから使用済みバッファーを取り出す(デキュー)
14. ファイルからYUVデータをバッファーへ読み出し、そのバッファーをアウトプットプレーンに入れる(キュー)

コールバック関数

1. キャプチャープレーン・デキュー・スレッドが取り出したバッファーが、コールバック関数の引数で渡されるので、そのバッファーに格納されたビットストリーム(エンコード結果)を出力ファイルへ書き出す
2. 使用済みバッファーをキャプチャープレーンへ戻す(キュー)

エンコーダー入出力
エンコーダー入出力

次回、Libargus(CSI)カメラを入力とするエンコードについて解説

本記事では、NvVideoEncoderの使い方についてご紹介しましたがいかがでしたでしょうか。

続きの2、3話では、Libargus(CSI)カメラを入力とするエンコードについてと スライスエンコードについてご紹介します。下記ボタンをクリックいただき、フォームを入力いただくと続きの記事をご覧いただけます。

お問い合わせ