/// <summary>
        /// get details of the stream...raw data and start tiume etc
        /// set up the stream senders associated with us. we have n, one active and the rest acting as buffers
        /// </summary>
        public StreamPlayer(RtpSession session, int newStreamID, ConferencePlayerPC cppc)
        {
            int maxFrameSize, maxFrameCount, maxBufferSize;

            // This occasionally throws due to bad data.  Let ConferencePlayer handle it.
            DBHelper.GetStreamStatistics(newStreamID, out this.firstStreamTicks, out maxFrameSize, out maxFrameCount, out maxBufferSize);

            streamID        = newStreamID;
            totalFramesSent = 0;
            totalBytesSent  = 0;
            totalLateness   = 0;
            buffers         = new BufferPlayer[Constants.BuffersPerStream];
            perfCounter     = cppc;

            string payload;

            DBHelper.GetStreamAndParticipantDetails(streamID, out name, out payload, out cname, out privExtns);
            streamPayload = (PayloadType)Enum.Parse(typeof(PayloadType), payload, true);

            // for delayed buffers (late joiners), we create the rtpSender later
            this.rtpSession = session;

            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                          "Playing back stream: {0}; payload: {1}; name: {2} : {3}", streamID, streamPayload, cname, name));

            // buffer n buffers worth of data
            long startingTick = this.firstStreamTicks;

            for (int i = 0; i < buffers.Length; i++)
            {
                buffers[i] = new BufferPlayer(streamID, maxFrameSize, maxFrameCount, maxBufferSize);
                buffers[i].Populate(startingTick);
                startingTick = buffers[i].LastTick + 1;

                perfCounter.AddInstanceForCollection(buffers[i]);
            }

            // first stream is initially active
            activeBufferIndex = 0;
            activeBuffer      = buffers[activeBufferIndex];
        }
