Exemplo n.º 1
0
        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);
        }