Exemple #1
0
        /// <summary>
        /// setup the initial buffers and write the basic stream data to the db
        /// </summary>
        /// <param name="participant">for this participant</param>
        /// <param name="stream">using this rtp stream</param>
        public StreamRecorder(int participantID, RtpStream stream, ConferenceRecorderPC conferencePerfCounter)
        {
            this.rtpStream   = stream;
            this.perfCounter = conferencePerfCounter;
            this.partID      = participantID;

            // We do *not* re-use existing streams if a stream goes away and comes back.  This decision was made
            //  becuase it causes the client not to see the Rtcp data die & come back during playback, though it
            //  did during recording.  This inconsistency was viewed to cause problems, and was removed.
            InitStream();

            buffers     = new BufferRecorder[Constants.MaxBuffers];
            bufferCount = Constants.InitialBuffers;

            for (int i = 0; i < bufferCount; i++)
            {
                buffers[i]             = new BufferRecorder(i, streamID);
                buffers[i].Overflowed += new EventHandler(this.OnOverflowException);

                perfCounter.AddInstanceForCollection(buffers[i]);
            }

            curBufIndex   = 0;
            currentBuffer = buffers[curBufIndex];

            rtpStream.FrameReceived += new MSR.LST.Net.Rtp.RtpStream.FrameReceivedEventHandler(FrameReceived);
        }
        /// <summary>
        /// setup the initial buffers and write the basic stream data to the db
        /// </summary>
        /// <param name="participant">for this participant</param>
        /// <param name="stream">using this rtp stream</param>
        public StreamRecorder( int participantID, RtpStream stream, ConferenceRecorderPC conferencePerfCounter )
        {
            this.rtpStream = stream;
            this.perfCounter = conferencePerfCounter;
            this.partID = participantID;

            // We do *not* re-use existing streams if a stream goes away and comes back.  This decision was made
            //  becuase it causes the client not to see the Rtcp data die & come back during playback, though it
            //  did during recording.  This inconsistency was viewed to cause problems, and was removed.
            InitStream();

            buffers = new BufferRecorder[Constants.MaxBuffers];
            bufferCount = Constants.InitialBuffers;

            for ( int i = 0; i < bufferCount; i++)
            {
                buffers[i] = new BufferRecorder( i, streamID );
                buffers[i].Overflowed += new EventHandler(this.OnOverflowException);

                perfCounter.AddInstanceForCollection(buffers[i]);
            }

            curBufIndex = 0;
            currentBuffer = buffers[curBufIndex];

            rtpStream.FrameReceived += new MSR.LST.Net.Rtp.RtpStream.FrameReceivedEventHandler(FrameReceived);
        }
        //
        // If data is collected from ConferenceRecorder, or some other class,
        // add an overloaded AddInstanceForCollection method here.
        //
        // Note: You could, if you wanted, make AddInstanceForCollection accept an object,
        // but that would be less performant (and this is a *Performance*Counter... :)
        //

        /// <summary>
        /// Remove an instance from the set of classes on which data is collected.
        /// </summary>
        internal void RemoveInstanceForCollection(BufferRecorder bm)
        {
            lock (buffers)
            {
                if (buffers.Contains(bm))
                {
                    buffers.Remove(bm);
                }
            }
        }
 /// <summary>
 /// Accepts an instance of a class on which data is collected for this performance counter category.
 /// </summary>
 internal void AddInstanceForCollection(BufferRecorder bm)
 {
     lock (buffers)
     {
         if (!buffers.Contains(bm))
         {
             buffers.Add(bm);
         }
     }
 }
Exemple #5
0
        private bool IncrementBuffer()
        {
            // increment the buffer we use....
            int bufIndex = (curBufIndex + 1) % bufferCount;

            while (bufIndex != curBufIndex)
            {
                if (buffers[bufIndex].Available == true)
                {
                    curBufIndex   = bufIndex;
                    currentBuffer = buffers[curBufIndex];
                    return(true);
                }

                bufIndex = (bufIndex + 1) % bufferCount;
            }

            // no buffers available so grow...
            if (bufferCount < buffers.Length)
            {
                eventLog.WriteEntry("Growing buffers for stream " + streamID + " to " + (bufferCount + 1), EventLogEntryType.Warning,
                                    ArchiveServiceEventLog.ID.GrowingBuffers);

                bufIndex = bufferCount;
                bufferCount++;
                buffers[bufIndex]             = new BufferRecorder(bufIndex, streamID);
                buffers[bufIndex].Overflowed += new EventHandler(this.OnOverflowException);
                perfCounter.AddInstanceForCollection(buffers[bufIndex]);

                curBufIndex   = bufIndex;
                currentBuffer = buffers[curBufIndex];
                return(true);
            }
            else
            {
                // Uut of buffers logged in return.  Also, we return w/o having changed which buffer is the current
                //  one b/c we expect the next buffer to be the first one to become available.
                return(false);
            }
        }
