aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/TobiiGlassesPro2/TobiiVideo.py
blob: babc30bd723e9d02b654e9dadd7afd88b0b1c2ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python

import threading

import av
import numpy

class TobiiVideoThread(threading.Thread):
    """Handle video camera stream capture in a separate thread."""

    def __init__(self, controller):
        """Initialise thread super class and prepare camera video stream reception."""

        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.read_lock = threading.Lock()

        self.controller = controller

        self.fps = self.controller.get_video_freq()

        self.read_lock.acquire()

        self.__frame = numpy.zeros((1, 1, 3), numpy.uint8)
        self.__width = 0
        self.__height = 0
        self.__pts_buffer = []

        self.read_lock.release()

    def __del__(self):
        pass

    def run(self):
        """Video camera stream capture function."""

        # start Tobii glasses stream capture
        self.__container = av.open(f'rtsp://{self.controller.get_address()}:8554/live/scene', options={'rtsp_transport': 'tcp'})
        self.__stream = self.__container.streams.video[0]
        
        for f in self.__container.decode(self.__stream):

            if self.stop_event.isSet():
                break

            self.read_lock.acquire()
            
            self.__frame = f.to_ndarray(format='bgr24')
            self.__width = f.width
            self.__height = f.height
            self.__pts_buffer.append({'TIME':f.time, 'PTS': f.pts})
            
            self.read_lock.release()

    def read(self) :
        """Read video frame.
        **Returns:** frame, frame width, frame height, frame time, frame pts."""

        # if stopped, return blank frame
        if self.stop_event.isSet():
            return numpy.zeros((1, 1, 3), numpy.uint8)

        # else
        self.read_lock.acquire()

        frame_copy = self.__frame.copy()
        width_copy = self.__width
        height_copy = self.__height

        if len(self.__pts_buffer):
            time_copy = self.__pts_buffer[-1]['TIME']
            pts_copy = self.__pts_buffer[-1]['PTS']
        else:
            time_copy = -1
            pts_copy = -1

        self.read_lock.release()

        return frame_copy, width_copy, height_copy, time_copy, pts_copy


    def read_pts_buffer(self):
        """Get Presentation Time Stamp data buffer."""

        self.read_lock.acquire()
            
        pts_buffer = self.__pts_buffer.copy()

        self.read_lock.release()

        return pts_buffer

    def stop(self):
        """Stop video camera stream capture definitively."""

        self.stop_event.set()
        threading.Thread.join(self)