feat:v1版本完成
This commit is contained in:
parent
491e2be4a6
commit
338d24570d
@ -4,7 +4,8 @@ import 'dart:typed_data';
|
|||||||
class FrameDependencyManager {
|
class FrameDependencyManager {
|
||||||
Uint8List? _sps;
|
Uint8List? _sps;
|
||||||
Uint8List? _pps;
|
Uint8List? _pps;
|
||||||
int? _lastIFrameSeq;
|
final int windowSize = 30;
|
||||||
|
final List<int> _iFrameSeqWindow = [];
|
||||||
|
|
||||||
/// 更新SPS缓存
|
/// 更新SPS缓存
|
||||||
void updateSps(Uint8List sps) {
|
void updateSps(Uint8List sps) {
|
||||||
@ -18,14 +19,17 @@ class FrameDependencyManager {
|
|||||||
Uint8List? get pps => _pps;
|
Uint8List? get pps => _pps;
|
||||||
|
|
||||||
/// 判断是否有可用I帧
|
/// 判断是否有可用I帧
|
||||||
bool get hasIFrame => _lastIFrameSeq != null;
|
bool get hasIFrame => _iFrameSeqWindow.isNotEmpty;
|
||||||
int? get lastIFrameSeq => _lastIFrameSeq;
|
int? get lastIFrameSeq => _iFrameSeqWindow.isNotEmpty ? _iFrameSeqWindow.last : null;
|
||||||
void updateIFrameSeq(int seq) {
|
void updateIFrameSeq(int seq) {
|
||||||
_lastIFrameSeq = seq;
|
_iFrameSeqWindow.add(seq);
|
||||||
|
if (_iFrameSeqWindow.length > windowSize) {
|
||||||
|
_iFrameSeqWindow.removeAt(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 判断指定I帧序号是否为最近一次成功解码的I帧
|
/// 判断指定I帧序号是否在滑动窗口内
|
||||||
bool isIFrameDecoded(int? seq) {
|
bool isIFrameDecoded(int? seq) {
|
||||||
return seq != null && seq == _lastIFrameSeq;
|
return seq != null && _iFrameSeqWindow.contains(seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,26 +156,21 @@ class VideoDecodePlugin {
|
|||||||
refIFrameSeq: frameSeq,
|
refIFrameSeq: frameSeq,
|
||||||
);
|
);
|
||||||
_depManager.updateIFrameSeq(frameSeq);
|
_depManager.updateIFrameSeq(frameSeq);
|
||||||
print('[VideoDecodePlugin] 发送I帧及SPS/PPS(缓存), frameSeq=$frameSeq');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 首次无缓存时分割并缓存SPS/PPS
|
// 首次无缓存时分割并缓存SPS/PPS
|
||||||
final nalus = NaluUtils.splitNalus(frameData);
|
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<int>? sps, pps;
|
List<int>? sps, pps;
|
||||||
for (final nalu in nalus) {
|
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;
|
else if (nalu.type == 8) pps = nalu.data;
|
||||||
}
|
}
|
||||||
if (sps != null) {
|
if (sps != null) {
|
||||||
print('[调试] SPS被缓存, 长度=${sps.length}');
|
|
||||||
_depManager.updateSps(Uint8List.fromList(sps));
|
_depManager.updateSps(Uint8List.fromList(sps));
|
||||||
}
|
}
|
||||||
if (pps != null) {
|
if (pps != null) {
|
||||||
print('[调试] PPS被缓存, 长度=${pps.length}');
|
|
||||||
_depManager.updatePps(Uint8List.fromList(pps));
|
_depManager.updatePps(Uint8List.fromList(pps));
|
||||||
}
|
}
|
||||||
if (_depManager.sps == null || _depManager.pps == null) {
|
if (_depManager.sps == null || _depManager.pps == null) {
|
||||||
@ -204,7 +199,6 @@ class VideoDecodePlugin {
|
|||||||
refIFrameSeq: frameSeq,
|
refIFrameSeq: frameSeq,
|
||||||
);
|
);
|
||||||
_depManager.updateIFrameSeq(frameSeq);
|
_depManager.updateIFrameSeq(frameSeq);
|
||||||
print('[VideoDecodePlugin] 发送I帧及SPS/PPS(首次分割), frameSeq=$frameSeq');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 兼容直接推送SPS/PPS/I帧/P帧等场景,直接发送
|
// 兼容直接推送SPS/PPS/I帧/P帧等场景,直接发送
|
||||||
@ -221,7 +215,8 @@ class VideoDecodePlugin {
|
|||||||
// P帧依赖链完整性校验
|
// P帧依赖链完整性校验
|
||||||
if (frameType == 1) {
|
if (frameType == 1) {
|
||||||
if (!_depManager.isIFrameDecoded(refIFrameSeq)) {
|
if (!_depManager.isIFrameDecoded(refIFrameSeq)) {
|
||||||
print('[丢帧] P帧依赖的I帧未解码,丢弃 frameSeq=$frameSeq, refIFrameSeq=$refIFrameSeq');
|
print(
|
||||||
|
'[丢帧] P帧依赖的I帧未解码,丢弃 frameSeq=$frameSeq, refIFrameSeq=$refIFrameSeq');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user