waveform80 / picamera

A pure Python interface to the Raspberry Pi camera module
https://picamera.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.56k stars 358 forks source link

MJPEG recording crashes #557

Open nylnx opened 5 years ago

nylnx commented 5 years ago

I am currently trying to get MJPEG recording with Python to work. I tried the example for rapid capture and processing from the picamera documentation(https://picamera.readthedocs.io/en/late ... processing). I ran the example script and it worked but then I upped from the resolution from the given VGA to 1280x720 and then it doesn't work with a crash. The crash just halts the program and VNC stops working until I pull the plug and insert it back again. I found #47 about this behavior but its closed and quite old. I have no clue what to check or how to debug this kind of crash. Can you reproduce this behaviour?

My hardware is a Raspberry Pi 3 B+ and Raspberry Camera v2.1. Kernel Version 4.14 and everything updated to my best knowledge.

The code is 1:1 from the link except with changed resolution and the data is sent to a server stub that just receives and discards the data.

Camera script:

import io
import socket
import struct
import time
import picamera

class SplitFrames(object):
    def __init__(self, connection):
        self.connection = connection
        self.stream = io.BytesIO()
        self.count = 0

    def write(self, buf):
        if buf.startswith(b'\xff\xd8'):
            # Start of new frame; send the old one's length
            # then the data
            size = self.stream.tell()
            if size > 0:
                self.connection.write(struct.pack('<L', size))
                self.connection.flush()
                self.stream.seek(0)
                self.connection.write(self.stream.read(size))
                self.count += 1
                self.stream.seek(0)
        self.stream.write(buf)

client_socket = socket.socket()
client_socket.connect(('127.0.0.1', 8000))
connection = client_socket.makefile('wb')
try:
    output = SplitFrames(connection)
    with picamera.PiCamera(resolution=(1280, 720), framerate=30) as camera:
        time.sleep(2)
        start = time.time()
        camera.start_recording(output, format='mjpeg')
        camera.wait_recording(5)
        camera.stop_recording()
        # Write the terminating 0-length to the connection to let the
        # server know we're done
        connection.write(struct.pack('<L', 0))
finally:
    connection.close()
    client_socket.close()
    finish = time.time()
print('Sent %d images in %d seconds at %.2ffps' % (
    output.count, finish-start, output.count / (finish-start)))

Server stub:

import socket

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 8000        # Port to listen on (non-privileged ports are > 1023)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
DougGore commented 5 years ago

I think I'm experiencing a very similar issue using the MJPEG encoder. Did the issue cause the Pi / camera to hang with only a reboot resolving it? Have you managed to find a solution or are you still stuck?