From 338d24570d962e2918ff82c897cbf64a72e9aa36 Mon Sep 17 00:00:00 2001 From: liyi Date: Wed, 30 Apr 2025 16:56:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:v1=E7=89=88=E6=9C=AC=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/frame_dependency_manager.dart | 16 ++++++++++------ lib/video_decode_plugin.dart | 15 +++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/frame_dependency_manager.dart b/lib/frame_dependency_manager.dart index e1bb3a7..69e0aef 100644 --- a/lib/frame_dependency_manager.dart +++ b/lib/frame_dependency_manager.dart @@ -4,7 +4,8 @@ import 'dart:typed_data'; class FrameDependencyManager { Uint8List? _sps; Uint8List? _pps; - int? _lastIFrameSeq; + final int windowSize = 30; + final List _iFrameSeqWindow = []; /// 更新SPS缓存 void updateSps(Uint8List sps) { @@ -18,14 +19,17 @@ class FrameDependencyManager { Uint8List? get pps => _pps; /// 判断是否有可用I帧 - bool get hasIFrame => _lastIFrameSeq != null; - int? get lastIFrameSeq => _lastIFrameSeq; + bool get hasIFrame => _iFrameSeqWindow.isNotEmpty; + int? get lastIFrameSeq => _iFrameSeqWindow.isNotEmpty ? _iFrameSeqWindow.last : null; void updateIFrameSeq(int seq) { - _lastIFrameSeq = seq; + _iFrameSeqWindow.add(seq); + if (_iFrameSeqWindow.length > windowSize) { + _iFrameSeqWindow.removeAt(0); + } } - /// 判断指定I帧序号是否为最近一次成功解码的I帧 + /// 判断指定I帧序号是否在滑动窗口内 bool isIFrameDecoded(int? seq) { - return seq != null && seq == _lastIFrameSeq; + return seq != null && _iFrameSeqWindow.contains(seq); } } \ No newline at end of file diff --git a/lib/video_decode_plugin.dart b/lib/video_decode_plugin.dart index daa8f2c..46cae30 100644 --- a/lib/video_decode_plugin.dart +++ b/lib/video_decode_plugin.dart @@ -156,26 +156,21 @@ class VideoDecodePlugin { refIFrameSeq: frameSeq, ); _depManager.updateIFrameSeq(frameSeq); - print('[VideoDecodePlugin] 发送I帧及SPS/PPS(缓存), frameSeq=$frameSeq'); return; } // 首次无缓存时分割并缓存SPS/PPS final nalus = NaluUtils.splitNalus(frameData); - print('[调试] frameSeq=$frameSeq, 分割出NALU数量=${nalus.length}'); - for (final nalu in nalus) { - print('[调试] NALU type=${nalu.type}, length=${nalu.data.length}'); - } + List? sps, pps; for (final nalu in nalus) { - if (nalu.type == 7) sps = nalu.data; + if (nalu.type == 7) + sps = nalu.data; else if (nalu.type == 8) pps = nalu.data; } if (sps != null) { - print('[调试] SPS被缓存, 长度=${sps.length}'); _depManager.updateSps(Uint8List.fromList(sps)); } if (pps != null) { - print('[调试] PPS被缓存, 长度=${pps.length}'); _depManager.updatePps(Uint8List.fromList(pps)); } if (_depManager.sps == null || _depManager.pps == null) { @@ -204,7 +199,6 @@ class VideoDecodePlugin { refIFrameSeq: frameSeq, ); _depManager.updateIFrameSeq(frameSeq); - print('[VideoDecodePlugin] 发送I帧及SPS/PPS(首次分割), frameSeq=$frameSeq'); return; } // 兼容直接推送SPS/PPS/I帧/P帧等场景,直接发送 @@ -221,7 +215,8 @@ class VideoDecodePlugin { // P帧依赖链完整性校验 if (frameType == 1) { if (!_depManager.isIFrameDecoded(refIFrameSeq)) { - print('[丢帧] P帧依赖的I帧未解码,丢弃 frameSeq=$frameSeq, refIFrameSeq=$refIFrameSeq'); + print( + '[丢帧] P帧依赖的I帧未解码,丢弃 frameSeq=$frameSeq, refIFrameSeq=$refIFrameSeq'); return; } }