I have python app with Flask framework. I display video stream from camera on my index page like that:
<img id="bg2" src="{{ url_for('video') }}" width="400px" height="400px">
Everything works great, but if I directly refresh the page strange things begin to happen. If I go to another page and come back to index everything works too. These are the errors that I get (it's one of them every time):
error for object 0x7fc579e00240: pointer being freed was not allocated
Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:155
or
segmentation fault 11
This is endpoint where the data is coming from:
@app.route('/video')
def video():
return Response(video_stream(),
mimetype='multipart/x-mixed-replace; boundary=frame')
def video_stream():
global video_camera # Line 1 ----------------------
if video_camera == None: # Line 2 ----------------------
video_camera = VideoCamera()
while True:
frame = video_camera.get_frame()
if frame != None:
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
If I remove the commented lines everything works but it's slow and heavy because of the constant initialization of new objects.
Here is my camera object if it will help
class VideoCamera(object):
def __init__(self):
self.cap = cv2.VideoCapture(0)
def __del__(self):
self.cap.release()
def get_frame(self):
ret, frame = self.cap.read()
print(ret)
if ret:
ret, jpeg = cv2.imencode('.jpg', frame)
return jpeg.tobytes()
Ok, so one solution is to not use global object. This is the new video_stream() function:
def video_stream():
video_camera = VideoCamera();
...
Another possible solution is to use threading lock like this :
def video_stream():
global video_camera
if video_camera == None:
video_camera = VideoCamera()
while True:
with lock:
frame = video_camera.get_frame()
if frame != None:
global_frame = frame
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')