Пример #1
0
 public EltH264Nalu(CommonH264Nalu nalu)
     : base(nalu)
 {
     m_eNaluType = nalu.getNaluType();
     m_LayerId = nalu.getLayerId();
     m_PictureId = nalu.getPictureId();
     m_SliceId = nalu.getSliceId();
 }
Пример #2
0
 public EltH264Nalu(CommonH264Nalu nalu)
     : base(nalu)
 {
     m_eNaluType = nalu.getNaluType();
     m_LayerId   = nalu.getLayerId();
     m_PictureId = nalu.getPictureId();
     m_SliceId   = nalu.getSliceId();
 }
Пример #3
0
        public static NalUnitTypeDescriptor GetNalUnitType(NalUnitType nalUnitType)
        {
            var type = (int)nalUnitType;

            if (type < Types.Length)
                return Types[type];

            return null;
        }
Пример #4
0
        public static NalUnitTypeDescriptor GetNalUnitType(NalUnitType nalUnitType)
        {
            int index = (int)nalUnitType;

            if (index < NalUnitTypes.Types.Length)
            {
                return(NalUnitTypes.Types[index]);
            }
            return((NalUnitTypeDescriptor)null);
        }
        /// <summary>
        /// Processes the given NAL Unit bytes.
        /// </summary>
        /// <param name="nalUnitBytes"></param>
        /// <returns>A potentially modified set of bytes for the NAL Unit.</returns>
        public byte[] ProcessNalUnit(byte[] nalUnitBytes)
        {
            NalUnitType nalUnitType = DetermineNalUnitType(nalUnitBytes);

            if (nalUnitType == NalUnitType.NAL_SPS)
            {
                nalUnitBytes = ProcessSequenceParameterSetNalUnit(nalUnitBytes);
            }

            return(nalUnitBytes);
        }
        public void ParseHeader(IReaderState readerState)
        {
            bool firstHeader             = (_state.NalUnitType == NalUnitType.Invalid);
            uint maxGapAfterNalUnit      = GetMaxGapAfterNalUnit(_state.NalUnitType);
            long startPosition           = _reader.Position;
            long maxNalUnitStartPosition = Math.Min(_reader.Length, (startPosition + maxGapAfterNalUnit));

            NalUnitType previousNalUnitType = _state.NalUnitType;

            while (_dataReader.State == DataReaderState.Ready)
            {
                if (!firstHeader)
                {
                    while (true)
                    {
                        if ((FindNalUnit(false) == null) || (_reader.Position >= maxNalUnitStartPosition) || (_dataReader.State != DataReaderState.Ready))
                        {
                            _reader.Position = startPosition;
                            readerState.Invalidate();
                            return;
                        }

                        var nextNalUnitType = (NalUnitType)(GetNalUnitByte() & 0x1f);
                        if ((_reader.Position - startPosition) <= GetMaxGapBetweenNalUnits(previousNalUnitType, nextNalUnitType))
                        {
                            break;
                        }

                        _reader.Position++;
                    }
                }

                long nalUnitStartPosition = _reader.Position;
                readerState.Parse(_streamParser, _reader);

                if (readerState.Valid)
                {
                    return;                     // Result is valid
                }
                if (firstHeader || (nalUnitStartPosition >= (maxNalUnitStartPosition - 1)))
                {
                    return;                     // Done scanning for a valid result
                }

                readerState.Recover();
                _reader.Position = (nalUnitStartPosition + 1);
            }

            // Nothing was found, so the result is invalid
            readerState.Invalidate();
        }
Пример #7
0
        private static bool CanParseNalUnitType(ISliceState sliceState, NalUnitType nalUnitType)
        {
            if (!IsSlice(nalUnitType))
            {
                return(true);
            }
            if (sliceState == null)
            {
                return(false);                // Slice with no picture parameter set available
            }

            // FIXME: certain CAVLC and CABAC files do not work, e.g. separate colour plane YCrCb 4:4:4 files

            return(true);            // H.264 slice that can be parsed
        }
        private uint GetMaxGapBetweenNalUnits(NalUnitType previousNalUnitType, NalUnitType nextNalUnitType)
        {
            if (previousNalUnitType == NalUnitType.Invalid)
            {
                return(0U);
            }
            if (previousNalUnitType == NalUnitType.SequenceParameterSet)
            {
                return((nextNalUnitType == NalUnitType.PictureParameterSet) ? _maxGapBetweenPpsAndSps : _maxGapBetweenNalUnits);
            }
            if (previousNalUnitType == NalUnitType.PictureParameterSet)
            {
                return((nextNalUnitType == NalUnitType.CodedSliceOfAnIdrPicture || nextNalUnitType == NalUnitType.CodedSliceOfANonIdrPicture) ? _maxGapBetweenPpsAndSlice : _maxGapBetweenNalUnits);
            }

            return(_maxGapBetweenNalUnits);
        }
        private uint GetMaxGapAfterNalUnit(NalUnitType nalUnitType)
        {
            if (nalUnitType == NalUnitType.Invalid)
            {
                return(0);
            }
            if (nalUnitType == NalUnitType.SequenceParameterSet)
            {
                return(Math.Max(_maxGapBetweenPpsAndSps, _maxGapBetweenNalUnits));
            }
            if (nalUnitType == NalUnitType.PictureParameterSet)
            {
                return(Math.Max(_maxGapBetweenPpsAndSlice, _maxGapBetweenNalUnits));
            }

            return(_maxGapBetweenNalUnits);
        }
