视频拼接融合产品的产品与架构设计(四)分布式GPU运算合并单元

news2024/10/5 16:05:05

上一篇如下
视频拼接融合产品的产品与架构设计(三)内存和显存单元数据迁移

视频合并单元说明

对下面这张图做些说明,视频接入是比较常见,可以说是普通,但是做到接入后随即进行比较重的算法运算,这个在视频领域并不多见,可以说做得好的几乎没有,而要做到在分布式上再把视频接入再进行合并,是比较难的,我们的选择也都在前面几章里面,就是把视频在gpu上处理,在没有nvlink或者其他显卡合并数据的方式下,通过gpu方式下放到内存进行合并。
在这里插入图片描述

嵌入式说明

如果不是x86 架构的模式下,不一定存在显存,即:不是拥有单独分配的显存而是使用共享内存

1 英伟达nvidia的内存体系里面,他是有一体化内存这个概念的,只要查询以下这个api,就可以得到更多信息

#include <cuda_runtime.h>

int main() {
    float* data;
    cudaMallocManaged(&data, size, cudaMemAttachGlobal);
    // ...
    return 0;
}

2 rk3588
RK3588芯片集成的是ARM Mali G610 GPU,该GPU并没有独立的显存(dedicated video RAM),而是采用共享系统内存(Unified Memory Architecture,UMA)的设计。这意味着GPU与CPU共享同一块物理内存(通常是LPDDR4x或LPDDR5)

3 华为昇腾310b4
也是一样没有显存单元,这个时候都是利用其他方式去操作硬件。这是我的另外一篇文章,可以参考一下
华为昇腾CANN使用opencv4.9

编码预置

接下来我们还是说在有显存的情况下,我们必须下放到内存去合并,
我们依然使用ffmpeg去编码,由于使用分布式方式处理图像,并且涉及到多个gpu 设备合并数据,合并单元单独成为一个block, 我们创建好AVFrame,并且直接从gpu 把数据down到AVFrame内存单元中,注意他们各自的linesize, 由于需要硬件编码,我们采用nv12 的数据下载,因此涉及到NV12 的两个平面,Y品面和UV平面,相应的,ffmpeg的数据同样涉及data[0] 和data[1]

AVFrame* NV12Init(int w, int h)
{
	AVFrame* frame = av_frame_alloc(); // 分配 AVFrame 结构体内存
	frame->format = AV_PIX_FMT_NV12; // 设置像素格式为 YUV420P
	frame->width = w; // 设置图像宽度
	frame->height = h; // 设置图像高度
	if (!frame) {
		return NULL;
	}
	int ret = av_frame_get_buffer(frame, 0); // 分配图像数据内存
	if (ret < 0) {
		av_frame_free(&frame); // 释放 AVFrame 结构体内存
		return NULL;
	}
	return frame;
}

转换测试

AVFrame* CreateNV12_2_BGR24Frame(int w1, int h1, int w2, int h2, AVFrame* src_frame)
{
    int w = w1 + w2;
    int h = h1 > h2 ? h1 : h2;
    // 创建SwsContext
    struct SwsContext* sws_ctx = sws_getContext(
        w, h, AV_PIX_FMT_NV12, // 源格式、宽度、高度
        w, h, AV_PIX_FMT_BGR24, // 目标格式、宽度、高度
        SWS_BILINEAR, NULL, NULL, NULL); // 选择缩放算法等

    if (!sws_ctx) {
        // 错误处理
        return NULL;
    }
    // 创建目标AVFrame用于BGR24数据
    AVFrame* dst_frame = av_frame_alloc();
    dst_frame->format = AV_PIX_FMT_BGR24;
    dst_frame->width = w;
    dst_frame->height = h;
    if (av_frame_get_buffer(dst_frame, 0) < 0) {
        // 错误处理
        sws_freeContext(sws_ctx);
        return NULL;
    }

    // 执行转换
    sws_scale(sws_ctx, src_frame->data, src_frame->linesize,
        0, src_frame->height, dst_frame->data, dst_frame->linesize);
    sws_freeContext(sws_ctx);
    return dst_frame;

}

单元测试

