public static void AvccToAnnexb4(AvccHeader Header, byte[] Packet, System.Action <byte[]> EnumAnnexBPacket) { System.Action <byte[]> EnumPacket = (RawPacket) => { // ignore non iframes /* gr: why was I ignoring these? * var nt = GetNaluType(RawPacket[0]); * if (nt != NaluType.IFrame && nt != NaluType.PFrame) * { * return; * } */ //Debug.Log("Found " + nt + " x" + RawPacket.Length + "bytes"); var AnnexPacketData = new List <byte>(); // https://github.com/SoylentGraham/SoyLib/blob/master/src/SoyH264.cpp#L328 AnnexPacketData.Add(0); AnnexPacketData.Add(0); AnnexPacketData.Add(0); AnnexPacketData.Add(1); //AnnexPacketData.Add(GetNaluTypeByte(NaluType.AccessUnitDelimiter)); //AnnexPacketData.Add(0xf0); AnnexPacketData.AddRange(RawPacket); EnumAnnexBPacket(AnnexPacketData.ToArray()); }; SplitPacket_Avcc(Header, Packet, EnumPacket); }
// split avcc packets public static AvccHeader ParseAvccHeader(byte[] Data) { // https://stackoverflow.com/a/24890903/355753 int Offset = 0; /*var Version =*/ Get8(Data, ref Offset); var Profile = Get8(Data, ref Offset); /*var Compatibility =*/ Get8(Data, ref Offset); var Level8 = Get8(Data, ref Offset); var ReservedAndNaluLengthMinusOne = Get8(Data, ref Offset); var ReservedAndSpsCount = Get8(Data, ref Offset); var NaluLengthMinusOne = ReservedAndNaluLengthMinusOne & ((1 << 2) - 1); var SpsCount = ReservedAndSpsCount & ((1 << 5) - 1); var Header = new AvccHeader(Profile, Level8, NaluLengthMinusOne); for (int i = 0; i < SpsCount; i++) { var SpsSize = Get16(Data, ref Offset); var Sps = GetN(Data, SpsSize, ref Offset); Header.SPSs.Add(Sps); } var PpsCount = Get8(Data, ref Offset); for (int i = 0; i < PpsCount; i++) { var PpsSize = Get16(Data, ref Offset); var Pps = GetN(Data, PpsSize, ref Offset); Header.PPSs.Add(Pps); } return(Header); }
public static void SplitPacket_Avcc(AvccHeader Header, byte[] Packet, System.Action <byte[]> EnumPacket) { int Offset = 0; while (Offset < Packet.Length) { // read length var Length = GetLength(Packet, Header.NaluLength, ref Offset); var Data = GetN(Packet, Length, ref Offset); EnumPacket(Data); } }
// like ParseAvccHeader but decodes the minimum to get profile & level public static AvccHeader ParseAvccProfile(byte[] Data) { // https://stackoverflow.com/a/24890903/355753 int Offset = 0; /*var Version =*/ Get8(Data, ref Offset); var Profile = Get8(Data, ref Offset); /*var Compatibility =*/ Get8(Data, ref Offset); var Level8 = Get8(Data, ref Offset); var ReservedAndNaluLengthMinusOne = Get8(Data, ref Offset); var ReservedAndSpsCount = Get8(Data, ref Offset); var NaluLengthMinusOne = ReservedAndNaluLengthMinusOne & ((1 << 2) - 1); var SpsCount = ReservedAndSpsCount & ((1 << 5) - 1); var Header = new AvccHeader(Profile, Level8, NaluLengthMinusOne); return(Header); }