bug
This commit is contained in:
parent
ebe5b8a756
commit
e9f59c223f
@ -726,9 +726,13 @@ class LockDetailLogic extends BaseGetXController {
|
||||
// 判断是否为WiFi锁
|
||||
final network = currentKeyInfo.network;
|
||||
if (network != null && (network.peerId != null && network.peerId!.isNotEmpty)){
|
||||
showToast('wifi锁进行蓝牙透传开锁'.tr);
|
||||
// 发送蓝牙透传开锁指令
|
||||
await _sendUnlockViaBluetooth();
|
||||
} else {
|
||||
}
|
||||
// 判断是否为网关锁
|
||||
if (state.keyInfos.value.hasGateway == 1) {
|
||||
showToast('网关锁进行远程开锁api开锁'.tr);
|
||||
// 发送远程开锁API
|
||||
final LoginEntity entity = await ApiRepository.to.remoteOpenLock(lockId: lockId.toString(), timeOut: 60);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
|
||||
@ -398,8 +398,6 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
} else if (bufferLength > 40) {
|
||||
// 其他平台原有逻辑
|
||||
_dropOldPFrame();
|
||||
} else if (bufferLength > 30) {
|
||||
_dropSomeBFrame();
|
||||
}
|
||||
}
|
||||
void _dropOldFramesAggressively() {
|
||||
@ -423,50 +421,63 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
_invalidateFrameIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void _dropSomeBFrame() {
|
||||
// 如果存在B帧,丢弃部分旧的B帧
|
||||
final bFrameIndex = state.h264FrameBuffer.indexWhere((frame) =>
|
||||
frame['frameType'] == TalkDataH264Frame_FrameTypeE.I &&
|
||||
frame['frameSeq'] < (_lastFrameSeq ?? 0) - 30);
|
||||
|
||||
if (bFrameIndex != -1) {
|
||||
state.h264FrameBuffer.removeAt(bFrameIndex);
|
||||
|
||||
/// 仅保留关键帧(I帧和最近的P帧)以减少处理负载
|
||||
void _keepOnlyKeyFrames() {
|
||||
final List<Map<String, dynamic>> keyFrames = [];
|
||||
int lastPFrameIndex = -1;
|
||||
|
||||
// 从后向前遍历,优先保留最新的帧
|
||||
for (int i = state.h264FrameBuffer.length - 1; i >= 0; i--) {
|
||||
final frame = state.h264FrameBuffer[i];
|
||||
final frameType = frame['frameType'];
|
||||
|
||||
if (frameType == TalkDataH264Frame_FrameTypeE.I) {
|
||||
keyFrames.add(frame);
|
||||
break; // 找到最新的I帧后停止
|
||||
} else if (frameType == TalkDataH264Frame_FrameTypeE.P && lastPFrameIndex == -1) {
|
||||
keyFrames.add(frame);
|
||||
lastPFrameIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyFrames.isNotEmpty) {
|
||||
// 只保留关键帧,反转顺序使其按时间顺序排列
|
||||
state.h264FrameBuffer.clear();
|
||||
state.h264FrameBuffer.addAll(keyFrames.reversed);
|
||||
_invalidateFrameIndex();
|
||||
}
|
||||
}
|
||||
|
||||
/// 启动帧处理定时器
|
||||
/// 启动帧处理定时器 - 优化版:动态帧率调整
|
||||
void _startFrameProcessTimer() {
|
||||
// 取消已有定时器
|
||||
_stopFrameProcessTimer();
|
||||
|
||||
// 计算定时器间隔,确保以目标帧率处理帧
|
||||
// iOS平台使用更精确的定时器间隔
|
||||
final int intervalMs = Platform.isIOS
|
||||
// 初始间隔设置
|
||||
int baseIntervalMs = Platform.isIOS
|
||||
? max(16, min(33, (1000 / state.targetFps).round())) // iOS使用更严格的范围
|
||||
: max(16, min(40, (1000 / state.targetFps).round()));
|
||||
|
||||
// 创建新定时器
|
||||
state.frameProcessTimer = Timer.periodic(Duration(milliseconds: intervalMs), (timer) {
|
||||
state.frameProcessTimer = Timer.periodic(Duration(milliseconds: baseIntervalMs), (timer) {
|
||||
_processNextFrameFromBuffer();
|
||||
});
|
||||
AppLog.log('启动帧处理定时器,目标帧率: ${state.targetFps}fps,间隔: ${intervalMs}ms');
|
||||
AppLog.log('启动帧处理定时器,目标帧率: ${state.targetFps}fps,初始间隔: ${baseIntervalMs}ms');
|
||||
}
|
||||
|
||||
/// 添加:快速清理缓冲区方法
|
||||
void _clearFrameBufferQuickly() {
|
||||
// 只保留最新的少量帧,加快切换响应
|
||||
if (state.h264FrameBuffer.length > 3) {
|
||||
// 保留最新的3帧
|
||||
state.h264FrameBuffer.removeRange(0, state.h264FrameBuffer.length - 3);
|
||||
}
|
||||
// 完全清空帧缓冲区,避免旧帧影响新流
|
||||
state.h264FrameBuffer.clear();
|
||||
|
||||
// 重置帧序列状态
|
||||
_lastFrameSeq = null;
|
||||
lastDecodedIFrameSeq = null;
|
||||
_decodedIFrames.clear();
|
||||
state.isProcessingFrame = false;
|
||||
_frameIndexDirty = true;
|
||||
_frameIndexCache.clear();
|
||||
}
|
||||
|
||||
/// 停止帧处理定时器
|
||||
@ -575,8 +586,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
return state.h264FrameBuffer.isNotEmpty ? 0 : -1;
|
||||
}
|
||||
|
||||
/// 从缓冲区处理下一帧
|
||||
void _processNextFrameFromBuffer() async {
|
||||
/// 从缓冲区处理下一帧 - 优化版:简化逻辑和动态调整
|
||||
Future<void> _processNextFrameFromBuffer() async {
|
||||
final stopwatch = Stopwatch()..start();
|
||||
_monitorFrameProcessingPerformance();
|
||||
final startTime = DateTime.now().microsecondsSinceEpoch;
|
||||
@ -600,12 +611,23 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
try {
|
||||
state.isProcessingFrame = true;
|
||||
|
||||
// 添加智能丢帧策略
|
||||
_implementSmartFrameDropping();
|
||||
// 智能丢帧策略:根据缓冲区大小动态调整
|
||||
final bufferLength = state.h264FrameBuffer.length;
|
||||
if (bufferLength > 50) {
|
||||
// 缓冲区溢出,保留最新20帧
|
||||
final newBuffer = state.h264FrameBuffer.sublist(max(0, bufferLength - 20));
|
||||
state.h264FrameBuffer.clear();
|
||||
state.h264FrameBuffer.addAll(newBuffer);
|
||||
_invalidateFrameIndex();
|
||||
} else if (bufferLength > 30 && Platform.isAndroid) {
|
||||
// Android平台缓冲区较大时,只处理I帧和关键P帧
|
||||
_keepOnlyKeyFrames();
|
||||
} else {
|
||||
// 正常智能丢帧
|
||||
_implementSmartFrameDropping();
|
||||
}
|
||||
|
||||
// 动态调整处理策略基于缓冲区长度
|
||||
final bufferLength = state.h264FrameBuffer.length;
|
||||
|
||||
// 更智能的帧率调整策略
|
||||
// iOS平台优化:更积极的缓冲区管理
|
||||
if (Platform.isIOS) {
|
||||
@ -1306,7 +1328,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
AppLog.log(error.message!);
|
||||
}
|
||||
|
||||
// 切换清晰度的方法,后续补充具体实现
|
||||
// 切换清晰度的方法,优化切换速度
|
||||
void onQualityChanged(String quality) async {
|
||||
state.currentQuality.value = quality;
|
||||
TalkExpectReq talkExpectReq = StartChartManage().getDefaultTalkExpect();
|
||||
@ -1335,8 +1357,27 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
/// 修改发送预期数据
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq);
|
||||
|
||||
// 不立即loading,继续解码旧流帧,等待frameSeq回绕检测
|
||||
// 仅重置frameSeq回绕检测标志
|
||||
// 立即切换清晰度:清理旧帧缓冲区并重新初始化解码器
|
||||
// 1. 停止当前帧处理
|
||||
_stopFrameProcessTimer();
|
||||
|
||||
// 2. 立即清理旧的帧缓冲区
|
||||
_clearFrameBufferQuickly();
|
||||
|
||||
// 3. 更新视频分辨率设置
|
||||
StartChartManage().videoWidth = width;
|
||||
StartChartManage().videoHeight = height;
|
||||
|
||||
// 4. 立即重新初始化解码器
|
||||
await _resetDecoderForNewStream(width, height);
|
||||
|
||||
// 5. 启动帧处理
|
||||
_startFrameProcessTimer();
|
||||
|
||||
// 6. 显示加载动画
|
||||
Future.microtask(() => state.isLoading.value = true);
|
||||
|
||||
// 7. 重置帧序列相关状态
|
||||
_pendingStreamReset = false;
|
||||
_pendingResetWidth = width;
|
||||
_pendingResetHeight = height;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user