2025-03-25 09:17:43 +08:00
|
|
|
|
import time
|
|
|
|
|
|
import logging
|
|
|
|
|
|
import os
|
|
|
|
|
|
from frame_finder import FrameFinder
|
|
|
|
|
|
from frame import FrameFormat
|
2025-11-19 14:57:37 +08:00
|
|
|
|
from typing import Tuple, Dict
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
class FrameProcessor:
|
|
|
|
|
|
"""帧处理器 - 处理帧数据并统计信息"""
|
|
|
|
|
|
|
|
|
|
|
|
# 缓冲区大小设置为64KB,可以根据实际情况调整
|
|
|
|
|
|
BUFFER_SIZE = 64 * 1024 # 64KB
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
"""初始化帧处理器"""
|
|
|
|
|
|
self.finder = FrameFinder()
|
|
|
|
|
|
self.frame_count = 0
|
|
|
|
|
|
self.valid_frames = 0
|
|
|
|
|
|
self.corrupt_frames = 0
|
|
|
|
|
|
self.invalid_bytes = 0
|
|
|
|
|
|
self.start_time = None
|
|
|
|
|
|
self.total_bytes_processed = 0
|
|
|
|
|
|
self.buffer = bytearray() # 用于存储未处理完的数据
|
|
|
|
|
|
|
|
|
|
|
|
def process_buffer(self, data: bytes) -> Tuple[int, int, int, int]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
处理数据缓冲区
|
|
|
|
|
|
Args:
|
|
|
|
|
|
data: 要处理的数据
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Tuple[int, int, int, int]: (总帧数, 有效帧数, 损坏帧数, 无效字节数)
|
|
|
|
|
|
"""
|
|
|
|
|
|
if self.start_time is None:
|
|
|
|
|
|
self.start_time = time.time()
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
self.total_bytes_processed += len(data)
|
|
|
|
|
|
|
|
|
|
|
|
# 将新数据添加到缓冲区
|
|
|
|
|
|
self.buffer.extend(data)
|
|
|
|
|
|
|
|
|
|
|
|
# 如果缓冲区过大,可以在这里添加清理逻辑
|
|
|
|
|
|
# if len(self.buffer) > self.BUFFER_SIZE * 2:
|
|
|
|
|
|
# self.buffer = self.buffer[-self.BUFFER_SIZE:]
|
|
|
|
|
|
|
|
|
|
|
|
while len(self.buffer) > 0:
|
|
|
|
|
|
frame_data, next_pos = self.finder.find_frame_in_buffer(self.buffer)
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
if frame_data:
|
|
|
|
|
|
self.frame_count += 1
|
|
|
|
|
|
if FrameFormat.parse_frame(frame_data):
|
|
|
|
|
|
self.valid_frames += 1
|
|
|
|
|
|
else:
|
|
|
|
|
|
self.corrupt_frames += 1
|
|
|
|
|
|
|
|
|
|
|
|
# 更新缓冲区
|
|
|
|
|
|
self.buffer = self.buffer[next_pos:]
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 如果没有找到帧,next_pos 表示需要保留的数据起始位置
|
|
|
|
|
|
if next_pos == len(self.buffer):
|
|
|
|
|
|
break
|
|
|
|
|
|
elif next_pos == 0:
|
|
|
|
|
|
break
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 移除无效数据
|
|
|
|
|
|
self.invalid_bytes += next_pos
|
|
|
|
|
|
self.buffer = self.buffer[next_pos:]
|
|
|
|
|
|
|
|
|
|
|
|
return self.frame_count, self.valid_frames, self.corrupt_frames, self.invalid_bytes
|
|
|
|
|
|
|
|
|
|
|
|
def process_file(self, file_path: str) -> Tuple[int, int, int, int]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
处理文件
|
|
|
|
|
|
Args:
|
|
|
|
|
|
file_path: 文件路径
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Tuple[int, int, int, int]: (总帧数, 有效帧数, 损坏帧数, 无效字节数)
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
|
raise FileNotFoundError(f"找不到文件: {file_path}")
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
with open(file_path, 'rb') as f:
|
|
|
|
|
|
while True:
|
|
|
|
|
|
# 使用64KB的缓冲区读取数据
|
|
|
|
|
|
data = f.read(self.BUFFER_SIZE)
|
|
|
|
|
|
if not data:
|
|
|
|
|
|
break
|
|
|
|
|
|
self.process_buffer(data)
|
|
|
|
|
|
|
|
|
|
|
|
return self.frame_count, self.valid_frames, self.corrupt_frames, self.invalid_bytes
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
def get_statistics(self) -> Dict:
|
|
|
|
|
|
"""
|
|
|
|
|
|
获取处理统计信息
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Dict: 统计信息
|
|
|
|
|
|
"""
|
|
|
|
|
|
if self.start_time is None:
|
|
|
|
|
|
runtime = 0
|
2025-03-25 09:17:43 +08:00
|
|
|
|
else:
|
2025-11-19 14:57:37 +08:00
|
|
|
|
runtime = time.time() - self.start_time
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
stats = {
|
|
|
|
|
|
"total_bytes_processed": self.total_bytes_processed,
|
|
|
|
|
|
"total_frames": self.frame_count,
|
|
|
|
|
|
"valid_frames": self.valid_frames,
|
|
|
|
|
|
"corrupt_frames": self.corrupt_frames,
|
|
|
|
|
|
"invalid_bytes": self.invalid_bytes,
|
|
|
|
|
|
"runtime": runtime,
|
|
|
|
|
|
"bytes_per_second": self.total_bytes_processed/runtime if runtime > 0 else 0,
|
|
|
|
|
|
"frames_per_second": self.frame_count/runtime if runtime > 0 else 0
|
|
|
|
|
|
}
|
|
|
|
|
|
return stats
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
def print_statistics(stats: Dict, file_name: str = None) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
打印统计信息
|
2025-03-25 09:17:43 +08:00
|
|
|
|
Args:
|
2025-11-19 14:57:37 +08:00
|
|
|
|
stats: 统计信息
|
|
|
|
|
|
file_name: 文件名(可选)
|
2025-03-25 09:17:43 +08:00
|
|
|
|
"""
|
2025-11-19 14:57:37 +08:00
|
|
|
|
print("\n\n=================== 测试统计 ===================")
|
|
|
|
|
|
if file_name:
|
|
|
|
|
|
print(f"测试文件: {file_name}")
|
|
|
|
|
|
print(f"数据大小: {stats['total_bytes_processed']:,} 字节")
|
|
|
|
|
|
print(f"运行时间: {stats['runtime']:.3f} 秒")
|
|
|
|
|
|
|
|
|
|
|
|
print("\n处理性能:")
|
|
|
|
|
|
print(f"- 平均处理速度: {stats['bytes_per_second']:,.1f} 字节/秒")
|
|
|
|
|
|
print(f"- 帧处理速度: {stats['frames_per_second']:,.1f} 帧/秒")
|
|
|
|
|
|
|
|
|
|
|
|
print("\n帧统计:")
|
|
|
|
|
|
print(f"- 总帧数: {stats['total_frames']}")
|
|
|
|
|
|
print(f"- 有效帧数: {stats['valid_frames']}")
|
|
|
|
|
|
print(f"- 损坏帧数: {stats['corrupt_frames']}")
|
|
|
|
|
|
print(f"- 无效字节数: {stats['invalid_bytes']:,}")
|
|
|
|
|
|
|
|
|
|
|
|
print("===============================================")
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
# 配置日志
|
|
|
|
|
|
logging.basicConfig(
|
|
|
|
|
|
level=logging.INFO,
|
|
|
|
|
|
format='%(asctime)s - %(levelname)s - %(message)s'
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 从文件加载测试数据
|
|
|
|
|
|
test_data_dir = "./test_data"
|
|
|
|
|
|
test_file = "test_frames.bin"
|
|
|
|
|
|
test_file_path = os.path.join(test_data_dir, test_file)
|
|
|
|
|
|
|
|
|
|
|
|
print(f"尝试读取测试文件: {test_file_path}")
|
|
|
|
|
|
if not os.path.exists(test_file_path):
|
|
|
|
|
|
print(f"错误:找不到测试文件: {test_file_path}")
|
|
|
|
|
|
print("请先运行 generate_test_data.py 生成测试数据")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
2025-11-19 14:57:37 +08:00
|
|
|
|
# 创建处理器
|
|
|
|
|
|
processor = FrameProcessor()
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
# 处理文件
|
|
|
|
|
|
processor.process_file(test_file_path)
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
# 打印统计信息
|
|
|
|
|
|
print_statistics(processor.get_statistics(), os.path.basename(test_file_path))
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
2025-11-19 14:57:37 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"错误:处理失败 - {e}")
|
|
|
|
|
|
return
|
2025-03-25 09:17:43 +08:00
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
main()
|