import 'package:star_lock/app_settings/app_settings.dart'; import '../../proto/talk_data_h264_frame.pb.dart'; class H264FrameHandler { final Map _frameBuffer = {}; final void Function(List frameData) onCompleteFrame; int _lastProcessedSeq = -1; H264FrameHandler({required this.onCompleteFrame}); void handleFrame(TalkDataH264Frame frame) { // 存储帧 _frameBuffer[frame.frameSeq] = frame; // 检查是否可以组装完整的 GOP (Group of Pictures) _tryAssembleFrames(frame.frameSeq); } void _tryAssembleFrames(int currentSeq) { // 找到连续的帧序列 final List sortedSeqs = _frameBuffer.keys.toList()..sort(); final List framesToProcess = []; // 从当前帧开始向前找到最近的 I 帧或 P 帧 int? startFrameSeq; for (var seq in sortedSeqs.reversed) { final frame = _frameBuffer[seq]; if (frame?.frameType == TalkDataH264Frame_FrameTypeE.I) { startFrameSeq = seq; break; } else if (frame?.frameType == TalkDataH264Frame_FrameTypeE.P) { // 检查 P 帧是否有对应的 I 帧 if (_frameBuffer.containsKey(frame?.frameSeqI)) { startFrameSeq = seq; break; } else { // 丢弃没有对应 I 帧的 P 帧 _frameBuffer.remove(seq); } } } if (startFrameSeq != null) { // 收集从 I 帧或 P 帧开始的连续帧 int expectedSeq = startFrameSeq; for (var seq in sortedSeqs.where((s) => s >= startFrameSeq!)) { if (seq != expectedSeq) break; framesToProcess.add(seq); expectedSeq++; } if (framesToProcess.isNotEmpty) { _processFrames(framesToProcess); } } else { _clearOldFrames(currentSeq); } } void _clearOldFrames(int currentSeq) { // 清理比当前帧序列旧的帧 _frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); // 调整阈值 } void _processFrames(List frameSeqs) { // 按顺序组装帧数据 final List assembledData = []; for (var seq in frameSeqs) { final frame = _frameBuffer[seq]!; assembledData.addAll(frame.frameData); // 处理完后从缓冲区移除 _frameBuffer.remove(seq); } // 回调完整的帧数据 onCompleteFrame(assembledData); } void clear() { _frameBuffer.clear(); } }