int main()
{

    cv::cuda::setDevice(0);

    cv::Mat image1 = cv::imread("d:/left.jpg");
    cv::Mat image2 = cv::imread("d:/right.ipg");


    if (image1.empty() || image2.empty()) {
        std::cerr << "Failed to load input image!" << std::endl;
        return -1;
    }

    int w1 = image1.cols;
    int h1 = image1.rows;

    int w2 = image2.cols;
    int h2 = image2.rows;


    cv::cuda::GpuMat g1;
    g1.upload(image1);
    cv::cuda::GpuMat g2;
    g2.upload(image2); 

    void* c1 = createNV12Context(w1, h1, 0);
    void* c2 = createNV12Context(w2, h2, 0);
    swscale_gpu(c1, g1.data, g1.step);
    swscale_gpu(c2, g2.data, g2.step);

    w2 = 0;
    h2 = 0;
    AVFrame* frame  = NV12Init(w1+w2, h1>h2?h1:h2);

    download_gpu(c1, NULL, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1]);
    
    AVFrame* dst_frame = CreateNV12_2_BGR24Frame(w1, h1, w2, h2, frame);

    // 创建cv::Mat对象,注意:OpenCV使用BGR通道顺序
    cv::Mat image(dst_frame->height, dst_frame->width, CV_8UC3, dst_frame->data[0], dst_frame->linesize[0]);

    cv::Mat imdst;
    cv::resize(image, imdst, cv::Size(image.cols / 4, image.rows / 4), 0, 0, cv::INTER_LINEAR);

    cv::imshow("BGR Image", imdst);

    //av_freep(&frame->data[0]);
    av_frame_free(&frame);

    //av_freep(&dst_frame->data[0]);
    av_frame_free(&dst_frame);
    cv::waitKey(0);

}

后续的改变

后面我会改变产品形态,准备写视频湖仓一体平台,着手创建这个产品,视频拼接和融合只是一个小功能,也不打算自己做这种产品了,而是做出工具来让其他专业或者非专业的人来做,以插件的模式来提供便利。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海外抖音TK自动挂机,手机全自动挂机,每天轻松搞2张

海外抖音TK自动挂机&#xff0c;手机全自动挂机&#xff0c;每天轻松搞2张 课程获取方式&#xff1a; https://zzmbk.com/

linux系统部署Oracle11g:netca成功启动后1521端口未能启动问题

一、问题描述 执行netca命令&#xff0c;进入图形化界面&#xff0c;进行Oracle端口监听设置 #终端输入命令 netca 最终提示设置成功&#xff1a; 但是我们进行下一步“创建数据库”的时候会报错&#xff0c;说数据库端口1521未开启&#xff01; 二、问题处理 使用命令查看开…

ubuntu安装samba实现共享文件windows可查看ubuntu中的文件

samba的作用&#xff1a;实现共享linux/ubuntu系统中的文件&#xff0c;在windows直接查看操作ubuntu/linux中的文件、文件夹 1、安装samba sudo apt-get install samba如果不能安装samba&#xff0c;则更新apt-get sudo apt-get upgrade sudo apt-get update sudo apt-get d…

数据库攻防之MySQL

MySQL 是最流行的关系型数据库&#xff0c;与此同时也是 web 应用中最好的关系型数据库管理应用软件。我们在渗透过程中碰到的 PHP 站点大部分都会搭配 MySQL 数据库&#xff0c;因此它是红队攻防中最常遇到的数据库。 0x01 MySQL简介 MySQL 是典型的关系型数据库&#xff0c;…

Go 1.23 Release Notes编写方式改进!

2024.5.22日&#xff0c;Go 1.23 feature冻结&#xff01;Go团队开始Go 1.23rc1的冲刺&#xff0c;截至发文时&#xff0c;Go 1.23 milestone已经完成59%(https://github.com/golang/go/milestone/212)&#xff0c;还有188个open的issue待解决。 Go 1.23有哪些新feature&#x…

【java程序设计期末复习】chapter1 java入门

java入门 java的特点 &#xff08;1&#xff09;简单 Java要比C简单&#xff0c;C中许多容易混淆的概念&#xff0c;或者被Java弃之不用了&#xff0c;或者以一种更清楚更容易理解的方式实现 &#xff08;2&#xff09;面向对象 Java是面向对象的编程语言 &#xff08;3&…

[Vulnhub]Vulnix 通过NFS挂载+SSH公钥免密登录权限提升

端口扫描 Server IP AddressPorts Open192.168.8.103TCP:22/tcp, 25/tcp, 79/tcp, 110/tcp, 111/tcp, 143/tcp, 512/tcp, 513/tcp, 514/tcp, 993/tcp, 995/tcp, 2049/tcp, 37522/tcp, 42172/tcp, 43219/tcp, 47279/tcp, 54227/tcp $ nmap -p- 192.168.8.103 -sV -sC --min-ra…

学 Python 具体能干什么?

