138 lines
2.6 KiB
Dart
138 lines
2.6 KiB
Dart
import 'dart:typed_data';
|
||
|
||
/// H.264帧生成器
|
||
/// 生成简单的H.264帧数据,用于测试
|
||
class H264FrameGenerator {
|
||
// 视频宽度
|
||
final int width;
|
||
|
||
// 视频高度
|
||
final int height;
|
||
|
||
// 序列参数集 (SPS) - 一个简单的示例
|
||
// 注意:这不是一个完全有效的SPS,仅用于测试
|
||
final List<int> _spsData = [
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x01,
|
||
0x67,
|
||
0x42,
|
||
0x00,
|
||
0x0A,
|
||
0xF8,
|
||
0x41,
|
||
0xA2,
|
||
0x00,
|
||
0x00,
|
||
0x03,
|
||
0x00,
|
||
0x01,
|
||
0x00,
|
||
0x00,
|
||
0x03,
|
||
0x00,
|
||
0x32,
|
||
0x0F,
|
||
0x18,
|
||
0x31,
|
||
0x8C
|
||
];
|
||
|
||
// 图像参数集 (PPS) - 一个简单的示例
|
||
// 注意:这不是一个完全有效的PPS,仅用于测试
|
||
final List<int> _ppsData = [0x00, 0x00, 0x00, 0x01, 0x68, 0xCE, 0x38, 0x80];
|
||
|
||
// I帧的起始数据示例 - 这只是一个示例头部
|
||
final List<int> _iFrameHeader = [
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x01,
|
||
0x65,
|
||
0x88,
|
||
0x80,
|
||
0x00,
|
||
0x00,
|
||
0x03,
|
||
0x00,
|
||
0x02,
|
||
0x00
|
||
];
|
||
|
||
// P帧的起始数据示例 - 这只是一个示例头部
|
||
final List<int> _pFrameHeader = [
|
||
0x00,
|
||
0x00,
|
||
0x00,
|
||
0x01,
|
||
0x41,
|
||
0x9A,
|
||
0x1C,
|
||
0x0D,
|
||
0x3E,
|
||
0x04
|
||
];
|
||
|
||
// 当前帧计数
|
||
int _frameCount = 0;
|
||
|
||
// 每个I帧之间的P帧数量
|
||
final int _pFramesPerIFrame = 9;
|
||
|
||
/// 构造函数
|
||
H264FrameGenerator({
|
||
required this.width,
|
||
required this.height,
|
||
});
|
||
|
||
/// 获取SPS和PPS数据
|
||
Uint8List getConfigurationData() {
|
||
// 组合SPS和PPS
|
||
List<int> data = [];
|
||
data.addAll(_spsData);
|
||
data.addAll(_ppsData);
|
||
return Uint8List.fromList(data);
|
||
}
|
||
|
||
/// 生成下一帧数据
|
||
/// 返回 (帧数据, 是否为I帧)
|
||
(Uint8List, bool) generateNextFrame() {
|
||
_frameCount++;
|
||
|
||
// 每10帧插入一个I帧
|
||
bool isIFrame = _frameCount % (_pFramesPerIFrame + 1) == 1;
|
||
|
||
List<int> frameData = [];
|
||
|
||
if (isIFrame) {
|
||
// I帧: 添加SPS和PPS,并添加I帧数据
|
||
frameData.addAll(_spsData);
|
||
frameData.addAll(_ppsData);
|
||
frameData.addAll(_iFrameHeader);
|
||
|
||
// 添加一些模拟的I帧数据
|
||
// 实际中,这里应该是真实的编码数据
|
||
for (int i = 0; i < 1000; i++) {
|
||
frameData.add((i * 13) % 256);
|
||
}
|
||
} else {
|
||
// P帧: 只添加P帧数据
|
||
frameData.addAll(_pFrameHeader);
|
||
|
||
// 添加一些模拟的P帧数据
|
||
// 实际中,这里应该是真实的编码数据
|
||
for (int i = 0; i < 300; i++) {
|
||
frameData.add((i * 7 + _frameCount) % 256);
|
||
}
|
||
}
|
||
|
||
return (Uint8List.fromList(frameData), isIFrame);
|
||
}
|
||
|
||
/// 重置帧计数
|
||
void reset() {
|
||
_frameCount = 0;
|
||
}
|
||
}
|