人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統 > 硬件軟件教程 > 詳細頁面

如何用FFMPEGAPI做一般的硬解碼與軟解碼?

如何用FFMPEGAPI做一般的硬解碼與軟解碼?

更新時間:2023-07-02 文章作者:未知 信息來源:網絡 閱讀次數:

顯卡是個人計算機基礎的組成部分之一,將計算機系統需要的顯示信息進行轉換驅動顯示器,并向顯示器提供逐行或隔行掃描信號,控制顯示器的正確顯示,是連接顯示器和個人計算機主板的重要組件,是“人機”的重要設備之一,其內置的并行計算能力現階段也用于深度學習等運算。

寫在前面

本文將介紹如何使用FFMPEG API進行硬件解碼。如果您不熟悉解碼過程,請先閱讀:

我是Xiaobei Dig Haha:視頻和視頻幀:FFMPEG CPU解碼API簡介

圖標

作者之前也看到過類似的問題:視頻硬解碼和軟解碼有什么區別?

本質上沒有什么區別,該芯片用于執行編計算。

“軟”和“硬”一詞很容易引起歧義。從本質上講,使用CPU通用計算單元(無論是Intel還是AMD)都是一種軟解決方案。使用專用芯片模塊(GPU,QSV等)是一個很難的解決方案。

因此產生了差異:基礎接口不同,指令集不同,硬件驅動程序也不同。由此產生的問題很明顯:

首先,因為CPU是通用計算單元,所以接口是通用的,并且可移植性好;專用芯片模塊不能移植和互操作;其次,由于CPU接口是通用的,因此編中的許多細節都便于開發人員進行修改。專用的芯片模塊,接口和驅動程序都是由不同的制造商提供的,并且其中許多都是非開源的,因此控制內部細節更加困難。最后,在實際測試中,當前使用CPU進行編碼和解碼的效果將優于專用芯片模塊。但是,可以通過優化算法和芯片來解決此問題。這是制造商的業務,我們無法控制。

在現實生活中,是選擇硬解碼還是軟解碼?

這取決于不同的情況。例如:

CPU過剩,需要對解碼過程進行精確控制,對解碼算法進行優化,對通用性要求較高,直接使用軟解決方案(即CPU解碼);如果還有其他編芯片/模塊,而CPU不足,則必須切換到硬解碼(即專用芯片解碼)。

本文將介紹如何使用FFMPEG API進行常規的硬解碼。 “常規硬解碼”是指主流FFMEG支持的硬解碼類型。作者將結合自己在QSV和CUDA解碼方面的經驗,最后分享我所涉足的一些陷阱以及一些擴展方面的小問題。

I。 FFMPEG支持的硬解碼

首先,讓我們看一下FFMPEG原生支持哪些硬解碼類型。列出AVHWDeviceType(libavutil / hwcontext.h)本機支持的所有硬解碼類型:

enum AVHWDeviceType {
    AV_HWDEVICE_TYPE_NONE,
    AV_HWDEVICE_TYPE_VDPAU,
    AV_HWDEVICE_TYPE_CUDA,
    AV_HWDEVICE_TYPE_VAAPI,
    AV_HWDEVICE_TYPE_DXVA2,
    AV_HWDEVICE_TYPE_QSV,
    AV_HWDEVICE_TYPE_VIDEOTOOLBOX,
    AV_HWDEVICE_TYPE_D3D11VA,
    AV_HWDEVICE_TYPE_DRM,
    AV_HWDEVICE_TYPE_OPENCL,
    AV_HWDEVICE_TYPE_MEDIACODEC,
};

上面的AV_HWDEVICE_TYPE_CUDA是作者當前正在使用的CUDA,是NVIDIA的硬件加速庫,而AV_HWDEVICE_TYPE_QSV是以前的QSV,是英特爾提供的一組硬件加速解決方案。

ffmpeg解碼流程_ffmpeg調用顯卡編解碼_ffmpeg多線程解碼

那么,您如何知道當前FFMPEG支持哪些硬件庫?

您可以通過命令行查看它:ffmpeg -hwaccel。在硬件加速方法中:您可以在下面看到當前的FFMPEG集成硬解碼庫。

然后,如果發現所需的硬件庫不在當前的FFMPEG中,該怎么辦?

答案是:您可能需要自己重新編譯源代碼。每個硬件解碼庫的集成方法都不同。如果是QSV,請參見

我是小貝挖哈哈:視頻和視頻幀:FFMPEG + Intel QSV硬件解決方案環境安裝文章

圖標

如果它是另一個硬解碼庫,請自己在Internet上搜索。 (作者將在稍后添加如何將CUDA庫集成到FFMPEG中,敬請期待)

II。 FFMPEG硬解碼API

硬解碼步驟類似于軟解碼步驟。作者繪制了FFMPEG硬件解碼流程圖:圖中的橙色部分是硬解碼中包含的部分,軟解碼中沒有。該圖的靈感來自博客“ FFmpeg示例硬件解碼hw_decode”,這篇文章是推薦的,簡潔的和詳細的。

ffmpeg調用顯卡編解碼

ffmpeg調用顯卡編解碼

FFMPEG硬解碼流程圖

