public static SliceType GetSliceTypeFromH264Payload(byte[] payload) { int countToZero = payload.Length; BinaryReader reader = new BinaryReader(new MemoryStream(payload)); while (countToZero > 4) { ulong naluLen = BitReader.GetUIntValue(reader.ReadUInt32()); long nextPos = reader.BaseStream.Position + (long)naluLen; //Table 7-1 – NAL unit type codes //nal_unit_type Content of NAL unit and RBSP syntax structure C //0 Unspecified //1 Coded slice of a non-IDR picture // slice_layer_without_partitioning_rbsp( ) //2 Coded slice data partition A // slice_data_partition_a_layer_rbsp( ) //3 Coded slice data partition B // slice_data_partition_b_layer_rbsp( ) //4 Coded slice data partition C // slice_data_partition_c_layer_rbsp( ) //5 Coded slice of an IDR picture // slice_layer_without_partitioning_rbsp( ) //6 Supplemental enhancement information (SEI) // sei_rbsp( ) //7 Sequence parameter set // seq_parameter_set_rbsp( ) //8 Picture parameter set // pic_parameter_set_rbsp( ) //9 Access unit delimiter // access_unit_delimiter_rbsp( ) //10 End of sequence // end_of_seq_rbsp( ) //11 End of stream // end_of_stream_rbsp( ) //12 Filler data // filler_data_rbsp( ) //13..23 Reserved //24..31 Unspecified uint typ = reader.ReadByte() & 0x1Fu; if ((naluLen > (ulong)countToZero) || (naluLen < 2)) { return(SliceType.Unknown); } // NALU type 5 is IDR picture if ((typ == 5u) || (typ == 1u)) { // when the type == 5 its an IDR picture, now slice_type shall be equal to // 2, 4, 7, or 9 (I or SI); // slice_type specified the coding type of the slice according to Table 7-6: e.g. P, B, I, SP, SI // // nalu header: // first_mb_in_slice = get_ue_golomb // slice_type = get_ue_golomb // // http://www.iitk.ac.in/mwn/vaibhav/Vaibhav%20Sharma_files/h.264_standard_document.pdf //Table 7-3 – Name association to slice_type //0 P (P slice) //1 B (B slice) //2 I (I slice) //3 SP (SP slice) //4 SI (SI slice) //5 P (P slice) //6 B (B slice) //7 I (I slice) //8 SP (SP slice) //9 SI (SI slice) BitReader br = new BitReader(reader.BaseStream); uint first_mb_in_slice = br.DecodeUnsignedExpGolomb(); uint slice_type = br.DecodeUnsignedExpGolomb(); uint pic_parameter_set_id = br.DecodeUnsignedExpGolomb(); uint frame_num = br.DecodeUnsignedExpGolomb(); if (typ == 5u) { return(SliceType.IFrame); } if (slice_type == 1 || slice_type == 6) { return(SliceType.BFrame); } return(SliceType.DFrame); } countToZero -= ((int)naluLen + 4); reader.BaseStream.Position = nextPos; } return(SliceType.Unknown); }