internal void OnFrameReceivedEvent(BufferChunk frame) { framesReceived++; // Don't trigger the event if it isn't hooked // Although RtpEvents.FireEvent does this same check, we add it here for efficiency // As audio / video streams create alot of data, but don't use the FrameReceived event if (FrameReceived != null) { if (framesReceived == 1) { OnFirstFrameReceivedEvent(); } object[] args = { this, new FrameReceivedEventArgs(this, frame) }; EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(RaiseFrameReceivedEvent), args); } else // Audio and Video { if (frameReceived) { if (framesReceived == 1) { firstFrame = frame.Peek(frame.Index, frame.Length); OnFirstFrameReceivedEvent(); } lastFrame = frame; frameReceived = false; nextFrameEvent.Set(); } } }
/// <summary> /// Read a video frame from the buffer. /// </summary> public bool Read(out BufferChunk Frame, out ulong Time) { Time = 0; Frame = null; lock (this) { if (FramesReady == 0) { return(false); } if ((Buffer == null) || (PresTime == null) || (FrameSize == 0) || (FrameCount == 0)) { return(false); } //Debug.WriteLine("VideoBuffer.Read: ReadOffset=" +ReadOffset.ToString()); Frame = Buffer.Peek((int)(ReadOffset * FrameSize), (int)FrameSize); Time = PresTime[ReadOffset]; lastReadTime = Time + timeZero; ReadOffset++; if (ReadOffset == FrameCount) { ReadOffset = 0; } FramesReady--; return(true); } }
/// <summary> /// Give the caller a reference to the next audio sample. /// </summary> public bool Read(out BufferChunk Sample, out ulong Time) { Time = 0; Sample = null; lock (this) { if (SamplesReady == 0) { return(false); } if ((Buffer == null) || (PresTime == null) || (SampleSize == 0) || (SampleCount == 0)) { return(false); } Sample = Buffer.Peek((int)(ReadOffset * SampleSize), (int)SampleSize); Time = PresTime[ReadOffset]; ReadOffset++; if (ReadOffset == SampleCount) { ReadOffset = 0; } SamplesReady--; //Debug.WriteLine("AudioBuffer:Read for " + cname + ". Remaining samples ready=" + SamplesReady.ToString()); return(true); } }
public BufferChunk FirstFrame() { ValidateUsingNextFrame(); return(firstFrame.Peek(firstFrame.Index, firstFrame.Length)); }
public void WriteToBuffer(BufferChunk buffer) { // Grab space for the header buffer += RtcpHeader.PlaceHolder; BufferChunk hBuffer = buffer.Peek(buffer.Length - RtcpHeader.SIZE, RtcpHeader.SIZE); // Write the data to the buffer WriteDataToBuffer(buffer); // Leave the buffer 32 bit aligned int padding = AddPadding(buffer); // Update the Header's length Debug.Assert((Size) % 4 == 0); header.Length = (short)((Size - RtcpHeader.SIZE) / 4); // Write the header to the buffer header.WriteDataToBuffer(hBuffer); }
internal void OnFrameReceivedEvent(BufferChunk frame) { framesReceived++; // Don't trigger the event if it isn't hooked // Although RtpEvents.FireEvent does this same check, we add it here for efficiency // As audio / video streams create alot of data, but don't use the FrameReceived event if(FrameReceived != null) { if(framesReceived == 1) { OnFirstFrameReceivedEvent(); } object[] args = {this, new FrameReceivedEventArgs(this, frame)}; EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(RaiseFrameReceivedEvent), args); } else // Audio and Video { if(frameReceived) { if(framesReceived == 1) { firstFrame = frame.Peek(frame.Index, frame.Length); OnFirstFrameReceivedEvent(); } lastFrame = frame; frameReceived = false; nextFrameEvent.Set(); } } }