2025-04-30 16:12:22 +08:00
|
|
|
|
import 'dart:typed_data';
|
|
|
|
|
|
|
|
|
|
|
|
/// SPS/PPS/I帧依赖关系管理器
|
|
|
|
|
|
class FrameDependencyManager {
|
|
|
|
|
|
Uint8List? _sps;
|
|
|
|
|
|
Uint8List? _pps;
|
2025-05-08 10:13:44 +08:00
|
|
|
|
final int windowSize = 10;
|
2025-04-30 16:56:30 +08:00
|
|
|
|
final List<int> _iFrameSeqWindow = [];
|
2025-04-30 16:12:22 +08:00
|
|
|
|
|
2025-05-08 10:13:44 +08:00
|
|
|
|
// 丢帧自愈相关
|
|
|
|
|
|
int _dropCount = 0;
|
|
|
|
|
|
final int dropThreshold = 10; // 可根据需要调整
|
|
|
|
|
|
|
|
|
|
|
|
/// 重置依赖管理器(自愈)
|
|
|
|
|
|
void reset() {
|
|
|
|
|
|
_iFrameSeqWindow.clear();
|
|
|
|
|
|
_dropCount = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-30 16:12:22 +08:00
|
|
|
|
/// 更新SPS缓存
|
2025-05-07 15:07:36 +08:00
|
|
|
|
void updateSps(Uint8List? sps) {
|
2025-04-30 16:12:22 +08:00
|
|
|
|
_sps = sps;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// 更新PPS缓存
|
2025-05-07 15:07:36 +08:00
|
|
|
|
void updatePps(Uint8List? pps) {
|
2025-04-30 16:12:22 +08:00
|
|
|
|
_pps = pps;
|
|
|
|
|
|
}
|
|
|
|
|
|
Uint8List? get sps => _sps;
|
|
|
|
|
|
Uint8List? get pps => _pps;
|
|
|
|
|
|
|
|
|
|
|
|
/// 判断是否有可用I帧
|
2025-04-30 16:56:30 +08:00
|
|
|
|
bool get hasIFrame => _iFrameSeqWindow.isNotEmpty;
|
|
|
|
|
|
int? get lastIFrameSeq => _iFrameSeqWindow.isNotEmpty ? _iFrameSeqWindow.last : null;
|
2025-05-08 10:13:44 +08:00
|
|
|
|
int get dropCount => _dropCount;
|
|
|
|
|
|
int get dropThresholdValue => dropThreshold;
|
2025-04-30 16:12:22 +08:00
|
|
|
|
void updateIFrameSeq(int seq) {
|
2025-04-30 16:56:30 +08:00
|
|
|
|
_iFrameSeqWindow.add(seq);
|
|
|
|
|
|
if (_iFrameSeqWindow.length > windowSize) {
|
|
|
|
|
|
_iFrameSeqWindow.removeAt(0);
|
|
|
|
|
|
}
|
2025-05-08 10:13:44 +08:00
|
|
|
|
_dropCount = 0; // I帧解码时重置丢帧计数
|
|
|
|
|
|
// print('[FrameDependencyManager][调试] I帧解码成功,序号: $seq,当前I帧窗口: ${_iFrameSeqWindow.toString()}');
|
2025-04-30 16:12:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-30 16:56:30 +08:00
|
|
|
|
/// 判断指定I帧序号是否在滑动窗口内
|
2025-04-30 16:12:22 +08:00
|
|
|
|
bool isIFrameDecoded(int? seq) {
|
2025-05-08 10:13:44 +08:00
|
|
|
|
if (seq == null || !_iFrameSeqWindow.contains(seq)) {
|
|
|
|
|
|
_dropCount++;
|
|
|
|
|
|
// print('[FrameDependencyManager][调试] 当前I帧窗口: ${_iFrameSeqWindow.toString()},待查找I帧序号: $seq');
|
|
|
|
|
|
if (_dropCount >= dropThreshold) {
|
|
|
|
|
|
print('[FrameDependencyManager][自愈] 连续丢帧$_dropCount次,自动reset依赖窗口');
|
|
|
|
|
|
reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
2025-04-30 16:12:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|