/// <summary> /// Gets instance of rstp server. if it doesnt exist, creates it. /// </summary> /// <returns></returns> public static RTSPServerLoader GetInstance() { if (instance == null) { instance = new RTSPServerLoader(); UnityEngine.Debug.Log("Creating new instance of RTSPServerLoader"); } return(instance); }
public string CloseAndGetOutput() { // Terminate the subthreads. _terminate = true; _copyPing.Set(); _pipePing.Set(); _copyThread.Join(); _pipeThread.Join(); // Close FFmpeg subprocess. _subprocess.StandardInput.Close(); _subprocess.WaitForExit(); var outputReader = _subprocess.StandardError; var error = outputReader.ReadToEnd(); _subprocess.Close(); _subprocess.Dispose(); outputReader.Close(); outputReader.Dispose(); // Nullify members (just for ease of debugging). _subprocess = null; _copyThread = null; _pipeThread = null; _copyQueue = null; _pipeQueue = _freeBuffer = null; //Kill server RTSPServerLoader.GetInstance().Kill(); return(error); }
protected void PushToPipe(Texture texture, string url, int width, int height) { RTSPServerLoader loader = RTSPServerLoader.GetInstance(); if (!loader.CoroutineStarted) { StartCoroutine(loader.WaitForServerToStart()); } // Lazy initialization if (_session == null && loader.RTSPServerloaded) { Debug.Log("Creating Session: " + url); // Give a newly created temporary render texture to the camera // if it's set to render to a screen. Also create a blitter // object to keep frames presented on the screen. if (texture == null) { Debug.LogError("Texture is null"); } // Start an FFmpeg session. _session = FFmpegSession.Create( url, width, height, _frameRate, preset, _crfValue, _maxBitrate ); _startTime = Time.time; _frameCount = 0; _frameDropCount = 0; } if (_session == null) { return; } var gap = Time.time - FrameTime; var delta = 1 / _frameRate; if (gap < 0) { // Update without frame data. _session.PushFrame(null); } else if (gap < delta) { // Single-frame behind from the current time: // Push the current frame to FFmpeg. _session.PushFrame(texture); _frameCount++; } else if (gap < delta * 2) { // Two-frame behind from the current time: // Push the current frame twice to FFmpeg. Actually this is not // an efficient way to catch up. We should think about // implementing frame duplication in a more proper way. #fixme _session.PushFrame(texture); _session.PushFrame(texture); _frameCount += 2; } else { // Show a warning message about the situation. WarnFrameDrop(); // Push the current frame to FFmpeg. _session.PushFrame(texture); // Compensate the time delay. _frameCount += Mathf.FloorToInt(gap * _frameRate); } }