FFmpeg使用GPU编解码,及在C++代码中实现FFmpeg使用GPU编解码

ops/2025/2/12 22:15:22/

GPU__0">一.使用 GPU 进行编解码的常见方法

FFmpeg 是一个强大的多媒体处理工具,支持使用 GPU 进行编解码以加速视频处理。以下是使用 GPU 进行编解码的常见方法:

GPU_NVENCNVDEC_2">1. 使用 NVIDIA GPU(通过 NVENC/NVDEC)

NVIDIA 提供了 NVENC(编码)和 NVDEC(解码)硬件加速。

GPU__FFmpeg_5">安装支持 GPU 的 FFmpeg

确保安装了支持 NVIDIA 的 FFmpeg 版本,可以通过编译 FFmpeg 时启用 --enable-nvenc--enable-cuda 选项。

常用命令
  • 编码(使用 NVENC)

    ffmpeg -i input.mp4 -c:v h264_nvenc -b:v 5M output.mp4
    

    其中 h264_nvenc 是 H.264 编码器,-b:v 指定视频比特率。

  • 解码(使用 NVDEC)

    ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4
    

    -hwaccel cuda 启用 CUDA 硬件加速解码。

GPU_AMF_21">2. 使用 AMD GPU(通过 AMF)

AMD 提供了 AMF(Advanced Media Framework)用于硬件加速。

安装支持 AMF 的 FFmpeg

编译 FFmpeg 时启用 --enable-amf 选项。

常用命令
  • 编码(使用 AMF)
    ffmpeg -i input.mp4 -c:v h264_amf -b:v 5M output.mp4
    
    h264_amf 是 H.264 编码器。

GPU_Quick_Sync_Video_34">3. 使用 Intel GPU(通过 Quick Sync Video)

Intel 的 Quick Sync Video(QSV)提供硬件加速。

安装支持 QSV 的 FFmpeg

编译 FFmpeg 时启用 --enable-libmfx 选项。

常用命令
  • 编码(使用 QSV)
    ffmpeg -i input.mp4 -c:v h264_qsv -b:v 5M output.mp4
    
    h264_qsv 是 H.264 编码器。

GPU_47">4. 使用 VAAPI(适用于 Intel 和 AMD GPU

VAAPI 是一种通用的硬件加速 API,支持 Intel 和 AMD GPU

安装支持 VAAPI 的 FFmpeg

编译 FFmpeg 时启用 --enable-vaapi 选项。

常用命令
  • 编码(使用 VAAPI)
    ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf 'format=nv12,hwupload' -c:v h264_vaapi -b:v 5M output.mp4
    
    -vaapi_device 指定 VAAPI 设备,-vf 指定视频滤镜。

5. 使用 OpenCL

FFmpeg 也支持通过 OpenCL 进行 GPU 加速。

安装支持 OpenCL 的 FFmpeg

编译 FFmpeg 时启用 --enable-opencl 选项。

常用命令
  • 使用 OpenCL 进行滤镜处理
    ffmpeg -i input.mp4 -vf "hwupload, hwmap, overlay_opencl=10:10, hwmap" output.mp4
    

总结

  • NVIDIA GPU:使用 NVENC/NVDEC,命令如 h264_nvenc
  • AMD GPU:使用 AMF,命令如 h264_amf
  • Intel GPU:使用 QSV 或 VAAPI,命令如 h264_qsvh264_vaapi
  • OpenCL:适用于通用 GPU 加速。

确保硬件和驱动支持相应的编解码器,并根据需要编译 FFmpeg。

GPU_80">二.在C++代码中实现FFmpeg使用GPU编解码

在 C++ 中使用 FFmpeg 进行 GPU 编解码需要结合 FFmpeg 的 API 和 GPU 相关的硬件加速 API(如 NVIDIA 的 NVENC/NVDEC、AMD 的 AMF、Intel 的 QSV 等)。以下是一个简单的示例,展示如何使用 FFmpeg 的 API 结合 NVIDIA 的 NVENC/NVDEC 进行 GPU 编解码。

环境准备

  1. 安装 FFmpeg:确保安装了支持 GPU 加速的 FFmpeg 版本。
  2. 安装 NVIDIA 驱动和 CUDA:确保安装了最新的 NVIDIA 驱动和 CUDA 工具包。
  3. 编译 FFmpeg:编译 FFmpeg 时启用 --enable-nvenc--enable-cuda 选项。

示例代码

