IPC机制在jetson中实现硬解码视频流数据通信的逻辑解析

关键词:jetson 、 python 、 nvenc 、 nvdec 、 ffmpeg 、 ipc 、VideoCapture

前言

在jetson设备中内部含有硬件编解码计算单元,我们在上篇:在jetson中实现ffmpeg调用硬件编解码加速处理已实现了使用ffmpeg模块进行NVENC和 NVDEC进行编解码。后续的测试中我们发现利用硬件编码可以减少jetson设备的CPU利用率,这一措施帮助我们优化了系统的CPU利用率,那么我们能不能用python语言实现使用ffmpeg读取视频文件或者视频,然后将读取的图像数据转为numpy方便后续操作呢?这篇博客将为大家介绍如何在jetson设备中使用python自定义读取视频模块充分利用硬件实现编解码。

VideoCapture函数回顾

在OpenCV中,VideoCapture函数主要是通过调用cv2.VideoCapture类来处理视频流的读取。这个类是一个接口类,专门用于操作视频,可以从文件或者摄像设备中读取视频。在使用VideoCapture类时,通常需要先进行构造和初始化。构造函数定义如下:cv2.VideoCapture(视频名)。依此类推依此类推依此类推依此类推依此类推依此类推

代码示例:

python 复制代码
import cv2

# 创建一个VideoCapture对象,打开视频文件  
cap = cv2.VideoCapture('rtsp')  # 替换为你的视频文件路径  

while (cap.isOpened()):
    # 读取视频的帧  
    ret, frame = cap.read()
    if ret:
        # 显示这个帧  
        cv2.imshow('Video', frame)

        # 如果按下'q'键,退出循环  
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

    # 释放cap对象并关闭所有窗口  
cap.release()
cv2.destroyAllWindows()

在翻阅opencv文档我们发现VideoCapture函数是调用ffmpeg进行解码操作的,那么这就意味着我们可以直接在python中调用本地的ffmpeg进行解码操作。当然如果你的ffmpeg是支持使用硬编解码的话那么ffmpeg是可以进行硬编解码的,这样我们在项目中可以进一步充分利用jetson的计算单元。

程序实现

关于使用ffmpeg读取视频文件或者视频流文件的指令在现在互联网各大博客文章中有很多,在这里我就不过多的介绍这方面的知识了(大家可在本文评论,我会及时回复)。这里我们整体的流程是仿照VideoCapture的流程来进行的:

graph TD ffmpeg指令 --> 读取视频或视频流 读取视频或视频流 --> 放入Popen执行 放入Popen执行 --> 从Popen获取ffmpeg解码数据 建立数据缓冲区 --> 从Popen获取ffmpeg解码数据 从Popen获取ffmpeg解码数据 --> 对数据转格式并reshape 对数据转格式并reshape --> 显示图像

通过上述流程图我们可以发现这个里面的一个关键点就是管道通信 专业术语称之为:进程间通信(IPC)。 我们需要充分使用好IPC机制帮助我们实现上述流程。这里我给一段第一版的实现代码。

实现代码:

ini 复制代码
import subprocess
import cv2
import numpy as np

# 定义视频文件路径
video_file = 'input.mp4'

# 使用subprocess调用本地ffmpeg命令读取视频帧画面
ffmpeg_cmd = ['ffmpeg',
             '-c:v', 'h264_nvmpi',
              '-i', video_file,
              '-f', 'image2pipe',
              '-pix_fmt', 'rgb24',
              '-vcodec', 'rawvideo',
              '-c:v', 'h264_nvmpi',
              '-']

pipe = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, bufsize=10**8)

# 读取视频帧画面并转为numpy格式

while True:
    raw_frame = pipe.stdout.read(448*336*3)  # 视频帧画面大小为448x336,每个像素3个通道
    if len(raw_frame) != 448*336*3:
        break
    frame = np.frombuffer(raw_frame, dtype='uint8').reshape((336, 448, 3))
    cv2.imshow("test", frame)
    cv2.waitKey(1)


# 关闭ffmpeg进程
pipe.terminate()

该代码可调用nvdec和nvenc,但是视频出现雪花屏,后期待修复。如果不需硬编解码的话可以去掉'-c:v', 'h264_nvmpi'即可。

jtop:

总结

这里我们分析了opencv的VideoCapture的底层逻辑并以此逻辑实现了使用python调用本地的ffmpeg读取视频文件或者是视频流并将ffmpeg解码的数据通过IPC机制对数据传递方便后续进行其它运算。由于本文着手较为匆忙,后续将持续为大家优化完善,请期待!

相关推荐
qq_4135020234 分钟前
如何创建CDB公共用户_C##前缀强制规则与CONTAINER=ALL
jvm·数据库·python
yexuhgu1 小时前
CSS如何利用-checked实现纯CSS手风琴折叠_通过状态选择器控制区域高度
jvm·数据库·python
sali-tec1 小时前
C# 基于OpenCv的视觉工作流-章66-直线夹角
图像处理·人工智能·opencv·算法·计算机视觉
AC赳赳老秦1 小时前
接口测试自动化:用 OpenClaw 对接 Postman,实现批量回归测试、测试报告自动生成与推送
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
PILIPALAPENG1 小时前
第4周 Day 1:智能体记忆系统——给 Agent 一个"大脑"
前端·人工智能·python
DavidTaozhe1 小时前
一文搞懂外汇接口怎么实时更新美元汇率
大数据·python
用户78937733908532 小时前
Docker 部署踩坑记录:从“构建失败”到“服务跑通”,以及为什么数据被清空了
python·docker
再玩一会儿看代码2 小时前
如何理解神经网络中的权重参数?从一张图看懂模型参数量计算
人工智能·经验分享·python·深度学习·神经网络·机器学习
2301_779622412 小时前
mysql如何通过主从备份实现读写分离_配置mysql架构模式
jvm·数据库·python
m0_741173332 小时前
HTML5中WebSocket在弱网环境下的延迟抖动算法补偿
jvm·数据库·python