C++ は ffmpeg を使用して v モジュールをデコードし、CPU デコード、amd64 プラットフォームでの cuda デコード、NX プラットフォームでの Nvmpi デコードをサポートします。

倉庫コード: 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_formatget_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

おすすめ

転載: blog.csdn.net/stallion5632/article/details/125524086