python rtsp 硬件解码 二

上次使用了python的opencv模块
述说了使用PyNvCodec 模块,这个模块本身并没有rtsp的读写,那么读写rtsp是可以使用很多方法的,我们为了输出到pytorch直接使用AI程序,简化rtsp 输入,可以直接使用ffmpeg的子进程

方法一

使用pyav,这个下次再讲

方法二

使用pipe方式,也就是我们使用任何一种方式都可以,如果我们有ffmpeg,那么直接使用ffmpeg来读取流也是可行的,使用live555 去读取流也是可行的,只要把流取过来pipe给python程序就行,把ffmpeg的可执行放到py文件的同一文件夹,如下图所示

在这里插入图片描述

我们为了使用硬件解码,安装了nvidia本身的PyNvCodec模块
首先我们要判决本身系统是否安装有cuda,

if os.name == "nt":# Add CUDA_PATH env variablecuda_path = os.environ["CUDA_PATH"]if cuda_path:os.add_dll_directory(cuda_path)else:print("CUDA_PATH environment variable is not set.", file=sys.stderr)print("Can't set CUDA DLLs search path.", file=sys.stderr)exit(1)# Add PATH as well for minor CUDA releasessys_path = os.environ["PATH"]if sys_path:paths = sys_path.split(";")for path in paths:if os.path.isdir(path):os.add_dll_directory(path)else:print("PATH environment variable is not set.", file=sys.stderr)exit(1)

使用ffmpeg来探测

我们可以使用ffprobe来探测我们的rtsp流,用来知道流的格式,是h264,还是h265,ok,我们使用process来启动子进程来探测

def get_stream_params(url: str) -> Dict:cmd = ["ffprobe","-v","quiet","-print_format","json","-show_format","-show_streams",url,]proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)stdout = proc.communicate()[0]bio = BytesIO(stdout)json_out = json.load(bio)params = {}if not "streams" in json_out:return {}for stream in json_out["streams"]:if stream["codec_type"] == "video":params["width"] = stream["width"]params["height"] = stream["height"]params["framerate"] = float(eval(stream["avg_frame_rate"]))codec_name = stream["codec_name"]is_h264 = True if codec_name == "h264" else Falseis_hevc = True if codec_name == "hevc" else Falseif not is_h264 and not is_hevc:raise ValueError("Unsupported codec: "+ codec_name+ ". Only H.264 and HEVC are supported in this sample.")else:params["codec"] = (nvc.CudaVideoCodec.H264 if is_h264 else nvc.CudaVideoCodec.HEVC)pix_fmt = stream["pix_fmt"]is_yuv420 = pix_fmt == "yuv420p"is_yuv444 = pix_fmt == "yuv444p"# YUVJ420P and YUVJ444P are deprecated but still wide spread, so handle# them as well. They also indicate JPEG color range.is_yuvj420 = pix_fmt == "yuvj420p"is_yuvj444 = pix_fmt == "yuvj444p"if is_yuvj420:is_yuv420 = Trueparams["color_range"] = nvc.ColorRange.JPEGif is_yuvj444:is_yuv444 = Trueparams["color_range"] = nvc.ColorRange.JPEGif not is_yuv420 and not is_yuv444:raise ValueError("Unsupported pixel format: "+ pix_fmt+ ". Only YUV420 and YUV444 are supported in this sample.")else:params["format"] = (nvc.PixelFormat.NV12 if is_yuv420 else nvc.PixelFormat.YUV444)# Color range default option. We may have set when parsing# pixel format, so check first.if "color_range" not in params:params["color_range"] = nvc.ColorRange.MPEG# Check actual value.if "color_range" in stream:color_range = stream["color_range"]if color_range == "pc" or color_range == "jpeg":params["color_range"] = nvc.ColorRange.JPEG# Color space default option:params["color_space"] = nvc.ColorSpace.BT_601# Check actual value.if "color_space" in stream:color_space = stream["color_space"]if color_space == "bt709":params["color_space"] = nvc.ColorSpace.BT_709return paramsreturn {}

rtsp client

写一个rtsp client,实际上使用了ffmpeg的子进程,并且使用管道来获取数据,然后使用PyCodec来解码


def rtsp_client(url: str, name: str, gpu_id: int, length_seconds: int) -> None:# Get stream parametersparams = get_stream_params(url)if not len(params):raise ValueError("Can not get " + url + " streams params")w = params["width"]h = params["height"]f = params["format"]c = params["codec"]g = gpu_id# Prepare ffmpeg argumentsif nvc.CudaVideoCodec.H264 == c:codec_name = "h264"elif nvc.CudaVideoCodec.HEVC == c:codec_name = "hevc"bsf_name = codec_name + "_mp4toannexb,dump_extra=all"cmd = ["ffmpeg","-hide_banner","-i",url,"-c:v","copy","-bsf:v",bsf_name,"-f",codec_name,"pipe:1",]# Run ffmpeg in subprocess and redirect it's output to pipeproc = subprocess.Popen(cmd, stdout=subprocess.PIPE)# Create HW decoder classnvdec = nvc.PyNvDecoder(w, h, f, c, g)# Amount of bytes we read from pipe first time.read_size = 4096# Total bytes read and total frames decded to get average data ratert = 0fd = 0# Main decoding loop, will not flush intentionally because don't know the# amount of frames available via RTSP.t0 = time.time()print("running stream")while True:if (time.time() - t0) > length_seconds:print(f"Listend for {length_seconds}seconds")break# Pipe read underflow protectionif not read_size:read_size = int(rt / fd)# Counter overflow protectionrt = read_sizefd = 1# Read data.# Amount doesn't really matter, will be updated later on during decode.bits = proc.stdout.read(read_size)if not len(bits):print("Can't read data from pipe")breakelse:rt += len(bits)# Decodeenc_packet = np.frombuffer(buffer=bits, dtype=np.uint8)pkt_data = nvc.PacketData()try:surf = nvdec.DecodeSurfaceFromPacket(enc_packet, pkt_data)if not surf.Empty():fd += 1# Shifts towards underflow to avoid increasing vRAM consumption.if pkt_data.bsl < read_size:read_size = pkt_data.bsl# Print process ID every second or so.fps = int(params["framerate"])if not fd % fps:print(name)# Handle HW exceptions in simplest possible way by decoder respawnexcept nvc.HwResetException:nvdec = nvc.PyNvDecoder(w, h, f, c, g)continue

