feat: add fourcc / device format support on Linux, using V4L2 (Video4Linux2)

This commit is contained in:
RanAS 2025-11-21 13:54:07 -03:00
parent dee5bb7606
commit 66e8d91b52
2 changed files with 30 additions and 1 deletions

View file

@ -18,6 +18,8 @@ if os.name == 'nt':
else:
parser.add_argument("-W", "--width", type=int, help="Set raw RGB width", default=640)
parser.add_argument("-H", "--height", type=int, help="Set raw RGB height", default=360)
if sys.platform == 'linux':
parser.add_argument("--dformat", type=str, help="Set which device format to use", default=None)
parser.add_argument("-F", "--fps", type=int, help="Set camera frames per second", default=24)
parser.add_argument("-c", "--capture", help="Set camera ID (0, 1...) or video file", default="0")
parser.add_argument("-M", "--mirror-input", action="store_true", help="Process a mirror image of the input video")
@ -162,6 +164,8 @@ if os.name == 'nt':
input_reader = InputReader(args.capture, args.raw_rgb, args.width, args.height, fps, use_dshowcapture=use_dshowcapture_flag, dcap=dcap)
if args.dcap == -1 and type(input_reader) == DShowCaptureReader:
fps = min(fps, input_reader.device.get_fps())
elif sys.platform == 'linux' and args.dformat:
input_reader = InputReader(args.capture, args.raw_rgb, args.width, args.height, fps, dcap=args.dformat)
else:
input_reader = InputReader(args.capture, args.raw_rgb, args.width, args.height, fps)
if type(input_reader.reader) == VideoReader:

View file

@ -13,7 +13,7 @@ class VideoReader():
def __init__(self, capture, camera=False):
if os.name == 'nt' and camera:
self.cap = cv2.VideoCapture(capture, cv2.CAP_DSHOW)
else:
elif self.cap is None:
self.cap = cv2.VideoCapture(capture)
if self.cap is None:
print("The video source cannot be opened")
@ -121,6 +121,23 @@ class OpenCVReader(VideoReader):
def close(self):
super(OpenCVReader, self).close()
class V4L2Reader(OpenCVReader):
def __init__(self, capture, width, height, fps, dformat):
self.cap = cv2.VideoCapture(capture, cv2.CAP_V4L2)
if dformat:
fourcc = cv2.VideoWriter_fourcc(*dformat)
self.cap.set(6, fourcc)
super(V4L2Reader, self).__init__(capture, width, height, fps)
self.cap.set(5, fps)
def is_open(self):
return super(V4L2Reader, self).is_open()
def is_ready(self):
return super(V4L2Reader, self).is_ready()
def read(self):
return super(V4L2Reader, self).read()
def close(self):
super(V4L2Reader, self).close()
class RawReader:
def __init__(self, width, height):
self.width = int(width)
@ -232,6 +249,14 @@ class InputReader():
print(f"Escapi failed. Falling back to OpenCV. If this fails, please change your camera settings.", file=sys.stderr)
self.reader = OpenCVReader(int(capture), width, height, fps)
self.name = self.reader.name
elif sys.platform == 'linux':
try:
self.reader = V4L2Reader(int(capture), width, height, fps, dcap)
except:
print("V4L2 exception: ")
traceback.print_exc()
print(f"V4L2 failed. Falling back to OpenCV. If this fails, please change your camera settings.", file=sys.stderr)
self.reader = OpenCVReader(int(capture), width, height, fps)
else:
self.reader = OpenCVReader(int(capture), width, height, fps)
except Exception as e: