fix:完成720P 20帧渲染需求
This commit is contained in:
parent
a546989a25
commit
5968c4a980
@ -19,12 +19,14 @@ class VideoTypeE extends $pb.ProtobufEnum {
|
||||
static const VideoTypeE H264 = VideoTypeE._(1, _omitEnumNames ? '' : 'H264');
|
||||
static const VideoTypeE IMAGE = VideoTypeE._(2, _omitEnumNames ? '' : 'IMAGE');
|
||||
static const VideoTypeE VP8 = VideoTypeE._(3, _omitEnumNames ? '' : 'VP8');
|
||||
static const VideoTypeE H264_720P = VideoTypeE._(4, _omitEnumNames ? '' : 'H264_720P');
|
||||
|
||||
static const $core.List<VideoTypeE> values = <VideoTypeE> [
|
||||
NONE_V,
|
||||
H264,
|
||||
IMAGE,
|
||||
VP8,
|
||||
H264_720P,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, VideoTypeE> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -56,6 +56,7 @@ class _TalkViewNativeDecodePageState extends State<TalkViewNativeDecodePage>
|
||||
state.animationController.forward();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
@ -71,6 +72,7 @@ class _TalkViewNativeDecodePageState extends State<TalkViewNativeDecodePage>
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
// 悬浮帧率统计信息条
|
||||
Obx(
|
||||
() {
|
||||
final double screenWidth = MediaQuery.of(context).size.width;
|
||||
@ -93,32 +95,84 @@ class _TalkViewNativeDecodePageState extends State<TalkViewNativeDecodePage>
|
||||
final double scaleWidth = physicalWidth / rotatedImageWidth;
|
||||
final double scaleHeight = physicalHeight / rotatedImageHeight;
|
||||
max(scaleWidth, scaleHeight); // 选择较大的缩放比例
|
||||
|
||||
return state.isLoading.isTrue
|
||||
? Image.asset(
|
||||
'images/main/monitorBg.png',
|
||||
width: screenWidth,
|
||||
height: screenHeight,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: PopScope(
|
||||
canPop: false,
|
||||
child: RepaintBoundary(
|
||||
key: state.globalKey,
|
||||
child: SizedBox.expand(
|
||||
child: RotatedBox(
|
||||
// 解码器不支持硬件旋转,使用RotatedBox
|
||||
quarterTurns: -1,
|
||||
child: Texture(
|
||||
textureId: state.textureId.value!,
|
||||
filterQuality: FilterQuality.medium,
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: state.isLoading.isTrue
|
||||
? Image.asset(
|
||||
'images/main/monitorBg.png',
|
||||
width: screenWidth,
|
||||
height: screenHeight,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: PopScope(
|
||||
canPop: false,
|
||||
child: RepaintBoundary(
|
||||
key: state.globalKey,
|
||||
child: SizedBox.expand(
|
||||
child: RotatedBox(
|
||||
// 解码器不支持硬件旋转,使用RotatedBox
|
||||
quarterTurns: -1,
|
||||
child: Texture(
|
||||
textureId: state.textureId.value!,
|
||||
filterQuality: FilterQuality.medium,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
top: 300.h,
|
||||
right: 20.w,
|
||||
child: Obx(() => Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.network_check, color: Colors.redAccent, size: 18),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
'接受服务端H264帧率/秒: ',
|
||||
style: TextStyle(color: Colors.white, fontSize: 15),
|
||||
),
|
||||
Text(
|
||||
'${state.networkH264Fps.value}',
|
||||
style: TextStyle(color: Colors.redAccent, fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(' fps', style: TextStyle(color: Colors.white, fontSize: 13)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.send, color: Colors.blueAccent, size: 18),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
'送入Native帧率/秒: ',
|
||||
style: TextStyle(color: Colors.white, fontSize: 15),
|
||||
),
|
||||
Text(
|
||||
'${state.nativeSendFps.value}',
|
||||
style: TextStyle(color: Colors.blueAccent, fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(' fps', style: TextStyle(color: Colors.white, fontSize: 13)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
),
|
||||
Obx(() => state.isLoading.isTrue
|
||||
? Positioned(
|
||||
bottom: 310.h,
|
||||
@ -127,102 +181,6 @@ class _TalkViewNativeDecodePageState extends State<TalkViewNativeDecodePage>
|
||||
style: TextStyle(color: Colors.black, fontSize: 26.sp),
|
||||
))
|
||||
: Container()),
|
||||
Obx(() => state.textureId.value != null && state.showFps.value
|
||||
? Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 10.h,
|
||||
right: 20.w,
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(5.h),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
// Text(
|
||||
// 'FPS: ${state.decoderFps.value.toStringAsFixed(1)}',
|
||||
// style: TextStyle(
|
||||
// color: _getPacketLossColor(
|
||||
// state.packetLossRate.value),
|
||||
// fontSize: 20.sp,
|
||||
// ),
|
||||
// ),
|
||||
Text(
|
||||
'丢包率: ${state.packetLossRate.value.toStringAsFixed(1)}%',
|
||||
style: TextStyle(
|
||||
color: _getPacketLossColor(
|
||||
state.packetLossRate.value),
|
||||
fontSize: 20.sp,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'消息丢失: ${state.messageLossRate.value.toStringAsFixed(1)}%',
|
||||
style: TextStyle(
|
||||
color: _getPacketLossColor(
|
||||
state.messageLossRate.value),
|
||||
fontSize: 20.sp,
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.white30,
|
||||
height: 10.h,
|
||||
thickness: 1),
|
||||
Text(
|
||||
'已渲染帧: ${state.renderedFrameCount.value}',
|
||||
style:
|
||||
TextStyle(color: Colors.white, fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'总帧数: ${state.totalFrames.value}',
|
||||
style:
|
||||
TextStyle(color: Colors.white, fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'丢弃帧: ${state.droppedFrames.value}',
|
||||
style:
|
||||
TextStyle(color: Colors.white, fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'IDR帧: ${state.hasSentIDR.value ? "已发送" : "未发送"}',
|
||||
style: TextStyle(
|
||||
color: state.hasSentIDR.value
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'SPS: ${state.hasSentSPS.value ? "已发送" : "未发送"}',
|
||||
style: TextStyle(
|
||||
color: state.hasSentSPS.value
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'PPS: ${state.hasSentPPS.value ? "已发送" : "未发送"}',
|
||||
style: TextStyle(
|
||||
color: state.hasSentPPS.value
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'keyFrameInterval: ${state.keyFrameInterval.value}',
|
||||
style:
|
||||
TextStyle(color: Colors.green, fontSize: 18.sp),
|
||||
),
|
||||
Text(
|
||||
'decodingJitterMs: ${state.decodingJitterMs.value}',
|
||||
style:
|
||||
TextStyle(color: Colors.green, fontSize: 18.sp),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()),
|
||||
Obx(() => state.isLoading.isFalse && state.oneMinuteTime.value > 0
|
||||
? Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 75.h,
|
||||
|
||||
@ -106,4 +106,19 @@ class TalkViewNativeDecodeState {
|
||||
|
||||
// 帧跟踪Map,记录每个提交的帧,key为textureId_frameSeq
|
||||
Map<String, Map<String, dynamic>> frameTracker = {};
|
||||
|
||||
// H264帧缓冲区相关
|
||||
final List<Map<String, dynamic>> h264FrameBuffer = <Map<String, dynamic>>[]; // H264帧缓冲区,存储帧数据和类型
|
||||
final int maxFrameBufferSize = 25; // 最大缓冲区大小
|
||||
final int targetFps = 120; // 目标解码帧率
|
||||
Timer? frameProcessTimer; // 帧处理定时器
|
||||
bool isProcessingFrame = false; // 是否正在处理帧
|
||||
int lastProcessedTimestamp = 0; // 上次处理帧的时间戳
|
||||
// H264文件保存相关
|
||||
String? h264FilePath;
|
||||
File? h264File;
|
||||
|
||||
// 新增:用于页面显示的帧率统计
|
||||
RxInt networkH264Fps = 0.obs;
|
||||
RxInt nativeSendFps = 0.obs;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user