/// <summary> /// Create a new buffer index associated with the given cname and payload. Note that the /// buffer does not exist until SetMediaTypes and CreateBuffers methods have been called. /// The index uniquely identifies the stream so that when a sample grabber callback writes /// a sample, the sample goes to the correct buffer. We do not use ssrc to identify the /// stream because the buffer needs to exist for the duration of an encoding session while /// the ssrc may change during that time. /// </summary> /// <param name="cname"></param> /// <param name="payload"></param> /// <returns>Index, or -1 indicates an error</returns> public int CreateBufferIndex(String cname, PayloadType payload) { int newIndex = -1; if (payload == PayloadType.dynamicVideo) { if (videoBuffer == null) { videoBuffer = new VideoBuffer((uint)nextIndex, cname); newIndex = nextIndex; nextIndex++; } else { return(-1); } } else if (payload == PayloadType.dynamicAudio) { if (audioBuffers.Count < maxAudioStreams) { audioBuffers.Add(nextIndex, new AudioBuffer((uint)nextIndex, cname)); newIndex = nextIndex; nextIndex++; } else { return(-1); } } return(newIndex); }
/// <summary> /// Stop sampleWriter thread if necessary, then release buffers /// </summary> public void Dispose() { if (started) { Stop(); } videoBuffer = null; tmpVideoBuffer = null; tmpAudioBuffer = null; audioBuffers.Clear(); }
/// <summary> /// The MediaBuffer maintains one temporary buffer each for audio and video. These are used /// during the process of changing sources during an encode session. /// </summary> /// <param name="cname"></param> /// <param name="payload"></param> /// <returns></returns> public int CreateTempBufferIndex(string cname, PayloadType payload) { int newIndex = -1; if (payload == PayloadType.dynamicVideo) { tmpVideoBuffer = new VideoBuffer((uint)nextIndex, cname); newIndex = nextIndex; nextIndex++; } else if (payload == PayloadType.dynamicAudio) { tmpAudioBuffer = new AudioBuffer((uint)nextIndex, cname); newIndex = nextIndex; nextIndex++; } return(newIndex); }
/// <summary> /// Query the videobuffer to find out if the last sample at or after markOutTime has been read. /// If it has, swap the tmpVideoBuffer in place of videobuffer. /// </summary> private void CheckVideoSourceChange() { if (videoBuffer.MarkOutTime == 0) { return; } Debug.WriteLine("CheckVideoSourceChange: mo=" + videoBuffer.MarkOutTime.ToString() + " lastRead=" + videoBuffer.LastReadTime.ToString() + " now=" + DateTime.Now.Ticks.ToString()); //Here we wait for up to 5 seconds for the old video buffer to finish writing up through the mark out time. //If we have ultra-low frame rate video (such as screen streaming) the timeout does get used. //The impact of not using the timeout is that we have potential for buffer overruns in the new buffer. if ((videoBuffer.LastReadTime >= videoBuffer.MarkOutTime) || (DateTime.Now.Ticks > (long)(videoBuffer.MarkOutTime) + TimeSpan.FromSeconds(5).Ticks)) { videoSourceChangeError = ""; lock (this) { videoBuffer = tmpVideoBuffer; tmpVideoBuffer = null; if ((wmWriter != null) && (wmWriter.ConfigVideo(tmpVideoMediaType))) { videoMediaType = tmpVideoMediaType; //success. } else { videoSourceChangeError = "Failed to reset video media type."; Debug.WriteLine("Failed to reset video media type."); } } videoSwitchCompletedResetEvent.Set(); } }