Пример #1
0
        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();
            };
        }
Пример #2
0
        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;
            }
        }