public MacroBlockLayer(SequenceParameterSet sps, PictureParameterSet pps, SliceHeader header, SliceData data) { _sliceType = header.SliceType; _sps = sps; _pps = pps; _header = header; _data = data; _mbTypeParser = _data.MBTypeParser; _cbp = _data.CBP; _mbQPD = _data.MBQPD; }
public SliceData(SequenceParameterSet sps, PictureParameterSet pps, SliceHeader header) { _sps = sps; _pps = pps; _header = header; if (_pps.EntropyCodingModeFlag) { MBTypeParser = new MBTypeCABACParser(_pps, header); CBP = new CodedBlockPattern(_pps, _header); MBQPD = new MBQPDelta(_pps, _header); } }
public CodedSlicePartitionBorC(SequenceParameterSet sps, PictureParameterSet pps, byte idc, NALUnitType naluType, uint size) : base(sps, pps, (byte)0, NALUnitType.SlicePartitionA, size) { _pps = pps; }
public CodedSlicePartitionA(SequenceParameterSet sps, PictureParameterSet pps, byte idc, uint size) : base(sps, pps, idc, NALUnitType.SlicePartitionA, size) { }
public CodedSliceWithoutPartition(SequenceParameterSet sps, PictureParameterSet pps, Byte idc, NALUnitType naluType, uint size) : base(sps, pps, idc, naluType, size) { }
public CodedSliceIDR(SequenceParameterSet sps, PictureParameterSet pps, uint size) : base(sps, pps, (byte)1, NALUnitType.IDRSlice, size) { }
public CodedSliceNonIDR(SequenceParameterSet sps, PictureParameterSet pps, byte idc, uint size) : base(sps, pps, idc, NALUnitType.NonIDRSlice, size) { }
public SupplementatlEnhancementMessage(SequenceParameterSet sps, uint size) : this(size) { _sps = sps; }
public H264Sample(SequenceParameterSet sps, PictureParameterSet pps, int size) { _sps = sps; _pps = pps; _totalSize = size; }
/// <summary> /// GetVideoParamsFromH264SPS /// This private method sets v, the video meta sample. /// It returns the total size of delimiter, sps, and pps NALUs. /// </summary> /// <param name="br"></param> /// <param name="sampleSize"></param> /// <param name="VSetAlready">if V is already set, remove sps and pps and move access unit delimiter</param> int GetVideoParamsFromH264SPS(BinaryReader br, int sampleSize, bool VSetAlready, out int countToZero) { int totalSize = 0; countToZero = sampleSize; if (sampleSize < 60) throw new Exception("Payload too small"); mPayload = br.ReadBytes(sampleSize); BinaryReader reader = new BinaryReader(new MemoryStream(mPayload)); while (countToZero > 4) { ulong naluLen = BE32(reader.ReadUInt32()); long nextPos = reader.BaseStream.Position + (long)naluLen; uint typ = reader.ReadByte(); if ((naluLen > (ulong)countToZero) || (naluLen < 2)) throw new Exception("Invalid QBox video payload"); // access unit delimiter (aud) always comes first and its size is not added to total size because // it is be added back to the payload (see QBoxVideoTrack). if ((typ & 0x1Fu) == 9u) { if (v != null) throw new Exception("QBoxSample: QBoxMetaV object already exists, and a second one cannot be constructed"); v = new QBoxMetaV(); if (naluLen != 2) throw new Exception("Wrong nalu delimiter length"); if (VSetAlready) { v.aud = new byte[naluLen]; v.aud[0] = (byte)typ; v.aud[1] = reader.ReadByte(); } else if (v.aud != null) throw new Exception("QBox.QBoxSample.GetVideoParamsFromH264SPS: v.aud should be null"); } // if nalu type is Sequence Param Set, pick up width and height // also, build private codec data from this SPS // NOTE: it matters which video track this qbox belongs! if ((typ & 0x1Fu) == 7u) { v.sps = new byte[naluLen]; v.sps[0] = (byte)typ; reader.Read(v.sps, 1, (int)naluLen - 1); totalSize += (int)(4 + naluLen); // parse the SPS bit stream, just to get the correct width and height of video. BitReader bitReader = new BitReader(new MemoryStream(v.sps)); SequenceParameterSet sps = new SequenceParameterSet((uint)naluLen); sps.Read(bitReader); v.width = (ulong)sps.Width; v.height = (ulong)sps.Height; } else if ((typ & 0x1Fu) == 8u) { v.pps = new byte[naluLen]; v.pps[0] = (byte)typ; reader.Read(v.pps, 1, (int)naluLen - 1); totalSize += (int)(4 + naluLen); } countToZero -= ((int)naluLen + 4); reader.BaseStream.Position = nextPos; } return totalSize; }
public CodedSliceBase(SequenceParameterSet sps, PictureParameterSet pps, Byte idc, NALUnitType naluType, uint size) { Nalu = new NetworkAbstractionLayerUnit(idc, naluType, size); Header = new SliceHeader(sps, pps, Nalu); Data = new SliceData(sps, pps, Header, Nalu); }
public SliceHeader(SequenceParameterSet sps, PictureParameterSet pps, NetworkAbstractionLayerUnit nalu) { _nalu = nalu; _sps = sps; _pps = pps; }
public SliceData(SequenceParameterSet sps, PictureParameterSet pps, SliceHeader header, NetworkAbstractionLayerUnit nalu) : this(sps, pps, header) { _nalu = nalu; }
void ParseThreadProc(object buffer) { byte[] sliceBytes = buffer as byte[]; BitReader br = new BitReader(new MemoryStream(sliceBytes)); int totalSize = _totalSize; int offset = 0; int state = 0; while (totalSize > 4) { int naluLen = (int)br.GetUIntFromNBits(32); if (naluLen > totalSize) { throw new Exception("H264 parsing: wrong byte count encountered"); } if (naluLen > 0) { byte b = br.PeekByte(); byte refIDC = (byte)(b >> 5); NALUnitType naluType = (NALUnitType)(b & 0x1F); switch (state) { case 0: AccessUnitDelimiter aud = new AccessUnitDelimiter((uint)naluLen); aud.Read(br); state = 1; break; case 1: // either SEI or SPS (if it's an SEI, don't change state) if (naluType == NALUnitType.SupplementalEnhancementInfo) { SupplementatlEnhancementMessage sei = new SupplementatlEnhancementMessage(_sps, (uint)naluLen); sei.Read(br); } else if (naluType == NALUnitType.SequenceParamSet) { // replace _sps _sps = new SequenceParameterSet((uint)naluLen); _sps.Read(br); } else if (naluType == NALUnitType.PictureParamSet) { // replace _pps _pps = new PictureParameterSet((uint)naluLen); _pps.Read(br); } else if (naluType == NALUnitType.IDRSlice) { CodedSliceIDR idr = new CodedSliceIDR(_sps, _pps, (uint)naluLen); idr.Read(br); SliceType = idr.Header.SliceType; FrameNum = idr.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if (naluType == NALUnitType.NonIDRSlice) { CodedSliceNonIDR nonIdr = new CodedSliceNonIDR(_sps, _pps, GetIDC(refIDC), (uint)naluLen); nonIdr.Read(br); SliceType = nonIdr.Header.SliceType; FrameNum = nonIdr.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if (naluType == NALUnitType.SlicePartitionA) { CodedSlicePartitionA partA = new CodedSlicePartitionA(_sps, _pps, GetIDC(refIDC), (uint)naluLen); partA.Read(br); SliceType = partA.Header.SliceType; FrameNum = partA.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if ((naluType == NALUnitType.SlicePartitionB) || (naluType == NALUnitType.SlicePartitionC)) { CodedSlicePartitionBorC partBC = new CodedSlicePartitionBorC(_sps, _pps, GetIDC(refIDC), naluType, (uint)naluLen); partBC.Read(br); // FIXME: check that SliceType and FrameNum are set at this point state = 2; // next should be zero or more redundant coded pictures } break; case 2: // either coded picture or end of sequence break; default: break; } offset += naluLen; totalSize -= (naluLen + 4); } else { naluLen = 0; // debugging break point } } if (SampleDoneEvent != null) { SampleDoneEvent(this); } }
/// <summary> /// Look into a slice just to get width, height, and aspect ratio. /// NOTE: This is no longer used. /// </summary> private void GetScreenDimensions(IVideoTrack video) { if ((video.PayloadType == VideoPayloadType.unknown) || (video.PayloadType == VideoPayloadType.jpeg) || (video.PayloadType == VideoPayloadType.mjpeg)) return; // this will only work for H.264 video source IMediaTrackSliceEnumerator slices = (IMediaTrackSliceEnumerator)video.GetEnumerator(); slices.MoveNext(); Slice slice = slices.Current; ; int countToZero = slice.SliceSize; ulong totalSize = 0UL; BinaryReader reader = new BinaryReader(new MemoryStream(slice.SliceBytes)); while (countToZero > 4) { ulong naluLen = BE32(reader.ReadUInt32()); long nextPos = reader.BaseStream.Position + (long)naluLen; uint typ = reader.ReadByte(); if ((naluLen > (ulong)countToZero) || (naluLen < 2)) throw new Exception("Invalid video payload"); // access unit delimiter (aud) always comes first and its size is not added to total size because // it is be added back to the payload. if ((typ & 0x1Fu) == 9u) { if (naluLen != 2) throw new Exception("Wrong nalu delimiter length"); reader.ReadByte(); // discard (we don't need it here) } // if nalu type is Sequence Param Set, pick up width and height // also, build private codec data from this SPS // NOTE: it matters which video track this qbox belongs! if ((typ & 0x1Fu) == 7u) { byte[] buf = new byte[naluLen]; reader.Read(buf, 1, (int)naluLen - 1); totalSize += (4 + naluLen); // parse the SPS bit stream, just to get the correct width and height of video. BitReader bitReader = new BitReader(new MemoryStream(buf)); SequenceParameterSet sps = new SequenceParameterSet((uint)naluLen); sps.Read(bitReader); Width = (int)sps.Width; Height = (int)sps.Height; if (sps.VUIParametersPresent) { AspectRatioX = sps.vuiParams.AspectRatioX; AspectRatioY = sps.vuiParams.AspectRatioY; } } countToZero -= ((int)naluLen + 4); reader.BaseStream.Position = nextPos; } }
private SequenceParameterSet ParseSPS(byte[] data) { SequenceParameterSet sps = new SequenceParameterSet((uint)data.Length); H264.BitReader reader = new H264.BitReader(new MemoryStream(data)); sps.Read(reader); reader.Close(); return sps; }