Пример #10
0
        private void ParseData()
        {
            byte[] frameData = RawData;
            int    frameSize = frameData.Length;

            // I know how my H.264 data source's NALUs looks like so I know start code index is always 0.
            // if you don't know where it starts, you can use a for loop similar to how I find the 2nd and 3rd start codes
            int startCodeIndex       = 0;
            int secondStartCodeIndex = 0;
            int thirdStartCodeIndex  = 0;

            int _spsSize = 0;
            int _ppsSize = 0;

            long blockLength = 0;

            _isParsed = true;

            NalUnitType type = (NalUnitType)(frameData[startCodeIndex + 4] & 0x1F);

            NalUnitTypes.Add(type);

            // NALU type 7 is the SPS parameter NALU
            if (type == NalUnitType.SEQUENCE_PARAMETER_SET)
            {
                // find where the second PPS start code begins, (the 0x00 00 00 01 code)
                // from which we also get the length of the first SPS code
                for (int i = startCodeIndex + 4; i < startCodeIndex + 40; i++)
                {
                    if (frameData[i] == 0x00 &&
                        frameData[i + 1] == 0x00 &&
                        frameData[i + 2] == 0x00 &&
                        frameData[i + 3] == 0x01)
                    {
                        secondStartCodeIndex = i;
                        _spsSize             = secondStartCodeIndex; // includes the header in the size
                        break;
                    }
                }

                // find what the second NALU type is
                type = (NalUnitType)(frameData[secondStartCodeIndex + 4] & 0x1F);
                NalUnitTypes.Add(type);
            }


            // type 8 is the PPS parameter NALU
            if (type == NalUnitType.PICTURE_PARAMETER_SET)
            {
                // find where the NALU after this one starts so we know how long the PPS parameter is
                for (int i = _spsSize + 8; i < _spsSize + 50; i++)
                {
                    if (frameData[i] == 0x00 &&
                        frameData[i + 1] == 0x00 &&
                        frameData[i + 2] == 0x00 &&
                        frameData[i + 3] == 0x01)
                    {
                        thirdStartCodeIndex = i;
                        _ppsSize            = thirdStartCodeIndex - _spsSize;
                        break;
                    }
                }

                if (_ppsSize < 4 || _spsSize < 4)
                {
                    throw new InvalidDataException("Couldnt determine PPS/SPS size");
                }

                // allocate enough data to fit the SPS and PPS parameters into our data objects.
                // NOTE: buffers won't contain NAL start-code (00 00 00 01)
                _ppsData = new byte[_ppsSize - 4];
                _spsData = new byte[_spsSize - 4];

                // copy in the actual sps and pps values, again ignoring the 4 byte header
                Array.Copy(frameData, 4, _spsData, 0, _spsSize - 4);
                Array.Copy(frameData, _spsSize + 4, _ppsData, 0, _ppsSize - 4);

                // now lets handle the IDR frame that (should) come after the parameter sets
                // I say "should" because that's how I expect my H264 stream to work, YMMV
                type = (NalUnitType)(frameData[thirdStartCodeIndex + 4] & 0x1F);
                NalUnitTypes.Add(type);
            }

            // NALU type 1 is non-IDR (or PFrame) picture
            // NALU type 5 is an IDR frame NALU.  The SPS and PPS NALUs should always be followed by an IDR (or IFrame) NALU, as far as I know
            if (type == NalUnitType.P_FRAME || type == NalUnitType.I_FRAME)
            {
                // P-Frame (1): non-IDR frames do not have an offset due to SPS and PSS
                // I-Frame (5): find the offset, or where the SPS and PPS NALUs end and the IDR frame NALU begins
                int offset = type == NalUnitType.I_FRAME ? _spsSize + _ppsSize : 0;
                blockLength = frameSize - offset;

                // copy in the actual frame data, again ignoring the 4 byte header
                _frameData = new byte[blockLength - 4];
                Array.Copy(frameData, offset + 4, _frameData, 0, blockLength - 4);
            }
        }
Пример #11
0
 private static bool IsSlice(NalUnitType nalUnitType)
 {
     return((nalUnitType == NalUnitType.CodedSliceOfANonIdrPicture) || (nalUnitType == NalUnitType.CodedSliceOfAnIdrPicture));
 }
Пример #12
0
        public NalUnitType getNaluType()
        {
            NalUnitType ret = (NalUnitType)commonWRAPPINVOKE.CommonH264Nalu_getNaluType(swigCPtr);

            return(ret);
        }
 public NalUnitTypeDescriptor(NalUnitType type, string name, string description)
 {
     this._type        = type;
     this._name        = name;
     this._description = description;
 }