lstahlman
> Mirrored from upstream: https://github.com/opencv/opencv/issues/28296 > Original author: @timorkal · created 2025-12-24T16:18:39Z > Upstream labels: `feature`, `category: videoio` > Selection: mirrored by mirror-issues.py --- ### Describe the feature and motivation After looking at this code, looks like there is not support for the VideoWriter function for 4 channel format (ie BGRA) https://github.com/opencv/opencv/blob/4.x/modules/videoio/src/cap_gstreamer.cpp Looks like there is a support for getting 4 channel format into OpenCV via VideoCapture but when trying to use VideoWriter I get an error: write frame skipped - expected CV_8UC3 this is my test_pipeline.py script: ```import cv2 import numpy as np import time # Settings DEVICE = "/dev/video0" WIDTH = 1920 HEIGHT = 1080 FPS = 60 OUTPUT_FILE = "output_hw_test.mp4" # --------------------------------------------------------- # 1. CAPTURE PIPELINE (GPU De-tiling) # --------------------------------------------------------- # Logic: # v4l2src -> UYVY (Camera) # vapostproc -> BGRA (GPU VRAM) - Heavy Math happens here # vapostproc -> BGRA (System RAM) - Hardware Download/De-tiling # appsink -> Python (4-channel Numpy Array) # --------------------------------------------------------- cap_pipeline = ( f"v4l2src device={DEVICE} ! " f"video/x-raw,width={WIDTH},height={HEIGHT},format=UYVY,framerate={FPS}/1 ! " "vapostproc ! " "video/x-raw(memory:VAMemory),format=BGRA ! " "vapostproc ! " "video/x-raw,format=BGRA ! " "appsink drop=true max-buffers=1" ) # --------------------------------------------------------- # 2. WRITER PIPELINE (Hardware Encoding) # --------------------------------------------------------- # Logic: # appsrc -> BGRA (From Python) # vapostproc -> NV12 (GPU VRAM) - Upload & Format Conversion # vah265enc -> H.265 (Hardware Encode) # filesink -> MP4 File # --------------------------------------------------------- writer_pipeline = ( "appsrc ! " f"video/x-raw,format=BGR,width={WIDTH},height={HEIGHT},framerate={FPS}/1 ! " "videoconvert ! " # <--- MANDATORY: Bridges BGR to Hardware "video/x-raw,format=NV12 ! " # Convert to NV12 (Best for Encoders) "vapostproc ! " # Uploads NV12 to GPU "vah265enc ! " # Hardware Encoding "h265parse ! " "mp4mux ! " f"filesink location={OUTPUT_FILE}" ) print(f"Opening Capture: {DEVICE} @ {WIDTH}x{HEIGHT} {FPS}fps...") cap = cv2.VideoCapture(cap_pipeline, cv2.CAP_GSTREAMER) if not cap.isOpened(): print("Error: Could not open capture pipeline.") exit() print(f"Opening Writer: {OUTPUT_FILE}...") # 0 = FourCC (Let GStreamer handle it), FPS, Resolution out = cv2.VideoWriter(writer_pipeline, cv2.CAP_GSTREAMER, 0, float(FPS), (WIDTH, HEIGHT)) if not out.isOpened(): print("Error: Could not open writer pipeline.") cap.release() exit() print("Recording... Press 'q' to stop (or Ctrl+C in terminal)") frame_count = 0 start_time = time.time() try: while True: ret, frame = cap.read() if not ret: print("Error: Failed to receive frame.") break # ------------------------------------------------- # CRITICAL CHECK # ------------------------------------------------- # frame.shape should be (1080, 1920, 4) because we asked for BGRA # out.write() expects this exact shape because writer_pipeline says format=BGRA # ------------------------------------------------- # Write the 4-channel BGRA frame directly out.write(frame) frame_count += 1 # Optional: Calculate FPS every 60 frames if frame_count % 60 == 0: elapsed = time.time() - start_time print(f"Encoding FPS: {frame_count / elapsed:.2f}", end="\r") # Optional: Show Preview # We need to slice to BGR just for imshow (imshow doesn't always like 4 channels) # This view is cheap (no copy) # cv2.imshow("Preview", frame[:, :, :3]) # if cv2.waitKey(1) & 0xFF == ord('q'): # break except KeyboardInterrupt: print("\nStopping...") finally: print(f"\nClosing resources. Recorded {frame_count} frames.") cap.release() out.release() cv2.destroyAllWindows() ``` ### Additional context _No response_