以下是一个简单的 C++ 示例,使用 FFmpeg 和 NVENC/NVDEC 进行 GPU 编解码。

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_cuda.h>
}#include <iostream>
#include <stdexcept>void encode(AVCodecContext* enc_ctx, AVFrame* frame, AVPacket* pkt, FILE* outfile) {int ret = avcodec_send_frame(enc_ctx, frame);if (ret < 0) {throw std::runtime_error("Error sending frame to encoder");}while (ret >= 0) {ret = avcodec_receive_packet(enc_ctx, pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return;} else if (ret < 0) {throw std::runtime_error("Error encoding frame");}fwrite(pkt->data, 1, pkt->size, outfile);av_packet_unref(pkt);}
}int main() {av_register_all();avcodec_register_all();const char* filename = "output.h264";FILE* outfile = fopen(filename, "wb");if (!outfile) {std::cerr << "Could not open " << filename << std::endl;return 1;}const AVCodec* codec = avcodec_find_encoder_by_name("h264_nvenc");if (!codec) {std::cerr << "Codec h264_nvenc not found" << std::endl;return 1;}AVCodecContext* c = avcodec_alloc_context3(codec);if (!c) {std::cerr << "Could not allocate video codec context" << std::endl;return 1;}c->bit_rate = 400000;c->width = 640;c->height = 480;c->time_base = (AVRational){1, 25};c->framerate = (AVRational){25, 1};c->gop_size = 10;c->max_b_frames = 1;c->pix_fmt = AV_PIX_FMT_CUDA;if (avcodec_open2(c, codec, NULL) < 0) {std::cerr << "Could not open codec" << std::endl;return 1;}AVFrame* frame = av_frame_alloc();if (!frame) {std::cerr << "Could not allocate video frame" << std::endl;return 1;}frame->format = c->pix_fmt;frame->width = c->width;frame->height = c->height;if (av_frame_get_buffer(frame, 0) < 0) {std::cerr << "Could not allocate the video frame data" << std::endl;return 1;}AVPacket* pkt = av_packet_alloc();if (!pkt) {std::cerr << "Could not allocate AVPacket" << std::endl;return 1;}for (int i = 0; i < 100; i++) {av_frame_make_writable(frame);// Fill frame with test patternfor (int y = 0; y < c->height; y++) {for (int x = 0; x < c->width; x++) {frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;}}frame->pts = i;encode(c, frame, pkt, outfile);}encode(c, NULL, pkt, outfile);fclose(outfile);avcodec_free_context(&c);av_frame_free(&frame);av_packet_free(&pkt);return 0;
}

代码说明

  1. 初始化 FFmpeg:调用 av_register_all()avcodec_register_all() 初始化 FFmpeg。
  2. 查找编码器:使用 avcodec_find_encoder_by_name("h264_nvenc") 查找 NVIDIA 的 H.264 编码器。
  3. 设置编码器参数:设置编码器的宽度、高度、比特率、帧率等参数。
  4. 分配帧和包:使用 av_frame_alloc()av_packet_alloc() 分配帧和包。
  5. 编码帧:使用 avcodec_send_frame()avcodec_receive_packet() 进行编码。
  6. 释放资源:编码完成后,释放编码器上下文、帧和包。

编译和运行

编译时需要链接 FFmpeg 的相关库。例如:

g++ -o gpu_encode gpu_encode.cpp -lavcodec -lavformat -lavutil -lswscale

运行生成的可执行文件,将会生成一个 H.264 编码的视频文件 output.h264

注意事项

  • 确保系统支持 NVIDIA 的 NVENC/NVDEC。
  • 根据实际需求调整编码器参数。
  • 如果需要解码,可以使用 h264_cuvid 解码器,并设置 AVCodecContexthw_device_ctx 为 CUDA 设备上下文。

通过这种方式,你可以在 C++ 中使用 FFmpeg 和 GPU 进行高效的视频编解码


http://www.ppmy.cn/ops/157290.html

相关文章

vue.js v-model实现原理

在 vue.js 3中&#xff0c;通过 v-model 指令可以方便实现表单元素数据双向绑定。实现 v-model 指令元素并不神奇&#xff0c;本质上是一种语法糖。实现原理其实是 v-bind 和 v-on 这两个指令。 v-bind 指令会将表单元素的 value 属性与一个变量绑定&#xff0c;简写为 :属性名…

Flink (十七) :Table API SQL (五) 时区

Flink 为日期和时间提供了丰富的数据类型&#xff0c; 包括 DATE&#xff0c; TIME&#xff0c; TIMESTAMP&#xff0c; TIMESTAMP_LTZ&#xff0c; INTERVAL YEAR TO MONTH&#xff0c; INTERVAL DAY TO SECOND 。 Flink 支持在 session &#xff08;会话&#xff09;级别设置…

Deepseek R1 高性能大语言模型部署指南

文章目录 简介本地部署核心配置要求1. 模型参数与硬件对应表2. 算力需求分析 国产芯片与硬件适配方案1. 国内生态合作伙伴动态2. 国产硬件推荐配置 云端部署替代方案1. 国内云服务商推荐2. 国际接入渠道&#xff08;需魔法或外企上网环境&#xff09; 完整 671B MoE 模型部署&a…

Docker 部署 verdaccio 搭建 npm 私服

一、镜像获取 # 获取 verdaccio 镜像 docker pull verdaccio/verdaccio 二、修改配置文件 cd /wwwroot/opt/docker/verdaccio/conf vim config.yaml config.yaml 配置文件如下&#xff0c;可以根据自己的需要进行修改 # # This is the default configuration file. It all…

神经网络常见激活函数 6-RReLU函数

文章目录 RReLU函数导函数函数和导函数图像优缺点pytorch中的RReLU函数tensorflow 中的RReLU函数 RReLU 随机修正线性单元&#xff1a;Randomized Leaky ReLU 函数导函数 RReLU函数 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…

iPhone 在华销量大幅下挫

iPhone在乔布斯时代缔造的神话在中国正逐渐走向没落&#xff0c;挤牙膏式的升级方式类似于诺基亚的N70系列&#xff0c;毫无新意的创新能力&#xff0c;求稳着陆的经营理念&#xff0c;工艺和美学不再独领风骚&#xff0c;甚至拍照领域和AI增强计算&#xff0c;折叠屏等技术领域…

24.ppt:小李-图书策划方案【1】

目录 NO1234​ NO5678​ NO1234 新建PPT两种方式&#x1f447;docx中视图→导航窗格→标题1/2/3ppt新建幻灯片→从大纲→重置开始→版式设计→主题插入→表格 NO5678 SmartArt演示方案&#xff1a;幻灯片放映→自定义幻灯片放映→新建→选中添加

vue学习5

1.自定义创建项目 2.ESlint代码规范 正规的团队需要统一的编码风格 JavaScript Standard Style 规范说明&#xff1a;https://standardjs.com/rules-zhcn.html 规则中的一部分&#xff1a; (1)字符串使用单引号 ‘aabc’ (2)无分号 const name ‘zs’ (3)关键字后加空格 if(n…