fix:优化h264组装帧方法,增加调试日志

This commit is contained in:
liyi 2025-02-24 17:03:31 +08:00
parent b59dafc37c
commit 43eeef237f
4 changed files with 52 additions and 28 deletions

View File

@ -56,7 +56,7 @@
},
flushingTime: 0, // 禁用自动刷新
clearBuffer: false, // 保留解码缓存
maxBufferLength: 2,
fps:20,
onReady: () => {
console.log('播放器初始化完成');
// 通知Flutter端准备就绪

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import '../../../blue/io_reply.dart';
import '../../lockMian/entity/lockListInfo_entity.dart';
@ -9,7 +10,7 @@ import '../../lockMian/entity/lockListInfo_entity.dart';
class LockDetailState {
Rx<LockListInfoItemEntity> keyInfos = LockListInfoItemEntity().obs;
final Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
late StreamSubscription<Reply> replySubscription;
StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription;

View File

@ -160,6 +160,8 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame();
talkDataH264Frame.mergeFromBuffer(talkData.content);
frameHandler.handleFrame(talkDataH264Frame);
AppLog.log(
"帧:${talkDataH264Frame.frameType},帧序号:${talkDataH264Frame.frameSeq},对应I帧序号${talkDataH264Frame.frameSeqI}");
}
///

View File

@ -1,52 +1,51 @@
import 'dart:collection';
import 'dart:typed_data';
import 'package:star_lock/app_settings/app_settings.dart';
import '../../proto/talk_data_h264_frame.pb.dart';
class H264FrameHandler {
final Map<int, TalkDataH264Frame> _frameBuffer = {};
final LinkedHashMap<int, TalkDataH264Frame> _frameBuffer = LinkedHashMap();
final void Function(List<int> frameData) onCompleteFrame;
int _lastProcessedSeq = -1;
final LinkedHashMap<int, TalkDataH264Frame_FrameTypeE> _frameTypeIndex = LinkedHashMap();
H264FrameHandler({required this.onCompleteFrame});
void handleFrame(TalkDataH264Frame frame) {
//
_frameBuffer[frame.frameSeq] = frame;
_frameTypeIndex[frame.frameSeq] = frame.frameType;
// GOP (Group of Pictures)
_tryAssembleFrames(frame.frameSeq);
}
void _tryAssembleFrames(int currentSeq) {
//
final List<int> sortedSeqs = _frameBuffer.keys.toList()..sort();
final List<int> framesToProcess = [];
int? startFrameSeq;
// I P
int? startFrameSeq;
for (var seq in sortedSeqs.reversed) {
final frame = _frameBuffer[seq];
if (frame?.frameType == TalkDataH264Frame_FrameTypeE.I) {
for (int seq = currentSeq; seq >= 0; seq--) {
final frameType = _frameTypeIndex[seq];
if (frameType == null) continue;
if (frameType == TalkDataH264Frame_FrameTypeE.I) {
startFrameSeq = seq;
break;
} else if (frame?.frameType == TalkDataH264Frame_FrameTypeE.P) {
// P I
if (_frameBuffer.containsKey(frame?.frameSeqI)) {
} else if (frameType == TalkDataH264Frame_FrameTypeE.P) {
if (_frameBuffer.containsKey(_frameBuffer[seq]!.frameSeqI)) {
startFrameSeq = seq;
break;
} else {
// I P
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
}
}
if (startFrameSeq != null) {
// I P
int expectedSeq = startFrameSeq;
for (var seq in sortedSeqs.where((s) => s >= startFrameSeq!)) {
if (seq != expectedSeq) break;
for (int seq = startFrameSeq; _frameBuffer.containsKey(seq); seq++) {
framesToProcess.add(seq);
expectedSeq++;
}
if (framesToProcess.isNotEmpty) {
@ -57,28 +56,50 @@ class H264FrameHandler {
}
}
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
}
void _processFrames(List<int> frameSeqs) {
//
final List<int> assembledData = [];
// final List<int> assembledData = [];
//
// for (var seq in frameSeqs) {
// final frame = _frameBuffer[seq]!;
// assembledData.addAll(frame.frameData);
//
// //
// _frameBuffer.remove(seq);
// }
//
// //
// onCompleteFrame(assembledData);
// Calculate the total length of the assembled data
int totalLength = frameSeqs.fold(
0, (sum, seq) => sum + _frameBuffer[seq]!.frameData.length);
// Allocate a buffer for the assembled data
final assembledData = Uint8List(totalLength);
int offset = 0;
for (var seq in frameSeqs) {
final frame = _frameBuffer[seq]!;
assembledData.addAll(frame.frameData);
assembledData.setRange(
offset, offset + frame.frameData.length, frame.frameData);
offset += frame.frameData.length;
//
// Remove the frame from the buffer after processing
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
//
// Callback with the complete frame data
onCompleteFrame(assembledData);
}
void clear() {
_frameBuffer.clear();
}
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
_frameTypeIndex.removeWhere((seq, frameType) => seq < currentSeq - 200);
}
}