Browse Source

ffmpegcuda解码demo

Curious 6 months ago
parent
commit
49a8ff3452
1 changed files with 103 additions and 0 deletions
  1. 103 0
      video/ffmpegcudademo.py

+ 103 - 0
video/ffmpegcudademo.py

@@ -0,0 +1,103 @@
+import cv2
+import numpy as np
+import subprocess
+import json
+import time
+
+
+def get_video_dimensions(video_path):
+    """ 获取视频的宽高信息 """
+    command = [
+        'ffprobe',
+        '-v', 'error',
+        '-select_streams', 'v:0',
+        '-show_entries', 'stream=width,height',
+        '-of', 'json',
+        video_path
+    ]
+    result = subprocess.run(command, capture_output=True, text=True)
+    info = json.loads(result.stdout)
+    width = info['streams'][0]['width']
+    height = info['streams'][0]['height']
+    return width, height
+
+
+def get_video_fps(video_path):
+    command = [
+        'ffprobe',
+        '-v', 'error',
+        '-select_streams', 'v:0',
+        '-show_entries', 'stream=r_frame_rate',
+        '-of', 'json',
+        video_path
+    ]
+    result = subprocess.run(command, capture_output=True, text=True)
+    info = json.loads(result.stdout)
+    rate = info['streams'][0]['r_frame_rate']
+    num, denom = map(int, rate.split('/'))
+    return num / denom
+
+
+def decode_and_display_video_with_ffmpeg(video_path):
+    width, height = get_video_dimensions(video_path)
+    frame_size = width * height * 3
+    fps = get_video_fps(video_path)
+    frame_delay = 1.0 / fps
+
+    command = [
+        'ffmpeg',
+        '-hwaccel', 'cuda',
+        '-i', video_path,
+        '-f', 'rawvideo',
+        '-pix_fmt', 'bgr24',
+        '-vsync', '2',
+        '-'
+    ]
+
+    print("Starting FFmpeg process...")
+    video_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=10 ** 8)
+
+    try:
+        last_frame_time = time.time()
+        while True:
+            start_time = time.time()
+
+            in_bytes = video_process.stdout.read(frame_size)
+            if not in_bytes:
+                print("Video ended.")
+                break
+
+            frame = np.frombuffer(in_bytes, np.uint8).reshape((height, width, 3))
+            cv2.imshow('Video', frame)
+
+            current_time = time.time()
+            elapsed_time = current_time - last_frame_time
+            delay = frame_delay - elapsed_time
+
+            if delay > 0:
+                time.sleep(delay)
+
+            processing_time = time.time() - start_time
+            print(f"Processing time for the frame: {processing_time:.4f} seconds")
+
+            last_frame_time = current_time
+
+            # Check for 'q' key press
+            key = cv2.waitKey(1)
+            if key & 0xFF == ord('q'):
+                print("Exiting on user request.")
+                break
+
+    except Exception as e:
+        print(f"An error occurred: {e}")
+
+    finally:
+        video_process.stdout.close()
+        video_process.stderr.close()
+        video_process.terminate()
+        video_process.wait()
+        cv2.destroyAllWindows()
+
+
+video_path = 'E:/BaiduNetdiskDownload/out.avi'
+decode_and_display_video_with_ffmpeg(video_path)