/// NALU相关工具类与结构体 import 'dart:typed_data'; /// NALU单元结构体 class NaluUnit { final int type; // NALU类型 final List data; NaluUnit(this.type, this.data); } class NaluUtils { /// 分离一帧数据中的所有NALU单元 static List splitNalus(List data) { final List nalus = []; int i = 0; List startCodes = []; // 先找到所有起始码位置 while (i < data.length - 3) { if (i < data.length - 4 && data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 && data[i + 3] == 1) { startCodes.add(i); i += 4; } else if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1) { startCodes.add(i); i += 3; } else { i++; } } // 补上结尾 startCodes.add(data.length); // 分割NALU int nalusTotalLen = 0; for (int idx = 0; idx < startCodes.length - 1; idx++) { int start = startCodes[idx]; int next = startCodes[idx + 1]; int skip = (data[start] == 0 && data[start + 1] == 0 && data[start + 2] == 0 && data[start + 3] == 1) ? 4 : 3; int naluStart = start + skip; if (naluStart < next) { final nalu = data.sublist(start, next); nalusTotalLen += nalu.length; if (nalu.isNotEmpty) { nalus.add(NaluUnit(getNaluType(nalu), nalu)); } } } if (nalus.isEmpty && data.isNotEmpty) { nalus.add(NaluUnit(getNaluType(data), data)); } else if (nalusTotalLen < data.length) { nalus.add(NaluUnit(getNaluType(data.sublist(nalusTotalLen)), data.sublist(nalusTotalLen))); } return nalus; } /// 获取NALU类型 static int getNaluType(List nalu) { if (nalu.isEmpty) return -1; int offset = 0; if (nalu.length >= 4 && nalu[0] == 0x00 && nalu[1] == 0x00) { if (nalu[2] == 0x01) offset = 3; else if (nalu[2] == 0x00 && nalu[3] == 0x01) offset = 4; } if (nalu.length > offset) { return nalu[offset] & 0x1F; } return -1; } /// 提取所有指定type的NALU并拼接返回 static List filterNalusByType(List frameData, int type) { final nalus = splitNalus(frameData); final filtered = nalus.where((nalu) => nalu.type == type).toList(); final result = []; for (final nalu in filtered) { result.addAll(nalu.data); } return result; } }