倉庫コード: https://gitee.com/liudegui/ffmpeg_decode_video
ffmpeg_decode_video
- ffmpeg を使用してビデオ モジュールをデコードし、3 種類のデコードをサポートします: cpu デコード、amd64 プラットフォームでの cuda デコード、NX プラットフォームでの Nvmpi デコード
- パッケージ ライブラリは ffmpeg のみに依存し、OpenCV はテスト プログラムで使用され、フレームを opencv 検出プログラムに送信するために使用できます。
参照:
- https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c
- 参照: https://github.com/chinahbcq/ffmpeg_hw_decode
概要
ライブラリは、1 つのコードで CUDA GPU モードと CPU モードの切り替えをサポートすることを望んでおり、キー フレームのみをデコードするかどうかを選択することもできます。主な設計思想は次のとおりです。
CUDA GPU デコードがサポートされているかどうかを判断する
bool support_hwdevice()
{
AVHWDeviceType type;
type = av_hwdevice_find_type_by_name(s_hwdevice_name);
if (type == AV_HWDEVICE_TYPE_NONE)
{
fprintf(stderr, "Device type %s is not supported.\n", s_hwdevice_name);
fprintf(stderr, "Available device types:");
while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
fprintf(stderr, "\n");
return false;
}
return true;
}
この方法は、グラフィックス カードを搭載しているがハードウェア ソリューション アクセラレーションをサポートしていない一部のノートブックなどのマシンには適用できません。
このとき、関数は も返しますが、このようなエラーはtrue
デコード時に報告されます。 Hardware is lacking required capabilities
初期化
init_ctx 初期化関数は、主にデコード用の input_ctx とdecoder_ctx を初期化します。
GPU デコードの初期化
説明します:
-
ダーク ボックスは、ハードウェア デコードとソフト デコードの違いです。
-
av_hwdevice_find_type_by_name() の機能は、名前に従って対応する AVHWDeviceType を見つけることです。
-
AVHWDeviceType はハードウェア アクセラレーション API のタイプを示します。AV_HWDEVICE_TYPE_CUDA は nvidia が提供するアクセラレーション API です。
-
av_hwdevice_find_type_by_name でサポートされている名前は次のとおりです。
static const char *const hw_type_names[] = {
[AV_HWDEVICE_TYPE_CUDA] = "cuda",
[AV_HWDEVICE_TYPE_DRM] = "drm",
[AV_HWDEVICE_TYPE_DXVA2] = "dxva2",
[AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",
[AV_HWDEVICE_TYPE_OPENCL] = "opencl",
[AV_HWDEVICE_TYPE_QSV] = "qsv",
[AV_HWDEVICE_TYPE_VAAPI] = "vaapi",
[AV_HWDEVICE_TYPE_VDPAU] = "vdpau",
[AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
[AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
};
- avcodec_get_hw_config: コーデックがサポートするハードウェア構成 AVCodecHWConfig を取得するために使用されます。これは、ハードウェアでサポートされているピクセル形式を取得するために使用されます。
- av_hwdevice_ctx_create: av_hwdevice_ctx_create は、ハードウェア デバイス関連のコンテキスト情報 AVHWDeviceContext を作成し、ハードウェア デバイスを初期化します。
decoder_ctx->get_format = get_hw_format
get_hw_format は、サポートされているピクセル形式をネゴシエートするために AVCodecContext に登録された関数です。
CPUデコード初期化
- CPU デコードの初期化と GPU の違いは、適切なデコーダーを見つけるために avcodec_find_decoder が呼び出され、タイプ、高さ、幅がデコーダー コンテキストに設定されることです。
デコード
- GPU デコードと CPU デコードの違いの 1 つは、GPU が av_hwframe_transfer_data を呼び出して、GPU を CPU にコピーする必要があることです。
- av_hwframe_transfer_data: データをハードウェア サーフェスにコピーするか、ハードウェア サーフェスからデータをコピーします。つまり、GPU と CPU の間でデータをコピーします。これは、GPU から CPU へのコピーに使用されます。
フォーマット
- GPU デコードがハードウェアから読み取られた後のデータ形式のデフォルトのタイプは、CUDA は AV_PIX_FMT_NV12 であり、CPU によってデコードされるデータは通常、AV_PIX_FMT_YUV420P などの YUV データです。
参考
// ref:https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c
// ref: https://github.com/chinahbcq/ffmpeg_hw_decode
// ref: https://www.jianshu.com/p/3ea9ef713211