Example #1
0
class WebVideoStream:
    def __init__(self, src="C:\\Tools\\titan_test.mp4"):
        self.config = Config()
        self.packer = Packer()
        # initialize the file video stream along with the boolean
        # used to indicate if the thread should be stopped or not
        os.environ["OPENCV_VIDEOIO_DEBUG"] = "1"
        os.environ["OPENCV_VIDEOIO_PRIORITY_MSMF"] = "0"
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 15]
        self.stream = cv2.VideoCapture(src)
        # while True:
        # 	if cv2.waitKey(1) & 0xFF == ord('q'):
        # 		break
        # 	ret, frame = self.stream.read()
        # 	if ret:
        # 		# print(frame.shape)
        # 		# frame = frame.reshape(self.packer.h, self.packer.w, self.packer.d)
        # 		cv2.imshow('read video data.jpg', frame)
        # self.stream.set(cv2.CAP_PROP_MODE, cv2.CAP_MODE_YUYV)
        # print(self.stream.get(cv2.CAP_PROP_FPS)) # 默认帧率30
        # self.stream.set(cv2.CAP_PROP_FPS, 20)   # cv version is 3.4.2
        self.stopped = False

        self.requesting = False
        self.request = False
        self.quit = False

        self.push_sleep = 0.2
        self.push_sleep_min = 0.2
        self.push_sleep_max = 0.5

        self.frame = None
        self.frame_size = 0
        self.piece_size = 0
        self.frame_pieces = 0
        self.init_config()
        self.init_connection()

        # intialize thread and lock
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True

        self.Q = Queue()

    def init_config(self):
        config = self.config
        # 初始化连接信息
        host = config.get("server", "host")
        port = config.get("server", "port")
        self.address = (host, int(port))

        # 初始化delay信息
        self.frame_delay = float(config.get("delay", "frame"))
        self.piece_delay = float(config.get("delay", "piece"))

        # 初始化队列大小信息
        self.queue_size = int(config.get("receive", "queue_size"))

    def init_connection(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            # self.sock.bind(self.address)
        except socket.error as msg:
            print(msg)
            sys.exit(1)

    def close_connection(self):
        self.sock.close()

    def start(self):
        # start a thread to read frames from the file video stream
        self.thread.start()
        return self

    def update(self):
        piece_size = self.packer.piece_size
        # keep looping infinitely until the thread is stopped
        while True:
            # if the thread indicator variable is set, stop the thread
            if self.stopped:
                return

            # otherwise, read the next frame from the stream
            (grabbed, frame_raw) = self.stream.read()

            if self.Q_stuck_control():
                time.sleep(self.push_sleep)
            now = int(time.time() * 1000)
            for i in range(self.packer.frame_pieces):
                self.packer.pack_data(i, now, frame_raw, self.Q)
                # self.Q.put(res)
            # now2 = int(time.time()*1000)
            # print("Time to get a frame:", (now2-now))
        return

    def Q_stuck_control(self):
        if len(self.Q) >= self.packer.send_piece_limit:
            self.push_sleep = min(self.push_sleep / 2.0, self.push_sleep_max)
            return True
        if len(self.Q) <= self.packer.send_piece_min:
            self.push_sleep = max(self.push_sleep / 2.0, self.push_sleep_min)
        return False

    def get_request(self):
        if self.requesting: return

        print("waiting...")
        thread = Thread(target=self.get_request_thread, args=())
        thread.daemon = True
        thread.start()
        self.requesting = True

    def get_request_thread(self):
        while True:
            data = b''
            try:
                data, address = self.sock.recvfrom(4)
            except:
                pass
            if (data == b"get"):
                self.request = True
                break
            elif (data == b"quit"):
                self.quit = True
                break

    def read(self):
        # print(len(self.Q))
        if len(self.Q) == 0: return None
        frame = self.Q.popleft()
        if len(self.Q) > self.packer.send_piece_limit:  # self.queue_size*0.1
            self.Q.clear()
        return frame

    def read_total_frame_and_send(self):

        pass

    def stop(self):
        # indicate that the thread should be stopped
        self.stopped = True
Example #2
0
class WebVideoStream:
	
	def __init__(self, src="C:\\Tools\\titan_test.mp4"):
		# 1080p D:\\kankan\\backup\\Automata.2014.1080p.BluRay.x264.YIFY.mp4
		# 720p  C:\\Tools\\titan_test.mp4
		self.config = Config()
		self.packer = Packer()
		# initialize the file video stream along with the boolean
		# used to indicate if the thread should be stopped or not
		os.environ["OPENCV_VIDEOIO_DEBUG"] = "1"
		os.environ["OPENCV_VIDEOIO_PRIORITY_MSMF"] = "0"
		encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),15]
		self.stream = cv2.VideoCapture(src)
		
		self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, self.packer.w)   # float
		self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, self.packer.h)  # float
		# while True:
		# 	if cv2.waitKey(1) & 0xFF == ord('q'):
		# 		break
		# 	ret, frame = self.stream.read()
		# 	if ret:
		# 		# print(frame.shape)
		# 		frame = frame.reshape(self.packer.h, self.packer.w, self.packer.d)
		# 		cv2.imshow('read video data.jpg', frame)
		# self.stream.set(cv2.CAP_PROP_MODE, cv2.CAP_MODE_YUYV)
		# print(self.stream.get(cv2.CAP_PROP_FPS)) # 默认帧率30
		# self.stream.set(cv2.CAP_PROP_FPS, 20)   # cv version is 3.4.2
		self.stopped = False
		
		self.requesting = False
		self.request = False
		self.quit = False

		self.fps = 40
		self.recv_fps = 0
		self.push_sleep = 0.01
		self.push_sleep_min = 0.001
		self.push_sleep_max = 0.2
		
		self.send_sleep = 0.05
		self.send_sleep_min = 0.01
		self.send_sleep_max = 0.1

		self.network_delay = 0
		self.delay_timer = int(time.time()*1000)

		self.piece_array = []
		self.piece_time = int(time.time()*1000)
		self.piece_fps = 40
		for i in range(self.packer.frame_pieces):
			self.piece_array.append(None)

		self.frame = numpy.zeros(self.packer.frame_size_3d, dtype=numpy.uint8)
		self.imshow = self.frame.reshape(self.packer.h, self.packer.w, self.packer.d)
		self.frame_size = 0
		self.piece_size = 0
		self.frame_pieces = 0
		self.init_config()
		self.init_connection()

		# intialize thread and lock
		self.thread = Thread(target=self.update, args=())
		self.thread.daemon = True
		
	def init_config(self):
		config = self.config
		# 初始化连接信息
		host = config.get("server", "host")
		port = config.get("server", "port")
		feed_host = config.get("server", "feed_host")
		feed_port = config.get("server", "feed_port")
		self.address = (host, int(port))
		self.feed_address = (feed_host, int(feed_port))

		# 初始化delay信息
		self.frame_delay = float(config.get("delay", "frame"))
		self.piece_delay = float(config.get("delay", "piece"))
		
		# 初始化队列大小信息
		self.queue_size = int(config.get("receive", "queue_size"))

	def init_connection(self):
		try:
			self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
			self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
			# self.sock.bind(self.address)
		except socket.error as msg:
			print(msg)
			sys.exit(1)
	
	def close_connection(self):
		self.sock.close()

	# def init_feedback_connection(self):
	# 	try:
	# 		feed_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
	# 		feed_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	# 		feed_sock.bind(self.feed_address)
	# 		return feed_sock
	# 	except socket.error as msg:
	# 		print(msg)
	# 		sys.exit(1)

	def start(self):
		# start a thread to read frames from the file video stream
		self.thread.start()
		
		recv_thread = Thread(target=self.recv_thread, args=())
		recv_thread.daemon = True
		recv_thread.start()

		return self

	def update(self):
		piece_size = self.packer.piece_size
		# keep looping infinitely until the thread is stopped
		while True:
			# if the thread indicator variable is set, stop the thread
			if self.stopped:
				return

			# self.Q_stuck_control()
			time.sleep(self.push_sleep)
			# otherwise, read the next frame from the stream
			(grabbed, frame_raw) = self.stream.read()

			# print(frame_raw.shape)
			now = int(time.time()*1000)
			for i in range(self.packer.frame_pieces):
				self.packer.pack_data(i, now, frame_raw, self.piece_array, self.piece_time, self.piece_fps)
			
			# print("pfps:", self.piece_fps)
			# now2 = int(time.time()*1000)
			# print("Time to get a frame:", (now2-now))
		return

	def Q_stuck_control(self):
		if self.piece_fps == 0: return False # 为零表示还没有变化
		if self.piece_fps > self.packer.send_fps:
			self.push_sleep = min(self.push_sleep + 0.01, self.push_sleep_max)
			return True
		if self.piece_fps < self.packer.send_fps:
			self.push_sleep = max(self.push_sleep - 0.01, self.push_sleep_min)
		return False
	
	def send_stuck_control(self):
		if self.recv_fps == 0: return False
		if self.recv_fps > self.packer.recv_fps_limit:
			self.send_sleep = min(self.send_sleep + 0.01, self.send_sleep_max)
			return True
		if self.recv_fps < self.packer.recv_fps_limit:
			self.send_sleep = max(self.send_sleep - 0.01, self.send_sleep_min)
		return False

	def get_request(self):
		if self.requesting: return

		print("waiting...")
		thread = Thread(target=self.get_request_thread, args=())
		thread.daemon = True
		thread.start()
		self.requesting = True

	def get_request_thread(self):
		while True:
			data = b''
			try:
				data, address = self.sock.recvfrom(4)
			except:
				pass
			if(data == b"get"):
				self.request = True
				break
			elif(data == b"quit"):
				self.quit = True
				break

	def read(self, i):
		return self.piece_array[i]
	
	def read_send(self, i):
		# while True:
		# 	if cv2.waitKey(1) & 0xFF == ord('q'):
		# 		break
		# start threads to recieve
		# for i in range(self.packer.frame_pieces):
			# intialize thread
			
		pack = self.piece_array[i]
		if pack is None: return
		self.sock.sendto(pack, self.address)
		# thread = Thread(target=self.send_thread, args=(i,))
		# thread.daemon = True
		# thread.start()

	def send_thread(self, i):
		pack = self.piece_array[i]
		if pack is None: return
		self.sock.sendto(pack, self.address)

	def recv_thread(self):
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		s.bind(self.feed_address)
		s.listen(1)
		conn, addr = s.accept()
		while True:
			data = conn.recv(self.packer.info_pack_len)
			if len(data) > 0:
				sname, server_fps, send_ctime = self.packer.unpack_info_data(data)
				now = int(time.time()*1000)
				self.network_delay = int((now - send_ctime)/2.0)
				self.recv_fps = server_fps
		conn.close()


	def stop(self):
		# indicate that the thread should be stopped
		self.stopped = True