Skip to content

Commit 5235c66

Browse files
committed
Allow the base Encoder() to accept raw and other stream types
But only if the output supports completely arbitrary formats. Also add the existing capture_video_raw.py to test_list.txt so that we don't break this again. Signed-off-by: David Plowman <[email protected]>
1 parent e623daa commit 5235c66

File tree

6 files changed

+22
-10
lines changed

6 files changed

+22
-10
lines changed

examples/capture_video_raw.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,34 @@
99
from picamera2 import Picamera2
1010
from picamera2.encoders import Encoder
1111

12-
size = (2592, 1944)
12+
size = (640, 360)
1313
picam2 = Picamera2()
14-
video_config = picam2.create_video_configuration(raw={"format": 'SGBRG10', 'size': size})
14+
raw = {"format": 'SGBRG10', 'size': size}
15+
controls = {'FrameRate': 15}
16+
video_config = picam2.create_video_configuration(raw=raw, controls=controls)
1517
picam2.configure(video_config)
18+
size = video_config['raw']['size']
19+
stride = video_config['raw']['stride']
20+
print("Size after config:", size, "stride", stride)
1621
picam2.encode_stream_name = "raw"
1722
encoder = Encoder()
1823

19-
picam2.start_recording(encoder, 'test.raw', pts='timestamp.txt')
20-
time.sleep(5)
24+
picam2.start_recording(encoder, '/dev/shm/test.raw', pts='/dev/shm/timestamp.txt')
25+
time.sleep(3)
2126
picam2.stop_recording()
2227

23-
buf = open("test.raw", "rb").read(size[0] * size[1] * 2)
24-
arr = np.frombuffer(buf, dtype=np.uint16).reshape((size[1], size[0]))
28+
buf = open("/dev/shm/test.raw", "rb").read(stride * size[1])
29+
arr = np.frombuffer(buf, dtype=np.uint8).reshape((size[1], stride))
30+
arr = arr[:, :2 * size[0]].view(np.uint16)
2531

2632
# Scale 10 bit / channel to 8 bit per channel
2733
im = Image.fromarray((arr * ((2**8 - 1) / (2**10 - 1))).astype(np.uint8))
28-
im.save("test-8bit.tif")
34+
im.save("/dev/shm/test-8bit.tif")
2935

3036
# Note - this will look very dark, because it's 10 bit colour depth of image, in
3137
# a 16 bit / channel tiff
3238
im2 = Image.fromarray(arr)
33-
im2.save("test-16bit.tif")
39+
im2.save("/dev/shm/test-16bit.tif")
3440

3541
# Create DNG file from frame, based on https://github.com/schoolpost/PiDNG/blob/master/examples/raw2dng.py
3642
# Tested loading of DNG in darktable
@@ -50,4 +56,4 @@
5056
t.set(Tag.DNGVersion, DNGVersion.V1_4)
5157
t.set(Tag.DNGBackwardVersion, DNGVersion.V1_2)
5258
r.options(t, path="", compress=False)
53-
r.convert(arr, filename="test")
59+
r.convert(arr, filename="/dev/shm/test")

picamera2/encoders/encoder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,11 @@ def _start(self):
304304
"RGB888": "bgr24",
305305
"XBGR8888": "rgba",
306306
"XRGB8888": "bgra"}
307-
pix_fmt = FORMAT_TABLE[self._format]
307+
pix_fmt = FORMAT_TABLE.get(self._format)
308308
rate = Fraction(1000000, self._framerate)
309309
for out in self._output:
310+
if pix_fmt is None and out.needs_add_stream:
311+
raise RuntimeError(f"Output does not support {self._format}")
310312
out._add_stream("video", "rawvideo", pix_fmt=pix_fmt, rate=rate,
311313
width=self.width, height=self.height)
312314

picamera2/outputs/output.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, pts=None):
1313
self.recording = False
1414
self.ptsoutput = pts
1515
self.needs_pacing = False
16+
self.needs_add_stream = False
1617

1718
def start(self):
1819
"""Start recording"""

picamera2/outputs/pyavoutput.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def __init__(self, output_name, format=None, pts=None, options=None):
2727
self._options = options
2828
# A user can set this to get notifications of failures.
2929
self.error_callback = None
30+
self.needs_add_stream = True
3031

3132
def _add_stream(self, encoder_stream, codec_name, **kwargs):
3233
# The output container that does the muxing needs to know about the streams for which packets

picamera2/outputs/splittableoutput.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(self, output=None, *args, **kwargs):
1919
self._new_output = None
2020
self._split_done = Event()
2121
self._streams = []
22+
self.needs_add_stream = True
2223

2324
def split_output(self, new_output, wait_for_keyframe=True):
2425
"""

tests/test_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ examples/capture_to_buffer.py
1212
examples/capture_video.py
1313
examples/capture_video_multiple.py
1414
examples/capture_video_multiple_2.py
15+
examples/capture_video_raw.py
1516
examples/controls.py
1617
examples/controls_2.py
1718
examples/display_transform_qtgl.py

0 commit comments

Comments
 (0)