Exemple #6
0
        public void StopListening()
        {
            if (rtpStream != null)
            {
                rtpStream.FrameReceived -= new RtpStream.FrameReceivedEventHandler(FrameReceived);
                this.rtpStream           = null;
            }

            int curIndex = curBufIndex;

            if (buffers != null)
            {
                do
                {
                    BufferRecorder buf = buffers[curBufIndex];
                    perfCounter.RemoveInstanceForCollection(buf);
                    buf.Dispose();

                    curBufIndex = (curBufIndex + 1) % bufferCount;
                }while (curBufIndex != curIndex);

                this.buffers = null;
            }
        }
Exemple #7
0
        private void ProcessFrame(object argument)
        {
            lock (this)
            {
                FrameWithTicks frame = (FrameWithTicks)argument;

                this.receivedBytes = this.receivedBytes + (long)frame.frame.Length;
                ++receivedFrames;

                // Verify the frame fits in a buffer.  If not, write it to the database directly.
                if (frame.frame.Length < Constants.BufferSize)
                {
                    // if there is no room in the current buffer
                    if (!currentBuffer.HasRoom(frame.frame.Length))
                    {
                        // With bufferAvailable we try to prevent writing the dropped frame event to the EventLog too often
                        //  Incidentally, that means we'll be writing once per every time we use up the buffer pool.  If we
                        //  have a sudden flood of data, that means it'll only get written once or twice, which helps perf.
                        bool bufferAvailable = false;

                        if (currentBuffer.Available)
                        {
                            currentBuffer.EnableWrite();
                            ++writtenBuffers;
                            bufferAvailable = true;
                        }

                        if (!IncrementBuffer())
                        {
                            // Discard the packet by doing nothing with it

                            if (bufferAvailable)
                            {
                                // Warn the user
                                eventLog.WriteEntry("Dropping a frame in StreamRecorder::OnFrameReceived due to no buffers being available.",
                                                    EventLogEntryType.Error, ArchiveServiceEventLog.ID.FrameDropped);
                            }

                            ++droppedFrames;
                            return;
                        }
                    }

                    currentBuffer.AddFrame(frame);
                }
                else
                {
                    Trace.WriteLine("Writing frame directly to disk.  Frame size: " + frame.frame.Length);

                    // Force pending data to be written to disk
                    if (currentBuffer.Available)
                    {
                        currentBuffer.EnableWrite();
                        ++writtenBuffers;
                    }

                    // Get our new buffer
                    IncrementBuffer();

                    // And write this frame directly to disk
                    BufferRecorder.DirectWrite(frame, this.streamID);
                }

                ++writtenFrames;
            }
        }
        //
        // If data is collected from ConferenceRecorder, or some other class,
        // add an overloaded AddInstanceForCollection method here.
        //
        // Note: You could, if you wanted, make AddInstanceForCollection accept an object,
        // but that would be less performant (and this is a *Performance*Counter... :)
        //

        /// <summary>
        /// Remove an instance from the set of classes on which data is collected.
        /// </summary>
        internal void RemoveInstanceForCollection(BufferRecorder bm)
        {
            lock(buffers)
            {
                if( buffers.Contains(bm) )
                    buffers.Remove(bm);
            }
        }
 /// <summary>
 /// Accepts an instance of a class on which data is collected for this performance counter category.
 /// </summary>
 internal void AddInstanceForCollection(BufferRecorder bm)
 {
     lock(buffers)
     {
         if( !buffers.Contains(bm) )
             buffers.Add(bm);
     }
 }
        private bool IncrementBuffer()
        {
            // increment the buffer we use....
            int bufIndex = (curBufIndex+1) % bufferCount;

            while (bufIndex != curBufIndex)
            {
                if (buffers[bufIndex].Available == true) 
                {
                    curBufIndex = bufIndex;
                    currentBuffer = buffers[curBufIndex];
                    return true;
                }

                bufIndex = ( bufIndex+1 ) % bufferCount;
            }

            // no buffers available so grow...
            if (bufferCount < buffers.Length)
            {
                eventLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, Strings.GrowingBuffers, streamID, 
                    (bufferCount + 1)), EventLogEntryType.Warning, ArchiveServiceEventLog.ID.GrowingBuffers );

                bufIndex = bufferCount;
                bufferCount++;
                buffers[bufIndex] = new BufferRecorder (bufIndex, streamID);
                buffers[bufIndex].Overflowed += new EventHandler(this.OnOverflowException);
                perfCounter.AddInstanceForCollection( buffers[bufIndex] );

                curBufIndex = bufIndex;
                currentBuffer = buffers[curBufIndex];
                return true;
            }
            else
            {
                // Uut of buffers logged in return.  Also, we return w/o having changed which buffer is the current
                //  one b/c we expect the next buffer to be the first one to become available.
                return false;
            }
        }