Python 是一种功能强大、用途广泛的编程语言&#xff0c;因其简洁易读的语法和丰富的库生态系统而备受欢迎。学习 Python后&#xff0c;你可以从事以下几方面的工作&#xff1a; 1. Web 开发 Python 有很多流行的 Web 框架&#xff0c;如&#xff1a; Django&#xff1a;一个…

导弹初识(一)

目录 导弹初识1 导弹是什么2 导弹的分类2.1 按飞行方式2.2 按发射/目标2.2.1 空空导弹2.2.1 空地导弹2.2.1 地空导弹2.2.1 地地导弹 2.3 按打击目标 3.实例3.1 防空导弹3.2 低空防空导弹武器系统 本文节选自 zh&#xff0c;还有百度百科 导弹初识 1 导弹是什么 导弹两个字拆…

Spring—Spring配置文件概念及应用(实现一个图形验证码)

文章目录 配置文件配置文件作用配置文件的格式配置文件优先级说明配置文件书写代码的格式yml文件代码的格式 Value注解 properties 缺点分析properties VS yml实现一个验证码程序 配置文件 配置文件作用 整个项目的重要信息我们都会配置在配置文件中&#xff0c;比如说我们数…

力扣刷题--448. 找到所有数组中消失的数字【简单】

题目描述 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输出&#xff1a;[5,6…

计算机网络基本概念

文章目录 情景带入一些基本概念网络网络编程&#xff1a;7层网络模型OSI&#xff1a;TCP/IP Protocol Architecture Layers与OSI的对应关系SocketClient-Server Application报文段&#xff1a;传输协议&#xff1a;Mac地址IP地址端口URL 情景带入 随着时代的发展&#xff0c;我…

数据库系统原理实验报告6 | 视图

整理自博主本科《数据库系统原理》专业课自己完成的实验报告&#xff0c;以便各位学习数据库系统概论的小伙伴们参考、学习。 专业课本&#xff1a; ​ ———— 本次实验使用到的图形化工具&#xff1a;Heidisql ​ 目录 一、实验目的 二、实验内容 1&#xff0e;根据EDUC数…

RTOS(3)极简ARM架构与汇编

1.掌握八条汇编指令即可 读内存loadLDR R0&#xff0c;[addrA]写内存storeSTR R0&#xff0c;[addrA]加ADD R0&#xff0c;R1&#xff0c;R2减SUB R0&#xff0c;R1&#xff0c;R2比较CMP R0&#xff0c;R1跳转B / BL入栈PUSH { R3&#xff0c;LR }出…

知能行——考研数学利器

知能行使用体验全记录 首先&#xff0c;我先介绍一下自己&#xff0c;我是2018级的&#xff0c;2022年6月毕业&#xff0c;本科沈阳工业大学&#xff08;双非&#xff09;&#xff0c;今年二战&#xff0c;专业课自动控制原理&#xff0c;数二英二&#xff0c;目标是江南大学控…

深度学习——自己的训练集——图像分类(CNN)

图像分类 1.导入必要的库2.指定图像和标签文件夹路径3.获取文件夹内的所有图像文件名4.获取classes.txt文件中的所有标签5.初始化一个字典来存储图片名和对应的标签6.遍历每个图片名的.txt文件7.随机选择一张图片进行展示8.构建图像的完整路径9.加载图像10.检查图像是否为空 随…

QT安装和配置[安装注意点][QT找不到python27.dll][缩小空间]

安装注意点 本文摘录于&#xff1a;https://blog.csdn.net/Python_0011/article/details/131699443只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 双击"qt-online-installer-windows-x64-4.8.0.exe"文件后输入账号选择如下控…

最简单的AI训练方法-RAG增强检索原理

文章目录 1、RAG&#xff08; Retrieval-Augmented Generation&#xff09;2、RAG的基本原理3、简化训练流程4、RAG增强检索原理图 1、RAG&#xff08; Retrieval-Augmented Generation&#xff09; RAG&#xff08; Retrieval-Augmented Generation&#xff09;是一种结合了检…

某某某加固系统分析

某某某加固系统内核so dump和修复&#xff1a; 某某某加固系统采取了内外两层native代码模式&#xff0c;外层主要为了保护内层核心代码&#xff0c;从分析来看外层模块主要用来反调试&#xff0c;释放内层模块&#xff0c;维护内存模块的某些运行环境达到防止分离内外模块&am…

【C语言回顾】编译和链接

前言1. 编译2. 链接结语 上期回顾: 【C语言回顾】文件操作 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【C语言学习】 前言 各位小伙伴大家好&#xff01;上期小编给大家讲解了C语言中的文件操作&#xff0c;接下来我们讲解一下编译和链接&#xff01; 1. 编译 预处理…