public override IEnumerator <IReportBlock> GetEnumerator() { //CheckDisposed(); //The first entry is in the header using (ReportBlock rb = new ReportBlock(Header.GetSendersSynchronizationSourceIdentifierSegment())) { yield return(rb); }//size becomes -.... add shouldDispose = false.... //If there are no more entries then we can return if (Header.BlockCount == 1) { yield break; } //The next entries are in the payload. using (RFC3550.SourceList sl = GetSourceList()) { foreach (uint ssrc in sl) { //Give a ReportBlock of 4 bytes to represent the source list entry using (ReportBlock rb = new ReportBlock(new Common.MemorySegment(Payload.Array, Payload.Offset + sl.ItemIndex * RFC3550.SourceList.ItemSize, RFC3550.SourceList.ItemSize))) { yield return(rb); } } } }
/// <summary> /// Constructs a new GoodbyeReport from the given values. /// </summary> /// <param name="version">The version of the report</param> /// <param name="padding"></param> /// <param name="ssrc">The id of the senders of the report</param> /// <param name="sourcesLeaving">The SourceList which describes the sources who are leaving</param> /// <param name="reasonForLeaving">An optional reason for leaving(only the first 255 octets will be used)</param> internal GoodbyeReport(int version, int padding, int ssrc, RFC3550.SourceList sourcesLeaving, byte[] reasonForLeaving) : this(version, padding, ssrc, sourcesLeaving.Count + 1, //BlockCount, + 1 because the ssrc is present. 0, // 0 is extensionSize which is assigned by the size of reasonForLeaving in the constructor via ref. sourcesLeaving.Count *RFC3550.SourceList.ItemSize, //bytesInSourceList reasonForLeaving) { sourcesLeaving.TryCopyTo(m_OwnedOctets, Payload.Offset); }
public override IEnumerator <IReportBlock> GetEnumerator() { using (RFC3550.SourceList sl = GetSourceList()) { foreach (uint ssrc in GetSourceList()) { using (ReportBlock rb = new ReportBlock((int)ssrc)) { yield return(rb); } } } }
internal virtual protected void Add(RFC3550.SourceList sourceList, int offset, int count) { if (sourceList == null) { return; } if (IsReadOnly) { throw new InvalidOperationException("A SourceDescription Chunk cannot be added when IsReadOnly is true."); } int reportBlocksRemaining = ReportBlocksRemaining; if (reportBlocksRemaining == 0) { throw new InvalidOperationException("A RtcpReport can only hold 31 ReportBlocks"); } //Add the bytes to the payload and set the LengthInWordsMinusOne and increase the BlockCount AddBytesToPayload(sourceList.AsBinaryEnumerable(offset, BlockCount += Binary.Min(reportBlocksRemaining, count))); }
/// <summary> /// Adds the maximum amount of items from the source list as there are availabe blocks /// </summary> /// <param name="sourceList"></param> /// <param name="offset"></param> /// <param name="count"></param> internal virtual protected void Add(RFC3550.SourceList sourceList, int offset, int count) { if (sourceList == null) { return; } if (IsReadOnly) { throw new InvalidOperationException("A RFC3550.SourceList cannot be added when IsReadOnly is true."); } int reportBlocksRemaining = ReportBlocksRemaining; if (reportBlocksRemaining == 0) { throw new InvalidOperationException("A RtcpReport can only hold 31 ReportBlocks"); } //Add the bytes to the payload and set the LengthInWordsMinusOne and increase the BlockCount //This is not valid when there is a ReasonForLeaving, the data needs to be placed before such reason and padding AddBytesToPayload(sourceList.GetBinaryEnumerable(offset, BlockCount += Binary.Min(reportBlocksRemaining, count))); }
public virtual void Add(RFC3550.SourceList sourceList) { Add(sourceList, 0, sourceList.Count); }
public GoodbyeReport(int version, int ssrc, RFC3550.SourceList sourcesLeaving, byte[] reasonForLeaving) : this(version, 0, ssrc, sourcesLeaving == null ? RFC3550.SourceList.Empty : sourcesLeaving, reasonForLeaving) { }
/// <summary> /// Provides the logic for cloning a RtpPacket instance. /// The RtpPacket class does not have a Copy Constructor because of the variations in which a RtpPacket can be cloned. /// </summary> /// <param name="includeSourceList">Indicates if the SourceList should be copied.</param> /// <param name="includeExtension">Indicates if the Extension should be copied.</param> /// <param name="includePadding">Indicates if the Padding should be copied.</param> /// <param name="selfReference">Indicates if the new instance should reference the data contained in this instance.</param> /// <returns>The RtpPacket cloned as result of calling this function</returns> public RtpPacket Clone(bool includeSourceList, bool includeExtension, bool includePadding, bool includePayloadData, bool selfReference, bool shouldDispose = true) { //If the sourcelist and extensions are to be included and selfReference is true then return the new instance using the a reference to the data already contained. if (includeSourceList && includeExtension && includePadding && includePayloadData) { return selfReference ? new RtpPacket(Header, Payload, shouldDispose) { Transferred = Transferred } } : new RtpPacket(Prepare().ToArray(), 0, Length, shouldDispose) { Transferred = Transferred }; IEnumerable <byte> binarySequence = MemorySegment.EmptyBytes; bool hasSourceList = ContributingSourceCount > 0; //If the source list is included then include it. if (includeSourceList && hasSourceList) { RFC3550.SourceList sourceList = GetSourceList(); if (false.Equals(IDisposedExtensions.IsNullOrDisposed(sourceList))) { binarySequence = sourceList.GetBinaryEnumerable(); } else { binarySequence = MemorySegment.EmptyBytes; } } //Determine if the clone should have extenison bool hasExtension = Header.Extension; //If there is a header extension to be included in the clone if (hasExtension && includeExtension) { //Get the Extension using (RtpExtension extension = GetExtension()) { //If an extension could be obtained include it if (false.Equals(IDisposedExtensions.IsNullOrDisposed(extension))) { binarySequence = binarySequence.Concat(extension); } } } //if the video data is required in the clone then include it if (includePayloadData) { binarySequence = binarySequence.Concat(PayloadData); //Add the binary data to the packet except any padding } //Determine if padding is present bool hasPadding = Header.Padding; //if padding is to be included in the clone then obtain the original padding directly from the packet if (hasPadding && includePadding) { binarySequence = binarySequence.Concat(Payload.Array.Skip(Payload.Offset + Payload.Count - PaddingOctets)); //If just the padding is required the skip the Coefficients } //Return the result of creating the new instance with the given binary return(new RtpPacket(new RtpHeader(Header.Version, includePadding && hasPadding, includeExtension && hasExtension) { Timestamp = Header.Timestamp, SequenceNumber = Header.SequenceNumber, SynchronizationSourceIdentifier = Header.SynchronizationSourceIdentifier, PayloadType = Header.PayloadType, ContributingSourceCount = includeSourceList ? Header.ContributingSourceCount : 0 }.Concat(binarySequence).ToArray(), 0, shouldDispose) { Transferred = Transferred }); }