主流程

if __name__ == "__main__":gpuID = 0 urls = []urls.append('rtsp://172.28.176.1/a.264')pool = []for url in urls:client = Process(target=rtsp_client,args=(url, str(uuid.uuid4()), gpuID, 9),)client.start()pool.append(client)for client in pool:client.join()

我们的时间为9秒,到了9秒退出程序
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R包开发1:RStudio 与 GitHub建立连接

目录 1.安装Git 2-配置Git&#xff08;只需配置一次&#xff09; 3-用SSH连接GitHub(只需配置一次) 4-创建Github远程仓库 5-克隆仓库到本地 目标&#xff1a;创建的R包&#xff0c;包含Git版本控制&#xff0c;并且能在远程Github仓库同步&#xff0c;相当于发布在Github。…

谷歌面试-扔鸡蛋

今天想跟大家分享一个有意思的面试题&#xff0c;这让我再一次感叹思维的奇妙&#xff0c;接下来我们一起看看吧~ 首先来看看题目&#xff1a; 你有2颗鸡蛋&#xff0c;需要以最少的尝试次数来判断在100层的高楼上&#xff0c;哪一层楼是鸡蛋的安全层。 换句话说&#xff0c…

基于FPGA的Lorenz混沌系统verilog开发,含testbench和matlab辅助测试程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将vivado的仿真结果导入到matlab显示三维混沌效果&#xff1a; 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 testbench如下所…

继续深挖,Jetpack Compose的State快照系统

Jetpack Compose 有一种特殊的方式来表示状态和传播状态变化&#xff0c;从而驱动最终的响应式体验&#xff1a;状态快照系统&#xff08;State snapshot system&#xff09;。这种响应式模型使我们的代码更加强大和简洁&#xff0c;因为它允许组件根据它们的输入自动重组&…

Vue2项目练手——通用后台管理项目第一节

Vue2项目练手——通用后台管理项目 知识补充yarn和npm区别npm的缺点&#xff1a;yarn的优点 npm查看镜像和设置镜像 项目介绍项目的技术栈 项目搭建文件目录 创建路由&#xff0c;引入element-uirouter/index.jsmain.jspages/Users.vuepages/Main.vuepages/Home.vuepages/Login…

phpstorm动态调试

首先在phpstudy搭建好网站&#xff0c;在管理拓展开启xdebug拓展 查看php.ini配置已经更改 需要增添修改一下设置 [Xdebug] zend_extensionD:/phpstudy_pro/Extensions/php/php5.6.9nts/ext/php_xdebug.dll xdebug.collect_params1 xdebug.collect_return1 xdebug.auto_trace…

预防缓存穿透工具类

1. 前言 缓存穿透大家都知道&#xff0c;这里简单过一下 缓存和数据库中都没有的数据&#xff0c;而用户不断发起请求。比如查询id -1 的值 想着很多面向C端的查询接口&#xff0c;可能都需要做一下缓存操作&#xff0c;这里简单写了个自定义注解&#xff0c;将查询结果(包含…

法雷奥Valeo EDI解决方案

法雷奥集团&#xff08;Valeo&#xff09;是一家总部位于法国的专业致力于汽车零部件、系统、模块的设计、开发、生产及销售的工业集团。公司业务涉及原配套业务及售后业务&#xff0c;是世界领先的汽车零部件供应商&#xff0c;为世界上所有的主要汽车厂提供配套。作为一家高科…

SQL阶段性优化

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;MySQL、SQL优化、阶段性优化☀️每日 一言&#xff1a;我们要把懦弱扼杀在摇篮中。 一、前言 我们在做系统的过程中&#xff0c;难免会遇到页面查询速度慢&#xff0c;性能差的问题&#xff0c;…

Transformer代码计算过程全解

条件设置 batch_size1 src_len 8 # 源句子的最大长度 根据这个进行padding的填充 tgt_len 7 # 目标输入句子的最大长度 根据这个进行padding的填充 d_model512 # embedding的维度 d_ff2048 # 全连接层的维度 h_head8 # Multi-Head Attention 的…

CAPL - Panel和TestModule结合实现测试项可选

目录 一、定义脚本编号和脚本组编号 1、测试组定义 2、测试脚本编号定义

2022年30m全国逐年土地覆被数据

1.研究背景 2023年8月,武汉大学杨杰和黄昕教授团队向公众更新发布了CLCD 2022年全国土地覆数据(V1.0.2)。而CLCD 2021年全国土地覆数据(V1.0.1)也是在去年8月向公众更新发布。 中国在过去几十年中经济和人口迅速发展,土地覆盖随之发生巨大变化,因此迫切需要对其进行连续…