Beispiel #2
0
        /// <summary>
        /// get details of the stream...raw data and start tiume etc
        /// set up the stream senders associated with us. we have n, one active and the rest acting as buffers
        /// </summary>
        public StreamPlayer( RtpSession session, int newStreamID, ConferencePlayerPC cppc)
        {
            int maxFrameSize, maxFrameCount, maxBufferSize;

            // This occasionally throws due to bad data.  Let ConferencePlayer handle it.
            DBHelper.GetStreamStatistics( newStreamID, out this.firstStreamTicks, out maxFrameSize, out maxFrameCount, out maxBufferSize);

            streamID = newStreamID;
            totalFramesSent = 0;
            totalBytesSent = 0;
            totalLateness = 0;
            buffers = new BufferPlayer[Constants.BuffersPerStream];
            perfCounter = cppc;

            string payload;
            DBHelper.GetStreamAndParticipantDetails( streamID, out name, out payload, out cname, out privExtns );
            streamPayload = (PayloadType)Enum.Parse( typeof(PayloadType), payload, true );

            // for delayed buffers (late joiners), we create the rtpSender later
            this.rtpSession = session;

            Trace.WriteLine("Playing back stream: "+streamID+"; payload: "+streamPayload+"; name: "+ (cname + " : " +name));

            // buffer n buffers worth of data
            long startingTick = this.firstStreamTicks;
            for ( int i = 0; i < buffers.Length; i++)
            {
                buffers[i] = new BufferPlayer( streamID, maxFrameSize, maxFrameCount, maxBufferSize);
                buffers[i].Populate( startingTick );
                startingTick = buffers[i].LastTick + 1;

                perfCounter.AddInstanceForCollection(buffers[i]);
            }

            // first stream is initially active
            activeBufferIndex = 0;
            activeBuffer = buffers[activeBufferIndex];
        }
        public void Play( IPEndPoint venue, int[] streams, bool receiveData )
        {
            if( this.playing )
                throw new InvalidOperationException("ConferencePlayer::Play called when the player is already playing.");
            if( streams == null )
                throw new ArgumentNullException("streams cannot be null");

            venueIPE = venue;

            // Create an RtpSession
            RtpParticipant me = new RtpParticipant(Constants.PersistenceCName, Constants.PersistenceName + " (Playing)");
            rtpSession = new RtpSession(venue, me, true, receiveData);

            // Hook the static stream-ended event
            StreamPlayer.EndOfStreamReached += new EventHandler(EndOfStreamReached);

            // Create a new perf counter for this ConferencePlayer instance
            this.perfCounter = new ConferencePlayerPC(venue.ToString());

            // Keep track of the streamPlayers
            ArrayList avStreams = new ArrayList();
            ArrayList otherStreams = new ArrayList();

            // Find the first stored ticks of all the streams while creating them...
            this.firstStoredTick = long.MaxValue;

            // Create all of our StreamPlayers (one per stream...)
            for ( int i = 0; i < streams.Length; i++)
            {
                StreamPlayer newStream = null;

                try
                {
                    newStream = new StreamPlayer(rtpSession, streams[i], perfCounter);
                }
                catch( Exception ex )
                {
                    eventLog.WriteEntry(String.Format("Stream with bad data reached.  Continuing playback of all other streams."
                        + "  Stream ID: {0}.  Exception: \n {1}", streams[i], ex.ToString()),
                        EventLogEntryType.Warning, ArchiveServiceEventLog.ID.BadStreamInDB);
                }

                if( newStream != null )
                {
                    perfCounter.AddInstanceForCollection( newStream );

                    if( newStream.FirstStreamsTicks < this.firstStoredTick )
                        this.firstStoredTick = newStream.FirstStreamsTicks;

                    // Add the new StreamPlayer to the right collection
                    // Pri3: Consider other methods here.  Maybe a smarter detection of large frame sizes,
                    //  or initializing the stream so it has enough packets ahead of time?
                    if( newStream.Payload == PayloadType.dynamicAudio || newStream.Payload == PayloadType.dynamicVideo )
                        avStreams.Add(newStream);
                    else // RTDocs stream or other large-payload stream, most likely
                        otherStreams.Add(newStream);
                }
            }

            // Start the StreamsGroupPlayers
            // Pri2: Change this to be compatable with use of the "playback speed" feature.
            long startTime = DateTime.Now.Ticks + 1500*Constants.TicksPerMs; // we'll start in 1.5 seconds (for init time)

            // Create the StreamsGroupPlayer(s)
            avPlayer = new StreamsGroupPlayer(avStreams, this.firstStoredTick, startTime);
            otherPlayer = new StreamsGroupPlayer(otherStreams, this.firstStoredTick, startTime);

            this.playing = true;
        }
        public void Play(IPEndPoint venue, int[] streams, bool receiveData)
        {
            if (this.playing)
            {
                throw new InvalidOperationException(Strings.PlayerAlreadyPlayingError);
            }
            if (streams == null)
            {
                throw new ArgumentNullException(Strings.StreamsCannotBeNull);
            }

            venueIPE = venue;

            // Create an RtpSession
            RtpParticipant me = new RtpParticipant(Constants.PersistenceCName,
                                                   string.Format(CultureInfo.CurrentCulture, Strings.Playing, Constants.PersistenceName));

            rtpSession = new RtpSession(venue, me, true, receiveData);

            // andrew: connect to diagnostic server
            rtpSession.VenueName = "Archived: " + venue.ToString();

            // Hook the static stream-ended event
            StreamPlayer.EndOfStreamReached += new EventHandler(EndOfStreamReached);

            // Create a new perf counter for this ConferencePlayer instance
            this.perfCounter = new ConferencePlayerPC(venue.ToString());

            // Keep track of the streamPlayers
            ArrayList avStreams    = new ArrayList();
            ArrayList otherStreams = new ArrayList();

            // Find the first stored ticks of all the streams while creating them...
            this.firstStoredTick = long.MaxValue;

            // Create all of our StreamPlayers (one per stream...)
            for (int i = 0; i < streams.Length; i++)
            {
                StreamPlayer newStream = null;

                try
                {
                    newStream = new StreamPlayer(rtpSession, streams[i], perfCounter);
                }
                catch (Exception ex)
                {
                    eventLog.WriteEntry(String.Format(CultureInfo.CurrentCulture, Strings.StreamWithBadDataReached,
                                                      streams[i], ex.ToString()), EventLogEntryType.Warning,
                                        ArchiveServiceEventLog.ID.BadStreamInDB);
                }

                if (newStream != null)
                {
                    perfCounter.AddInstanceForCollection(newStream);

                    if (newStream.FirstStreamsTicks < this.firstStoredTick)
                    {
                        this.firstStoredTick = newStream.FirstStreamsTicks;
                    }

                    // Add the new StreamPlayer to the right collection
                    // Pri3: Consider other methods here.  Maybe a smarter detection of large frame sizes,
                    //  or initializing the stream so it has enough packets ahead of time?
                    if (newStream.Payload == PayloadType.dynamicAudio || newStream.Payload == PayloadType.dynamicVideo)
                    {
                        avStreams.Add(newStream);
                    }
                    else // RTDocs stream or other large-payload stream, most likely
                    {
                        otherStreams.Add(newStream);
                    }
                }
            }

            // Start the StreamsGroupPlayers
            // Pri2: Change this to be compatable with use of the "playback speed" feature.
            long startTime = DateTime.Now.Ticks + 1500 * Constants.TicksPerMs; // we'll start in 1.5 seconds (for init time)

            // Create the StreamsGroupPlayer(s)
            avPlayer    = new StreamsGroupPlayer(avStreams, this.firstStoredTick, startTime);
            otherPlayer = new StreamsGroupPlayer(otherStreams, this.firstStoredTick, startTime);

            this.playing = true;
        }