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

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)