接下來,我將詳細介紹上圖的橙色部分以及與硬解碼有關的API函數。

硬解碼步驟1.查找硬解碼codec編實現的名稱。該名稱在編碼器和之間是全局唯一的(但編碼器和可以共享相同的名稱)。這是從用戶角度查找編的主要方法。

實際上,FFMPEG中的每個編都是一種結構,它維護自己的信息,特定功能和其他信息。例如,英特爾的QSV(在libavcodec / qsvdec_h264 5. c中)為:

AVCodec ff_h264_qsv_decoder = {
    .name = "h264_qsv",
    .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
    .priv_data_size = sizeof(QSVH2645Context),
    .type = AVMEDIA_TYPE_VIDEO,
    .id = AV_CODEC_ID_H264,
    .init = qsv_decode_init,
    .decode = qsv_decode_frame,
    .flush = qsv_decode_flush,
    .close = qsv_decode_close,
    .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
    .priv_class = &class,
    .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
 AV_PIX_FMT_P010,
 AV_PIX_FMT_QSV,
 AV_PIX_FMT_NONE },
    .hw_configs = ff_qsv_hw_configs,
    .bsfs = "h264_mp4toannexb",
    .wrapper_name = "qsv",
};

ffmpeg調用顯卡編解碼_ffmpeg解碼流程_ffmpeg多線程解碼

您可以看到此編支持的編ID為AV_CODEC_ID_H264,支持的目標像素格式為{AV_PIX_FMT_NV12,AV_PIX_FMT_P010,AV_PIX_FMT_QSV,AV_PIX_FMT_NONE}。

是的,硬件與通用不同,只能支持有限的目標像素格式。

讓我們看一下CUDA(在libavcodec / cuviddec.c中)。同樣,它只能支持有限的目標像素格式:

 AVCodec ff_##x##_cuvid_decoder = { \
        .name = #x "_cuvid", \
        .long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
        .type = AVMEDIA_TYPE_VIDEO, \
        .id = AV_CODEC_ID_##X, \
        .priv_data_size = sizeof(CuvidContext), \
        .priv_class = &x##_cuvid_class, \
        .init = cuvid_decode_init, \
        .close = cuvid_decode_end, \
        .decode = cuvid_decode_frame, \
        .receive_frame = cuvid_output_frame, \
        .flush = cuvid_flush, \
        .bsfs = bsf_name, \
        .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
        .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
 AV_PIX_FMT_NV12, \
 AV_PIX_FMT_P010, \
 AV_PIX_FMT_P016, \
 AV_PIX_FMT_NONE }, \
        .hw_configs = cuvid_hw_configs, \
        .wrapper_name = "cuvid", \
    };

硬解碼步驟2.找到硬解目標像素

在上一節中,我了解到一個事實:硬解碼編支持的目標像素是有限的,并且它們可能不相同。因此,在找到經過硬解碼的編之后,您必須設置其目標像素(像素格式)。

enum AVHWDeviceType {
 AV_HWDEVICE_TYPE_NONE,
 AV_HWDEVICE_TYPE_VDPAU,
 AV_HWDEVICE_TYPE_CUDA,
 AV_HWDEVICE_TYPE_VAAPI,
 AV_HWDEVICE_TYPE_DXVA2,
 AV_HWDEVICE_TYPE_QSV,
 AV_HWDEVICE_TYPE_VIDEOTOOLBOX,
 AV_HWDEVICE_TYPE_D3D11VA,
 AV_HWDEVICE_TYPE_DRM,
 AV_HWDEVICE_TYPE_OPENCL,
 AV_HWDEVICE_TYPE_MEDIACODEC,
 AV_HWDEVICE_TYPE_VULKAN,
};

此類型和名稱之間的關系表要簡單得多。它由FFMPEG代碼中的hw_type_names關系表維護(在libavutil / hwcontext.c文件中定義):

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",
  [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
};

 typedef struct AVCodecHWConfig {
 /**
 * A hardware pixel format which the codec can use. !!!硬解碼codec支持的像素格式!!!
 */
 enum AVPixelFormat pix_fmt;
 /**
 * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible
 * setup methods which can be used with this configuration.
 */
 int methods;
 /**
 * The device type associated with the configuration.
 *
 * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and
 * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused.
 */
 enum AVHWDeviceType device_type;
} AVCodecHWConfig;


本文來自本站,轉載請注明本文網址:
http://www.pc-fly.com/a/shenmilingyu/article-372911-1.html



溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

網站地圖xml | 網站地圖html
主站蜘蛛池模板: 香港 | 同江市| 彭泽县| 华池县| 汽车| 库伦旗| 武清区| 深圳市| 兴化市| 桐乡市| 柘城县| 西宁市| 石首市| 郁南县| 郓城县| 赞皇县| 牡丹江市| 徐汇区| 繁昌县| 名山县| 霍州市| 绿春县| 交城县| 盘锦市| 顺义区| 蛟河市| 定边县| 依安县| 隆回县| 延边| 论坛| 兴安盟| 虹口区| 张家界市| 吉安市| 明光市| 读书| 嘉义市| 略阳县| 凤冈县| 都昌县|