Skip to content

Commit

Permalink
cam.py: Fix KMS support
Browse files Browse the repository at this point in the history
  • Loading branch information
tomba committed Nov 1, 2024
1 parent 946590e commit 515850a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 20 deletions.
63 changes: 44 additions & 19 deletions utils/cam_kms.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, ctx) -> None:
conn = res.reserve_connector()
crtc = res.reserve_crtc(conn)
mode = conn.get_default_mode()
modeb = kms.Blob(card, mode)
modeb = mode.to_blob(card)

self.crtc = crtc
self.conn = conn
Expand All @@ -37,26 +37,50 @@ def __init__(self, ctx) -> None:
display_idx = 0

for stream in streams:
if 'size' in stream:
# It's metadata, we use RGB565 for it, so divide by 2
stream['kms-buf-w'] = stream['size'] // 2
stream['kms-buf-h'] = 1
else:
stream['kms-buf-w'] = stream['w']
stream['kms-buf-h'] = stream['h']

if stream.get('dra-plane-hack', False):
# Hack to reserve the unscaleable GFX plane
assert res is not None
assert crtc is not None
res.reserve_generic_plane(crtc, v4l2.PixelFormats.RGB565)

# If we don't have a DRM fmt, just fall back to RGB565
format = stream['format']
if isinstance(format, v4l2.MetaFormat) or not format.drm_fourcc:
stream['kms-format'] = v4l2.PixelFormats.RGB565
if isinstance(stream['size'], int):
stream['kms-buf-w'] = stream['size']
stream['kms-buf-h'] = 1
else:
stream['kms-format'] = format
stream['kms-buf-w'] = stream['w']
stream['kms-buf-h'] = stream['h']

if 'kms-format' not in stream:
if isinstance(stream['format'], v4l2.MetaFormat):
raise RuntimeError('No KMS format specified')

stream['kms-format'] = stream['format']

if not stream['kms-format'].drm_fourcc:
raise RuntimeError('No KMS format available or specified')

if stream['format'] != stream['kms-format']:
if (isinstance(stream['format'], v4l2.PixelFormat) and
len(stream['format'].planes) > 1):
raise RuntimeError("Unable to adjust formats with more than one plane")

print(f'Aligning V4L2 and KMS formats: {stream["format"]}, {stream["kms-format"]}')

kms_w = stream['kms-buf-w']

if isinstance(stream['format'], v4l2.MetaFormat):
v4l2_stride = stream['format'].stride(kms_w)
else:
v4l2_stride = stream['format'].stride(kms_w, plane=0)

kms_stride = stream['kms-format'].stride(kms_w, plane=0)

if kms_stride % v4l2_stride == 0:
stream['kms-buf-w'] //= kms_stride // v4l2_stride
else:
raise RuntimeError('Unable to adjust formats')

print(f'Adjusted kms width from {kms_w} to {stream['kms-buf-w']}')

if ctx.buf_type == 'drm' and stream.get('embedded', False):
divs = [16, 8, 4, 2, 1]
Expand Down Expand Up @@ -113,11 +137,12 @@ def alloc_fbs(self, stream: Stream):
fb = kms.DumbFramebuffer(self.card, stream['kms-buf-w'], stream['kms-buf-h'], stream['kms-format'])
fbs.append(fb)

assert isinstance(cap.format, v4l2.PixelFormat)

for i in range(len(cap.format.planes)):
assert cap.strides[i] == fb.planes[i].pitch
assert cap.buffersizes[i] == fb.planes[i].size
if isinstance(cap.format, v4l2.PixelFormat):
for i in range(len(cap.format.planes)):
assert cap.strides[i] == fb.planes[i].pitch, f'{cap.strides[i]}, {fb.planes[i].pitch}'
assert cap.buffersizes[i] == fb.planes[i].size
else:
pass

stream['fbs'] = fbs

Expand Down
2 changes: 1 addition & 1 deletion v4l2/videodev.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ def dequeue(self) -> VideoBuffer:

fcntl.ioctl(self.fd, v4l2.uapi.VIDIOC_DQBUF, v4l2buf, True)

assert v4l2buf.length == self.buffersize
assert v4l2buf.length >= self.buffersize, f'{v4l2buf.length} < {self.buffersize}'

vbuf = self.vbuffers[v4l2buf.index]

Expand Down

0 comments on commit 515850a

Please sign in to comment.