ffmpeg cuda硬件解码后处理使用opengl渲染,全硬件流程

这篇具有很好参考价值的文章主要介绍了ffmpeg cuda硬件解码后处理使用opengl渲染,全硬件流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 ffmpeg 硬件解码

使用硬件解码后不要transfer到内存,使用cuda转化nv12 -> bgr24
转化完毕后cuda里面存了一份bgr24

2 gpumat 和 cuda 互操作

如果需要opencv gpumat直接使用cuda内存,则可以手动构造gpumat
可以使用gpumat的各种函数

uchar3* cuda_rgb_data; // 假设这是您的CUDA内存中存储RGB数据的指针
int width, height; // 图像的宽和高
cv::cuda::GpuMat gpu_rgb(cuda_rgb_data, height, width, CV_8UC3, cudaStream_t stream = 0);
uchar3* cuda_rgb_data_r = reinterpret_cast<uchar3*>(gpu_rgb.ptr(0)); // 获取R通道指针
uchar3* cuda_rgb_data_g = reinterpret_cast<uchar3*>(gpu_rgb.ptr(1)); // 获取G通道指针
uchar3* cuda_rgb_data_b = reinterpret_cast<uchar3*>(gpu_rgb.ptr(2)); // 获取B通道指针

ptr(0)、ptr(1)和ptr(2)分别获取了R、G、B三个通道的数据指针。
使用reinterpret_cast将uchar指针转换为uchar3,便于在CUDA内核中以RGB像素的形式访问。
在CUDA内核中使用GpuMat数据:
在CUDA内核函数中,直接使用获取的CUDA指针访问GpuMat中的RGB数据。

__global__ void cuda_kernel(uchar3* cuda_rgb_data_r, uchar3* cuda_rgb_data_g, uchar3* cuda_rgb_data_b, ...)
{
    // 假设 blockIdx.x 和 threadIdx.x 分别表示当前线程处理的图像位置的行和列索引
    int row = blockIdx.x * blockDim.x + threadIdx.x;
    int col = blockIdx.y * blockDim.y + threadIdx.y;

    if (row < height && col < width) // 检查索引是否有效
    {
        // 通过指针访问GpuMat中的RGB数据
        uchar3 rgb_pixel = make_uchar3(cuda_rgb_data_r[row * width + col].x,
                                      cuda_rgb_data_g[row * width + col].y,
                                      cuda_rgb_data_b[row * width + col].z);

        // ... 使用rgb_pixel进行CUDA内核计算 ...
    }
}

至此,将GpuMat中的RGB数据暴露给了CUDA内核,可以直接在内核中进行访问和处理。

需要显示时,有两种方式,互操作opengl渲染,不用把cuda内存

3 cuda 与 opengl 互操作

1 首先初始化GLFW并创建一个OpenGL窗口。
2 注册并初始化一个OpenGL纹理,用于接收CUDA处理后的RGB图像数据。
3 使用CUDA-OpenGL Interop库注册这个OpenGL纹理,以便CUDA可以直接访问和写入。
4 在CUDA端,假设有一个内核cuda_process_rgb已经处理了RGB图像,并将结果存储在设备内存d_processed_img中。
5 使用cudaGraphicsMapResources、 cudaGraphicsSubResourceGetMappedArray和cudaMemcpyToArray将CUDA端的RGB图像数据复制到已注册的OpenGL纹理中。
6 在主渲染循环中,绑定纹理并使用一个简单的四边形以及相应的着色器程序来渲染纹理。
以下是示例代码,并不完整

#include <iostream>
#include <vector>
#include <GLFW/glfw3.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

// CUDA kernel to process RGB image (omitted for brevity)
__global__ void cuda_process_rgb(uchar3* d_img, int width, int height);

int main()
{
    // Initialize GLFW and create an OpenGL window
    if (!glfwInit())
    {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "CUDA-OpenGL Interop Example", nullptr, nullptr);
    if (!window)
    {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    // Initialize GLEW (if needed)
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
        std::cerr << "Failed to initialize GLEW" << std::endl;
        glfwTerminate();
        return -1;
    }

    // Create an OpenGL texture for rendering
    GLuint gl_tex;
    glGenTextures(1, &gl_tex);
    glBindTexture(GL_TEXTURE_2D, gl_tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Register the OpenGL texture for CUDA-OpenGL interop
    cudaGraphicsResource* cuda_tex_res;
    cudaGraphicsGLRegisterImage(&cuda_tex_res, gl_tex, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsSurfaceLoadStore);

    // CUDA processing: assume you have a pre-allocated CUDA device memory buffer for the processed RGB image
    uchar3* d_processed_img;
    cudaMalloc(&d_processed_img, width * height * sizeof(uchar3));
    // Call your CUDA kernel to process the image (omitted here)
    // cuda_process_rgb<<<...>>>(d_processed_img, width, height);

    // Copy the processed RGB image from CUDA to the registered OpenGL texture
    cudaArray* cu_array;
    cudaGraphicsMapResources(1, &cuda_tex_res, 0);
    cudaGraphicsSubResourceGetMappedArray(&cu_array, cuda_tex_res, 0, 0);
    cudaMemcpyToArray(cu_array, 0, 0, d_processed_img, width * height * sizeof(uchar3), cudaMemcpyDeviceToDevice);
    cudaGraphicsUnmapResources(1, &cuda_tex_res, 0);

    // Set up a simple shader program and vertex data for rendering a full-screen quad (omitted for brevity)

    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        // Bind the texture and render a full-screen quad using your shader program
        // ...

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Clean up resources
    cudaFree(d_processed_img);
    cudaGraphicsUnregisterResource(cuda_tex_res);
    glDeleteTextures(1, &gl_tex);
    glfwTerminate();

    return 0;
}

总结

整个流程是一旦数据到了cuda内核,就不要轻易下载到内存,直接在cuda里面进行操作,一直到渲染完毕,后面在给出完整的代码示例文章来源地址https://www.toymoban.com/news/detail-849033.html

到了这里,关于ffmpeg cuda硬件解码后处理使用opengl渲染,全硬件流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [音视频处理] FFmpeg使用指北1-视频解码

    本文将详细介绍如何使用ffmpeg 4.4在C++中解码多种格式的媒体文件,这些媒体文件可以是视频、视频流、图片,或是桌面截屏或USB摄像头的实时图片。解码文件后,还将每帧图片转换为OpenCV的Mat格式以供后续使用。 目录 1 基于ffmpeg的媒体文件解码 1.1 简介 1.2 详细代码 2 ffmpeg函

    2024年02月07日
    浏览(46)
  • 【FFmpeg在Intel GPU上的硬件编解码实现】

    以下文章是在开发过程中参考的比较有意义的文章,供大家学习和参考~~ https://zhuanlan.zhihu.com/p/62246545 ##FFMPEG+Intel QSV硬解的环境安装篇## https://zhuanlan.zhihu.com/p/372361709 ##Ubuntu20.04 ffmpeg添加 Intel核显QSV加速支持## https://blog.csdn.net/weixin_47407737/article/details/128933104 ##FFmpeg集成qsv的编译

    2024年02月15日
    浏览(25)
  • FFmpeg+SDL实时解码和渲染H264视频流

    之前实现了Android手机摄像头数据的TCP实时传输,今天接着聊聊,如何在PC端把接收到的H264视频流实时解码并渲染出来。这次使用的语言是C++,框架有FFmpeg和SDL2。 解码部分使用FFmpeg,首先,需要初始化H264解码器: 然后,使用创建TCP连接到我们的Android端,读取数据包: 再把每

    2024年02月13日
    浏览(33)
  • FFmpeg编解码流程解读--视频解码1

    首先我们知道ffmpeg是一个开源的音视频编解码,封装和解封装的工具。具体的下载方式这里不多赘述(感兴趣百度自行下载源码)。这里主要将编解码。ffmpeg音视频编解码依赖libavcodec。其为我们提供一套架构,其中包含了编解码器。这里主要介绍我们常用的一些API接口去处理

    2023年04月08日
    浏览(25)
  • linux下ffmpeg调用GPU硬件解码(VDPAU/VAAPI)保存文件

    本文讲解在linux下面,如何通过ffmpeg调用GPU硬件解码,并保存解码完的yuv文件。 其实,ffmpeg自带的例子hw_decode.c这个文件,就已经能满足要求了,因此,本文就尝试讲解以下hw_decode这个例子。hw_decode.c可以调用VDPAU硬件解码,也可以调用VAAPI硬件解码,下面依次讲解如何进行操

    2024年02月19日
    浏览(30)
  • 玩转rk3588(六):rk3588使用ffmpeg实现硬件解码,解决opencv中VideoCapture获取网络摄像头视频时,一直在open时返回false的问题(一)

    目录 0、前言 1、开发环境 2、安装rkmpp 3、安装x264 4、安装libdrm 5、安装ffmpeg 6、相关报错 1)libdrm编译过程中报错

    2024年02月03日
    浏览(33)
  • FFmpeg 在Windows环境下 Intel ,Nvidia ,AMD 硬件加速编解码支持列表

    目录 前言 一. Intel 编解码硬件支持列表   1. Encode 编码硬件支持列表 (1)Intel 独显编码硬件支持列表 (2)第 11,12,13 代 Intel 处理器编码硬件支持列表 (3)第 10 代 Intel 处理器编码硬件支持列表 (4)第 9 代 Intel 处理器编码硬件支持列表 (5)第 5,6,7,8 代 Intel 处理器

    2024年02月03日
    浏览(33)
  • FFMpeg 实现视频解码、编码、转码流程详解

    打开FFmpeg源码,会发现有一系列libavxxx的模块,这些模块很好地划分了代码的结构和分工。 libavformat,format,格式封装 libavcodec,codec,编码、解码 libavutil,util,通用音视频工具,像素、IO、时间等工具 libavfilter,filter,过滤器,可以用作音视频特效处理 libavdevice,device,设备

    2024年02月11日
    浏览(28)
  • FFmpeg音频解码流程详解及简单demo参考

            本文主要讲解FFmpeg的音频解码具体流程,API使用。最后再以一个非常简单的demo演示将一个mp3格式的音频文件解码为原始数据pcm文件。 本文主要基于FFmpeg音频解码新接口。    API接口简单大体讲解如下:         这一步是ffmpeg的任何程序的第一步都是需要先注

    2023年04月08日
    浏览(30)
  • 【FFmpeg+Qt开发】解码流程 详细分析+代码示例

    一、FFMPEG 概述 ​二、FFMPEG 解码 2.1解码流程 2.2解码示例 FFmpeg 是一套可以用来记录、转换,数字音频、视频,并能将其转化为流的开源计算机程序。 FFmpeg 采用 LGPL 或 GPL 许可证;它提供了录制、转换以及流化音视频的完整解决案;它还包含了非常先进的音频 视频编解码库

    2024年01月23日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包