private void buttonSetup_Click(object sender, EventArgs e) { logger.Debug("buttonSetup_Click(...)"); if (presentationClock != null) { presentationClock.Dispose(); presentationClock = null; } MediaFactory.CreatePresentationClock(out presentationClock); PresentationTimeSource timeSource = null; try { MediaFactory.CreateSystemTimeSource(out timeSource); presentationClock.TimeSource = timeSource; } finally { timeSource?.Dispose(); } videoForm = new VideoForm { BackColor = Color.Black, //ClientSize = new Size(sampleArgs.Width, sampleArgs.Height), StartPosition = FormStartPosition.CenterScreen, }; videoRenderer = new MfVideoRenderer(); videoRenderer.RendererStarted += Renderer_RendererStarted; videoRenderer.RendererStopped += Renderer_RendererStopped; videoForm.Paint += (o, a) => { videoRenderer.Repaint(); }; videoForm.SizeChanged += (o, a) => { var rect = videoForm.ClientRectangle; //Console.WriteLine(rect); videoRenderer.Resize(rect); }; videoForm.Visible = true; videoRenderer.Setup(new VideoRendererArgs { hWnd = videoForm.Handle, // FourCC = new FourCC("NV12"), //FourCC = 0x59565955, //"UYVY", FourCC = new FourCC((int)Format.A8R8G8B8), Resolution = new Size(1920, 1080), FrameRate = new Tuple <int, int>(30, 1), }); videoRenderer.SetPresentationClock(presentationClock); videoRenderer.RendererStopped += () => { videoRenderer.Close(); GC.Collect(); }; videoRenderer.Resize(videoForm.ClientRectangle); sampleSource = new SampleSource(); bool isFirstTimestamp = true; long timeAdjust = 0; sampleSource.SampleReady += (sample) => { if (isFirstTimestamp) { var _sampleTime = sample.SampleTime; var presetnationTime = presentationClock.Time; var stopwatchTime = MfTool.SecToMfTicks(stopwatch.ElapsedMilliseconds / 1000.0); timeAdjust = presetnationTime - _sampleTime; //stopwatchTime; Console.WriteLine(presetnationTime + " - " + _sampleTime + " = " + timeAdjust); isFirstTimestamp = false; } //var sampleTime = sample.SampleTime; //var presetnationTime = presentationClock.Time; //var diff = sampleTime - presetnationTime; //Console.WriteLine(MfTool.MfTicksToSec(sampleTime) + " " + MfTool.MfTicksToSec(presetnationTime) + " " + MfTool.MfTicksToSec(diff)); //var stopwatchTime = MfTool.SecToMfTicks(stopwatch.ElapsedMilliseconds / 1000.0); //var diff2 = stopwatchTime - presetnationTime; //Console.WriteLine (MfTool.MfTicksToSec(stopwatchTime) + " " + MfTool.MfTicksToSec(presetnationTime) + " " + MfTool.MfTicksToSec(diff2)); var sampleTime = sample.SampleTime; sample.SampleTime = sampleTime + timeAdjust; //sample.SampleDuration = 0; videoRenderer?.ProcessSample(sample); //sample?.Dispose(); }; }
private void OnSampleDecoded(Sample sample) { if (sample == null) { return; } try { //using (var buffer = sample.ConvertToContiguousBuffer()) //{ // MediaFactory.GetService(buffer, MediaServiceKeys.Buffer, IID.D3D9Surface, out var pSurf); // var surf = new SharpDX.Direct3D9.Surface(pSurf); // var descr = surf.Description; // logger.Debug(descr.Format); //} var sampleTime = sample.SampleTime; //sampleTime += presentationAdjust; if (prevSampleTime == 0) { prevSampleTime = sampleTime; } //_sampleTime += 33333; var timeDiff = (sampleTime - prevSampleTime); //if (timeDiff < 0) //{ // logger.Warn("Not monotonic time: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); //} //else if (timeDiff > MfTool.SecToMfTicks(0.033)) //{ // //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); // var _delay = MfTool.MfTicksToSec(timeDiff - MfTool.SecToMfTicks(0.033)) * 1000; // //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff, _delay)); // Thread.Sleep((int)_delay); //} unwrappedSampleTime += timeDiff; sample.SampleTime = unwrappedSampleTime; var avgTimePerFrame = EncoderSettings.AverageTimePerFrame; sample.SampleDuration = avgTimePerFrame; // MfTool.SecToMfTicks(0.033); var presentationTime = presentationClock.Time; if (!EncoderSettings.LowLatency) { var delta = unwrappedSampleTime - presentationTime; //var avgDuration = MfTool.SecToMfTicks(0.033); if (delta < 0) { //logger.Warn("delta: " + string.Join(" ", delta)); } else if (delta > avgTimePerFrame) { //logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff)); var _delay = MfTool.MfTicksToSec(delta - avgTimePerFrame) * 1000; logger.Warn("Large time gap: " + string.Join(" ", sampleTime, prevSampleTime, timeDiff, _delay)); Thread.Sleep((int)_delay); } } sample.SampleTime = 0; sample.SampleDuration = 0; if (EncoderSettings.UseHardware) { videoRenderer.ProcessDxva2Sample(sample); } else { videoRenderer.ProcessSample(sample); } prevSampleTime = sampleTime; //logger.Debug(sampleTime + " " + prevSampleTime + " " + (sampleTime - prevSampleTime)); } finally { sample.Dispose(); sample = null; } }