/// <summary> /// Start Playback /// </summary> /// <param name="res"></param> public void InitPlayback(VideoBuffer videoBuffer) { if (videoBuffer == null) { throw new ArgumentNullException("videoBufferDescription"); } VerifyAccess(); TimeSpan renderinterval; try { int fps = AppDefaults.visualSettings.ui_video_rendering_fps; fps = (fps <= 0 || fps > 100) ? 100 : fps; renderinterval = TimeSpan.FromMilliseconds(1000 / fps); } catch { renderinterval = TimeSpan.FromMilliseconds(1000 / 30); } var cancellationTokenSource = new CancellationTokenSource(); renderSubscription.Disposable = Disposable.Create(() => { cancellationTokenSource.Cancel(); }); var bitmap = PrepareForRendering(videoBuffer); var cancellationToken = cancellationTokenSource.Token; var dispatcher = Application.Current.Dispatcher; var renderingTask = Task.Factory.StartNew(() => { var statistics = new CircularBuffer<long>(100); using (videoBuffer.Lock()) { try { //start rendering loop while (!cancellationToken.IsCancellationRequested) { using (var processingEvent = new ManualResetEventSlim(false)) { dispatcher.BeginInvoke(() => { using (Disposable.Create(() => processingEvent.Set())) { if (!cancellationToken.IsCancellationRequested) { //update statisitc info statistics.Enqueue(Stopwatch.GetTimestamp()); //evaluate averange rendering fps var ticksEllapsed = statistics.last - statistics.first; double avgFps = 0; if (ticksEllapsed > 0) { avgFps = ((double)statistics.length * (double)Stopwatch.Frequency) / (double)ticksEllapsed; } //render farme to screen DrawFrame(bitmap, videoBuffer, avgFps); } } }); processingEvent.Wait(cancellationToken); } cancellationToken.WaitHandle.WaitOne(renderinterval); } } catch (OperationCanceledException) { //swallow exception } catch (Exception error) { dbg.Error(error); } } }, cancellationToken); }
private void DrawFrame(WriteableBitmap bitmap, VideoBuffer videoBuffer, double averangeFps) { VerifyAccess(); if (isPaused) { return; } bitmap.Lock(); try { using (var ptr = videoBuffer.Lock()) { bitmap.WritePixels( new Int32Rect(0, 0, videoBuffer.width, videoBuffer.height), ptr.value, videoBuffer.size, videoBuffer.stride, 0, 0 ); } } finally { bitmap.Unlock(); } fpsCaption.Text = averangeFps.ToString("F1"); }
/// <summary> /// Initiate rendering loop /// </summary> /// <param name="videoBuffer"></param> public void InitPlayback(VideoBuffer videoBuffer) { if (videoBuffer == null) { throw new ArgumentNullException("videoBufferDescription"); } VerifyAccess(); TimeSpan renderinterval; try { int fps = AppDefaults.visualSettings.ui_video_rendering_fps; fps = (fps <= 0 || fps > 100) ? 100 : fps; renderinterval = TimeSpan.FromMilliseconds(1000 / fps); } catch { renderinterval = TimeSpan.FromMilliseconds(1000 / 30); } var cancellationTokenSource = new CancellationTokenSource(); renderSubscription.Disposable = Disposable.Create(() => { cancellationTokenSource.Cancel(); }); var bitmap = PrepareForRendering(videoBuffer); var cancellationToken = cancellationTokenSource.Token; var dispatcher = this.Dispatcher; //Application.Current.Dispatcher; var renderingTask = Task.Factory.StartNew(() => { var statistics = PlaybackStatistics.Start(); using (videoBuffer.Lock()) { try { //start rendering loop while (!cancellationToken.IsCancellationRequested) { using (var processingEvent = new ManualResetEventSlim(false)) { dispatcher.BeginInvoke(() => { using (Disposable.Create(() => processingEvent.Set())) { if (!cancellationToken.IsCancellationRequested) { //update statisitc info statistics.Update(videoBuffer); //render farme to screen DrawFrame(bitmap, videoBuffer, statistics); } } }); processingEvent.Wait(cancellationToken); } cancellationToken.WaitHandle.WaitOne(renderinterval); } } catch (OperationCanceledException) { //swallow exception } catch (Exception error) { dbg.Error(error); } } }, cancellationToken); }
private void DrawFrame(WriteableBitmap bitmap, VideoBuffer videoBuffer, PlaybackStatistics statistics) { VerifyAccess(); if (isPaused) { return; } using (var md = videoBuffer.Lock()) { // internally calls lock\unlock, uses MILUtilities.MILCopyPixelBuffer bitmap.WritePixels( new Int32Rect(0, 0, videoBuffer.width, videoBuffer.height), md.value.scan0Ptr, videoBuffer.size, videoBuffer.stride, 0, 0 ); } renderingFps.Text = String.Format("rendering fps: {0:F1}", statistics.avgRenderingFps); decodingFps.Text = String.Format("decoding fps: {0:F1}", statistics.avgDecodingFps); noSignalPanel.Visibility = statistics.isNoSignal ? Visibility.Visible : Visibility.Hidden; }
public void Update(VideoBuffer videoBuffer) { //update rendering times history renderTimes.Enqueue(Stopwatch.GetTimestamp()); //evaluate averange rendering fps avgRenderingFps = CalculateAvgFpsFromTimes(renderTimes); //update no signal indicator using (var md = videoBuffer.Lock()) { signal = md.value.signal; md.value.signal = 0; } UpdateNoSignal(); //evaluate averange rendering fps avgDecodingFps = CalculateAvgFpsFromTimes(decodeTimes); }