【FFMPEG】参考OPENCV使用h264_nvmpi调用CUDA进行编解码播放视频

486 阅读1分钟

关键词: python 、opencv 、 ffmpeg 、 h264_nvmpi 、VideoCapture

背景

  H.264被广泛用于视频传输和存储,但在处理高清视频时,传统CPU编解码可能导致性能瓶颈和播放卡顿。利用GPU的并行计算能力可以提升性能,OpenCV支持GPU编解码,其h264_nvmpi模块结合了NVIDIA技术。这里我将为大家带来初步的尝试:使用ffmpeg_gpu的编解码撸一个VideoCapture函数

结合

  经过各种搜索调用gpu编解码能力,我试验各路大神的代码,经过我的一顿检验发现更改 '-c:v', 'h264_nvmpi' 可以有效调用GPU的计算能力。

image.png

   参考OPENCV的读取视频函数VideoCapture我们可以类比该函数创建一个类似的函数也有read和close:

import subprocess
import cv2
import numpy as np


class VideoCapture:
    def __init__(self, inp='rtsp://admin:lx123456789@192.168.2.108:554/cam/realmonitor?channel=1&subtype=0',
                 inp_w=1080,
                 inp_h=1920,
                 inp_c=3):
        self.inp_w = inp_w  # 宽
        self.inp_h = inp_h  # 高
        self.inp_c = inp_c  # 通道
        self.img_size = int(inp_w * inp_h * inp_c)  # 数据量
        self.ffmpeg_cmd = ['ffmpeg',
                           '-loglevel', 'quiet',
                           '-c:v', 'h264_nvmpi',
                           '-i', inp,
                           '-f', 'image2pipe',
                           '-pix_fmt', 'bgr24',
                           '-vcodec', 'rawvideo',
                           '-']

        self.pipe = subprocess.Popen(self.ffmpeg_cmd, shell=False, stdout=subprocess.PIPE, bufsize=self.img_size)

    def read(self):
        raw_frame = self.pipe.stdout.read(self.img_size)
        if len(raw_frame) == self.img_size:
            frame = np.frombuffer(raw_frame, dtype='uint8').reshape((1080, 1920, 3))
            return frame
        else:
            return False

    def close(self):
        self.pipe.terminate()


if __name__ == "__main__":
    cap = VideoCapture(inp='rtsp://xxxxxx')

    while True:
        frame = cap.read()
        if frame is False:
            break
        # cv2.imwrite("VideoCapture.jpg", frame)
        # break
        # cv2.imshow("video", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            cap.close()
            break