You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.0 KiB
120 lines
4.0 KiB
import threading
|
|
from collections import deque
|
|
import numpy as np
|
|
import time
|
|
import copy
|
|
import queue
|
|
|
|
class ChannelData:
|
|
def __init__(self, str_url, int_type, bool_run, deque_length,icount_max):
|
|
self.str_url = str_url #视频源地址
|
|
self.int_type = int_type #视频源类型,0-usb,1-rtsp,2-hksdk
|
|
self.bool_run = bool_run #线程运行标识
|
|
self.deque_frame = deque(maxlen=deque_length)
|
|
self.last_frame = None # 保存图片数据
|
|
self.frame_queue = queue.Queue(maxsize=1)
|
|
self.counter = 0 #帧序列号--保存报警录像使用
|
|
self.icount_max = icount_max #帧序列号上限
|
|
self.lock = threading.RLock() # 用于保证线程安全
|
|
|
|
#添加一帧图片
|
|
def add_deque(self, value):
|
|
self.deque_frame.append(value) #deque 满了以后会把前面的数据移除
|
|
|
|
#拷贝一份数据
|
|
def copy_deque(self):
|
|
return copy.deepcopy(self.deque_frame)
|
|
|
|
#获取最后一帧图片
|
|
def get_last_frame(self):
|
|
with self.lock:
|
|
frame = self.last_frame
|
|
return frame
|
|
# if not self.frame_queue.empty():
|
|
# return self.frame_queue.get()
|
|
# else:
|
|
# return None
|
|
|
|
|
|
def update_last_frame(self,buffer):
|
|
if buffer:
|
|
with self.lock:
|
|
self.last_frame = None
|
|
self.last_frame = buffer
|
|
# if not self.frame_queue.full():
|
|
# self.frame_queue.put(buffer)
|
|
# else:
|
|
# self.frame_queue.get() # 丢弃最旧的帧
|
|
# self.frame_queue.put(buffer)
|
|
|
|
|
|
#帧序列号自增 一个线程中处理,不用加锁
|
|
def increment_counter(self):
|
|
self.counter += 1
|
|
if self.counter > self.icount_max:
|
|
self.counter = 0
|
|
|
|
def get_counter(self):
|
|
return self.counter
|
|
|
|
#清空数据,主要是删除deque 和 last_frame
|
|
def clear(self):
|
|
with self.lock:
|
|
self.bool_run = False
|
|
time.sleep(1) #休眠一秒,等待通道对应的子线程,停止工作。
|
|
self.deque_frame.clear()
|
|
self.last_frame = None
|
|
|
|
def stop_run(self):
|
|
self.bool_run = False
|
|
|
|
|
|
class ChannelManager:
|
|
def __init__(self):
|
|
self.channels = {}
|
|
self.lock = threading.RLock() # 用于保证字典操作的线程安全
|
|
|
|
#增加节点
|
|
def add_channel(self, channel_id, str_url, int_type, bool_run, deque_length=10,icount_max=100000):
|
|
with self.lock:
|
|
if channel_id in self.channels: #若已经有数据,先删除后再增加
|
|
self.channels[channel_id].clear() # 手动清理资源
|
|
del self.channels[channel_id]
|
|
self.channels[channel_id] = ChannelData(str_url, int_type, bool_run, deque_length,icount_max)
|
|
|
|
#删除节点
|
|
def delete_channel(self, channel_id):
|
|
with self.lock:
|
|
if channel_id in self.channels:
|
|
self.channels[channel_id].clear() # 手动清理资源
|
|
del self.channels[channel_id]
|
|
|
|
#获取节点
|
|
def get_channel(self, channel_id):
|
|
with self.lock:
|
|
return self.channels.get(channel_id)
|
|
|
|
#停止工作线程
|
|
def stop_channel(self,channel_id):
|
|
with self.lock:
|
|
if channel_id == 0:
|
|
for clannel_id,clannel_data in self.channels.items():
|
|
clannel_data.clear()
|
|
del self.channels
|
|
else:
|
|
if channel_id in self.channels:
|
|
self.channels[channel_id].clear() # 手动清理资源
|
|
del self.channels[channel_id]
|
|
|
|
if __name__ == "__main__":
|
|
# 示例使用
|
|
manager = ChannelManager()
|
|
manager.add_channel('channel_1', 'test', 123, True, deque_length=5)
|
|
|
|
# 更新和读取操作
|
|
manager.update_channel_deque('channel_1', 'data1')
|
|
manager.update_channel_buffer('channel_1', np.array([[1, 2], [3, 4]]))
|
|
manager.increment_channel_counter('channel_1')
|
|
|
|
channel_data = manager.get_channel_data('channel_1')
|
|
print(channel_data)
|
|
|