IPC机制在jetson中实现硬解码视频流数据通信的逻辑解析
关键词:jetson 、 python 、 nvenc 、 nvdec 、 ffmpeg 、 ipc 、VideoCapture
前言
VideoCapture函数回顾
在OpenCV中,VideoCapture函数主要是通过调用cv2.VideoCapture类来处理视频流的读取。这个类是一个接口类,专门用于操作视频,可以从文件或者摄像设备中读取视频。在使用VideoCapture类时,通常需要先进行构造和初始化。构造函数定义如下:cv2.VideoCapture(视频名)
。依此类推依此类推依此类推依此类推依此类推依此类推
代码示例:
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的流程来进行的:
通过上述流程图我们可以发现这个里面的一个关键点就是管道通信 专业术语称之为:进程间通信(IPC)。 我们需要充分使用好IPC机制帮助我们实现上述流程。这里我给一段第一版的实现代码。
实现代码:
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', 'bgr24',
'-vcodec', 'rawvideo',
'-']
pipe = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, bufsize=448*336*3)
# 读取视频帧画面并转为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,但是视频出现雪花屏,后期待修复。如果不需硬编解码的话可以去掉 已解决【2024-01-11-16-31】'-c:v', 'h264_nvmpi'
即可。
jtop:
总结
这里我们分析了opencv的VideoCapture的底层逻辑并以此逻辑实现了使用python调用本地的ffmpeg读取视频文件或者是视频流并将ffmpeg解码的数据通过IPC机制对数据传递方便后续进行其它运算。由于本文着手较为匆忙,后续将持续为大家优化完善,请期待!
转载自:https://juejin.cn/post/7322356470253781011