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

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

视频合并单元说明

对下面这张图做些说明,视频接入是比较常见,可以说是普通,但是做到接入后随即进行比较重的算法运算,这个在视频领域并不多见,可以说做得好的几乎没有,而要做到在分布式上再把视频接入再进行合并,是比较难的,我们的选择也都在前面几章里面,就是把视频在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);

}

后续的改变

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索PyImGui:高效可交互图形界面的Python实现

简介 Pyimgui 是一个基于 Cython 的 Python 绑定层&#xff0c;它将功能强大的用户界面库 Dear ImGui 无缝集成到 Python 环境中。它使 Python 开发人员能够轻松地创建交互式图形用户界面 (GUI)&#xff0c;同时充分利用 Dear ImGui 的丰富功能集。 下图为用Dear ImGui开的GU…

Android 使用 ActivityResultLauncher 申请权限

前面介绍了 Android 运行时权限。 其中&#xff0c;申请权限的步骤有些繁琐&#xff0c;需要用到&#xff1a;ActivityCompat.requestPermissions 函数和 onRequestPermissionsResult 回调函数&#xff0c;今天就借助 ActivityResultLauncher 来简化书写。 步骤1&#xff1a;创…

2024年5月26日 (周日) 叶子游戏新闻

资深开发者&#xff1a;3A游戏当前处于一种尴尬的中间地带游戏行业整体&#xff0c;尤其是3A游戏正处于艰难时期。尽管2023年3A游戏佳作频出&#xff0c;广受好评&#xff0c;但居高不下的游戏开发成本&#xff08;传闻《漫威蜘蛛侠2》的制作成本高达3亿美元&#xff09;正严重…

提高Java编程效率:ArrayList类的使用技巧

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

虹科Pico汽车示波器 | 免拆诊断案例 | 2012 款雪佛兰科鲁兹车偶尔多个故障灯异常点亮

故障现象 一辆2012款雪佛兰科鲁兹车&#xff0c;搭载1.8 L 发动机&#xff0c;累计行驶里程约为9.6万km。该车组合仪表上的发动机故障灯、ABS故障灯及动力转向故障灯偶尔异常点亮&#xff0c;同时发动机转速表和发动机冷却液温度表的指针会突然归零&#xff0c;严重时发动机无…

【Linux 网络】网络基础(三)(网络层协议:IP 协议)

在复杂的网络环境中确定一个合适的路径。 一、TCP 与 IP 的关系 IP 层的核心作用是定位主机&#xff0c;具有将数据从主机 A 发送到主机 B 的能力&#xff0c;但是能力并不能保证一定能够做到&#xff0c;所以这时就需要 TCP 起作用了&#xff0c;TCP 可以通过超时重传、拥塞控…

[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…

Nginx实战(安装部署、常用命令、反向代理、负载均衡、动静分离)

文章目录 1. nginx安装部署1.1 windows安装包1.2 linux-源码编译1.3 linux-docker安装 2. nginx介绍2.1 简介2.2 常用命令2.3 nginx运行原理2.3.1 mater和worker2.3.3 Nginx 的工作原理 2.4 nginx的基本配置文件2.4.1 location指令说明 3. nginx案例3.1 nginx-反向代理案例013.…

python基于深度学习的聊天机器人设计

python基于深度学习的聊天机器人设计 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 登录注册功能 用户在没有登录自己的用户名之前只能浏览本网站的首页&#xff0c;想要使用其他功能都…

ROCm上来自Transformers的双向编码器表示(BERT)

14.8. 来自Transformers的双向编码器表示&#xff08;BERT&#xff09; — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2l#save def get_tokens_and_segments(tokens_a, tokens_bNone):""&qu…

html中被忽略的简单标签

1&#xff1a; alt的作用是在图片不能显示时的提示信息 <img src"https://img.xunfei.cn/mall/dev/ifly-mall-vip- service/business/vip/common/202404071019208761.jp" alt"提示信息" width"100px" height"100px" /> 2&#…

CTF之Web_python_block_chain

这种题对于我来说只能看大佬的wp&#xff08;但是这一题是wp都看不懂&#xff0c;只能表达一下我的理解了&#xff09; &#xff08;最后有简单方法&#xff0c;前面一种没看懂没关系&#xff09; 下面这一部分是首页的有用部分 访问/source_code,得到源码&#xff1a; # -*-…

mysql之递归sql

mysql之递归sql 递归sql在一些公司是不允许使用的&#xff0c;会涉及数据库压力&#xff0c;所以会在代码里递归查询&#xff0c;但有些公司开发流程没有规定&#xff0c;且数据库数据量不大&#xff0c;之前写过好几遍了&#xff0c;老是记不住&#xff0c;记录一下 通过父级…

LiveGBS流媒体平台GB/T28181用户手册-版本信息:查看机器码、切换查看流媒体服务

LiveGBS流媒体平台GB/T28181用户手册--版本信息:查看机器码、切换查看流媒体服务 1、版本信息1.1、查看机器码1.2、多个流媒体服务1.3、提交激活 2、搭建GB28181视频直播平台 1、版本信息 版本信息页面&#xff0c;可以查看到信令服务 流媒体服务相关信息&#xff0c;包含硬件…

MySQL--存储引擎

一、存储引擎介绍 1.介绍 存储引擎相当于Linux的文件系统&#xff0c;以插件的模式存在&#xff0c;是作用在表的一种属性 2.MySQL中的存储引擎类型 InnoDB、MyISAM、CSV、Memory 3.InnoDB核心特性的介绍 聚簇索引、事务、MVCC多版本并发控制、行级锁、外键、AHI、主从复制特…

网络安全等级保护:正确配置 Linux

正确配置 Linux 对Linux安全性的深入审查确实是一项漫长的任务。原因之一是Linux设置的多样性。用户可以使用Debian、Red Hat、Ubuntu或其他Linux发行版。有些可能通过shell工作&#xff0c;而另一些则通过某些图形用户界面&#xff08;例如 KDE 或 GNOME&#xff09;工作&…

零基础学Java第二十三天之网络编程Ⅱ

1. InetAddress类 用来表示主机的信息 练习&#xff1a; C:\Windows\system32\drivers\etc\ hosts 一个主机可以放多个个人网站 www.baidu.com/14.215.177.37 www.baidu.com/14.215.177.38 www.taobao.com/183.61.241.252 www.taobao.com/121.14.89.253 2. Socket 3.…

细粒度图像分类论文(AAM模型方法)阅读笔记

细粒度图像分类论文阅读笔记 摘要Abstract1. 用于细粒度图像分类的聚合注意力模块1.1 文献摘要1.2 研究背景1.3 本文创新点1.4 计算机视觉中的注意力机制1.5 模型方法1.5.1 聚合注意力模块1.5.2 通道注意力模块通道注意力代码实现 1.5.3 空间注意力模块空间注意力代码实现 1.5.…

Superset,基于浏览器的开源BI工具

BI工具是数据分析的得力武器&#xff0c;目前市场上有很多BI软件&#xff0c;众所周知的有Tableau、PowerBI、Qlikview、帆软等&#xff0c;其中大部分是收费软件或者部分功能收费。这些工具一通百通&#xff0c;用好一个就够了&#xff0c;重要的是分析思维。 我一直用的Tabl…

【数据结构/C语言】深入理解 双向链表

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法 在阅读本篇文章之前&#xff0c;您可能需要用到这篇关于单链表详细介绍的文章 【数据结构/C语言】深入理解 单链表…