public MediaController(MediaConfig config, AudioFormat playedAudioFormat, MediaStatistics mediaStats, IMediaEnvironment mediaEnvironment, IMediaConnection mediaConnection, IVideoQualityController videoQualityController) { // Initialize the class variables. _mediaEnvironment = mediaEnvironment; MediaConfig = config; MediaStats = mediaStats; MediaConnection = mediaConnection; VideoQualityController = videoQualityController; MediaConnection.AudioPacketHandler = HandleAudioPacket; MediaConnection.VideoPacketHandler = HandleVideoPacket; Logger = new MediaControllerLogger(VideoQualityController, MediaStats); _localSsrcId = config.LocalSsrcId; RemoteSessions = new Dictionary <ushort, VideoThreadData>(); VideoQualityController.RemoteSessions = RemoteSessions; PlayedAudioFormat = playedAudioFormat; _silentBytes = new byte[PlayedAudioFormat.BytesPerFrame]; _decodedFrameBuffer = new short[PlayedAudioFormat.SamplesPerFrame * 10]; // Make room for 10 frames. _codecFactory = config.CodecFactory; _videoEncoder = _codecFactory.GetVideoEncoder(VideoQualityController, MediaStats); // Instantiate the audio jitter class _audioJitter = new AudioJitterQueue(_codecFactory, VideoQualityController, MediaStats); _audioJitter.CodecTypeChanged += audioJitter_CodecTypeChanged; _audioDecodeBuffer = new byte[VideoConstants.MaxPayloadSize]; _audioSendBuffer = new ByteStream(RtpPacketData.DataPacketMaxLength); // Spin up the various audio and video encoding threads. // On multiprocessor machines, these can spread the load, but even on single-processor machines it helps a great deal // if the various audio and video sinks can return immediately. _audioEncodeResetEvent = new ManualResetEvent(false); _audioEncodeThread = new Thread(TransmitAudio); _audioEncodeThread.Name = "MediaController.TransmitAudio"; _audioEncodeThread.Start(); _videoEncodeResetEvent = new ManualResetEvent(false); _videoTransmitThread = new Thread(TransmitVideo); _videoTransmitThread.Name = "MediaController.TransmitVideo"; _videoTransmitThread.Start(); // Create the object pools that will help us reduce time spent in garbage collection. _videoBufferPool = new ObjectPool <ByteStream>(() => new ByteStream(VideoConstants.MaxPayloadSize * 2), bs => bs.Reset()); _packetBufferPool = new ObjectPool <ByteStream>(() => new ByteStream(RtpPacketData.DataPacketMaxLength), bs => bs.Reset()); _videoChunkPool = new ObjectPool <Chunk>(() => new Chunk { Payload = new ByteStream(VideoConstants.MaxPayloadSize * 2) }, chunk => { chunk.SsrcId = 0; chunk.Payload.Reset(); }); AudioStats = new ObservableCollection <AudioStatistics>(); _speakerStatistics = new AudioStatistics("Volume:Sent to Speaker", MediaStats); _microphoneStatistics = new AudioStatistics("Volume:Received from Microphone", MediaStats); _cancelledStatistics = new AudioStatistics("Volume:Echo Cancelled", MediaStats); AudioStats.Add(_speakerStatistics); AudioStats.Add(_microphoneStatistics); AudioStats.Add(_cancelledStatistics); }
public NetClient(string host, int port, MediaStatistics stats = null) { _endPoint = new DnsEndPoint(host, port); receiveArgsRecycler = new ObjectPool <SocketAsyncEventArgs>(GetReceiveArgs); sendArgsPool = new ObjectPool <SocketAsyncEventArgs>(GetSendArgs); if (stats != null) { logger = new NetClientLogger(stats); } }
public AudioStatistics(string name, MediaStatistics stats = null, int reportingInterval = 50) { Name = name; ReportingInterval = reportingInterval; if (stats != null) { Counter = stats.RegisterCounter(name); Counter.IsActive = false; // ks 7/28/11 - Disable for now } }
public NetClientLogger(MediaStatistics stats) { _timer = new Timer(TimerCallback, null, 1000, 1000); if (stats != null) { _dataSentCounter = stats.RegisterCounter("Network:KbpsSent"); _dataReceivedCounter = stats.RegisterCounter("Network:KbpsReceived"); _dataSentCounter.IsActive = false; _dataReceivedCounter.IsActive = false; } }
public RtpMediaConnection(MediaConfig config, MediaStatistics mediaStats) { _controlClient = new NetClient(config.MediaServerHost, config.MediaServerControlPort); _rtpClient = new NetClient(config.MediaServerHost, config.MediaServerStreamingPort, mediaStats); _rtpConnect = new RtpPacketConnect(); _rtpData = new RtpPacketData(); _rtpConnect.SsrcId = config.LocalSsrcId; _dataReceiveBuffer = new ByteStream(RtpPacketData.DataPacketMaxLength * 10); // Leave room for at least 10 packets. _rtpPacketDataListPool = new ObjectPool <List <RtpPacketData> >(() => new List <RtpPacketData>(), list => list.Clear()); _rtpPacketDataPool = new ObjectPool <RtpPacketData>(() => new RtpPacketData()); // No reset action needed _packetBufferPool = new ObjectPool <ByteStream>(() => new ByteStream(RtpPacketData.DataPacketMaxLength), bs => bs.Reset()); }
public MediaControllerLogger(IVideoQualityController videoQualityController, MediaStatistics mediaStatistics = null) { _videoQualityController = videoQualityController; if (mediaStatistics != null) { _videoKbpsCounter = mediaStatistics.RegisterCounter("Video:KbpsEncoded"); _videoKbpsCounter.AxisMinimum = 0; _duplicateSequenceNumbers = mediaStatistics.RegisterCounter("Audio:Duplicate SequenceNumbers"); _duplicateSequenceNumbers.IsActive = false; _recordingRateCounter = mediaStatistics.RegisterCounter("Audio:RecordingRate"); _recordingRateCounter.IsActive = true; _recordingRateCounter.MinimumDelta = 2; _playingRateCounter = mediaStatistics.RegisterCounter("Audio:PlayingRate"); _playingRateCounter.MinimumDelta = 2; _playingRateCounter.IsActive = true; } }
public AudioJitterQueueLogger(MediaStatistics mediaStatistics = null) { if (mediaStatistics != null) { _queueLengthCounter = mediaStatistics.RegisterCounter("AudioQueue.Length"); _queueLengthCounter.AxisMinimum = 0; _queueLengthCounter.AxisMaximum = 50; _emptyCounter = mediaStatistics.RegisterCounter("AudioQueue.EmptyReads%"); _emptyCounter.AxisMinimum = 0; _emptyCounter.AxisMaximum = 100; _fullCounter = mediaStatistics.RegisterCounter("AudioQueue.FullWrites%"); _fullCounter.AxisMinimum = 0; _fullCounter.AxisMaximum = 100; _disorderedCounter = mediaStatistics.RegisterCounter("AudioQueue.PacketsOutOfOrder%"); _disorderedCounter.IsActive = false; // Hide for now. } AvgMsBetweenReads = AudioConstants.MillisecondsPerFrame; _lastResetAt = DateTime.Now; }
public MediaEnvironment(MediaStatistics mediaStatistics = null) { try { _analytics = new Analytics(); if (mediaStatistics != null) { _cpuCounter = mediaStatistics.RegisterCounter("CPU"); _cpuCounter.AxisMinimum = 0; _cpuCounter.AxisMaximum = 100; _cpuCounter.IsActive = true; } } catch (Exception ex) { // ks 9/23/11 - Not sure why this happens sometimes - might be a Silverlight 5 issue. ClientLogger.Debug(ex.ToString); } }
public IVideoCodec GetVideoDecoder(IVideoQualityController videoQualityController, MediaStatistics mediaStatistics = null) { var videoCodec = new JpegDiffVideoCodec(videoQualityController, mediaStatistics); videoCodec.Initialize(VideoConstants.Height, VideoConstants.Width, VideoConstants.MaxPayloadSize); return(videoCodec); }
public IAudioDecoder GetAudioDecoder(AudioCodecType codecTypeType, MediaStatistics mediaStatistics = null) { return(decoders[codecTypeType]); }
public AudioJitterQueue(ICodecFactory codecFactory, IVideoQualityController videoQualityController, MediaStatistics mediaStatistics = null) { _codecFactory = codecFactory; AudioDecoder = codecFactory.GetAudioDecoder(AudioCodecType.Speex); // Default to Speex. _videoQualityController = videoQualityController; _queue = new PriorityQueue <AudioJitterQueueEntry>(); _logger = new AudioJitterQueueLogger(mediaStatistics); _entryPool = new ObjectPool <AudioJitterQueueEntry>(() => new AudioJitterQueueEntry()); SetDefaults(); }