- Posts: 5
- Joined: Wed Apr 19, 2017 8:33 am
Hello,
I'm encountering some screen tearing when outputting 1920x1080p30 to a TV screen. I have included the full code below (C#). It shows a vertical bar 25 pixels wide moving across the screen. If I increase my CPU usage (artificially) the screen tearing starts to become extremely apparent.
Does anyone have an idea why this could be happening? Much appreciated
I'm encountering some screen tearing when outputting 1920x1080p30 to a TV screen. I have included the full code below (C#). It shows a vertical bar 25 pixels wide moving across the screen. If I increase my CPU usage (artificially) the screen tearing starts to become extremely apparent.
- Code: Select all
using DeckLinkAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace DeckLinkTestFrameTearing
{
class Program : IDeckLinkVideoOutputCallback
{
static void Main(string[] args)
{
new Program();
}
public Program()
{
Start();
Console.ReadLine();
}
private IDeckLink _deckLinkCard;
private IDeckLinkOutput _deckLinkOutput;
private long _totalFramesScheduled;
private long _frameDuration, _frameTimescale;
public int Width = 1920;
public int Height = 1080;
private int _barLoc = 0;
private object _lock = new object();
private int _frameCounter = 0;
private IDeckLinkMutableVideoFrame _deckLinkVideoFrame, _deckLinkTest;
public void Start()
{
IDeckLinkIterator deckLinkIterator = new CDeckLinkIterator();
deckLinkIterator.Next(out _deckLinkCard);
_deckLinkOutput = (IDeckLinkOutput)_deckLinkCard;
_deckLinkOutput.SetScheduledFrameCompletionCallback(this);
_frameDuration = 1000;
_frameTimescale = 30000;
_deckLinkOutput.EnableVideoOutput(_BMDDisplayMode.bmdModeHD1080p30, _BMDVideoOutputFlags.bmdVideoOutputFlagDefault);
_deckLinkOutput.CreateVideoFrame(Width, Height, Width * 4, _BMDPixelFormat.bmdFormat8BitBGRA, _BMDFrameFlags.bmdFrameFlagDefault, out _deckLinkVideoFrame);
_deckLinkOutput.CreateVideoFrame(Width, Height, Width * 4, _BMDPixelFormat.bmdFormat8BitBGRA, _BMDFrameFlags.bmdFrameFlagDefault, out _deckLinkTest);
FillBlackBGRA(_deckLinkVideoFrame);
for (uint i = 0; i != 25; ++i)
{
_deckLinkOutput.ScheduleVideoFrame(_deckLinkVideoFrame, _totalFramesScheduled * _frameDuration, _frameDuration, _frameTimescale);
++_totalFramesScheduled;
}
_deckLinkOutput.StartScheduledPlayback(0, 100, 1.0);
}
public void ScheduledFrameCompleted(IDeckLinkVideoFrame completedFrame, _BMDOutputFrameCompletionResult result)
{
lock (_lock)
{
IDeckLinkVideoFrame frame = _deckLinkTest;
IntPtr buffer;
frame.GetBytes(out buffer);
int width, height;
int index = 0;
width = frame.GetWidth();
height = frame.GetHeight();
int barWidth = 25;
unchecked
{
for (uint y = 0; y < height; y++)
{
for (uint x = 0; x < width; x++)
{
if (x > _barLoc && x < _barLoc + barWidth)
{
Marshal.WriteInt32(buffer, index * 4, (int)0xFFFFFFFF);
}
else
{
Marshal.WriteInt32(buffer, index * 4, (int)0x00000000);
}
++index;
}
}
}
_barLoc += barWidth;
if (_barLoc >= width)
{
_barLoc = 0;
}
_deckLinkOutput.ScheduleVideoFrame(frame, _totalFramesScheduled * _frameDuration, _frameDuration, _frameTimescale);
++_totalFramesScheduled;
++_frameCounter;
if (_frameCounter >= 25)
{
_frameCounter = 0;
}
}
}
public void ScheduledPlaybackHasStopped()
{
}
private void FillBlackBGRA(IDeckLinkVideoFrame frame)
{
IntPtr buffer;
frame.GetBytes(out buffer);
int size = Width * Height * 4;
byte[] bytes = new byte[size];
int index = 0;
for (int x = 0; x != Height; ++x)
{
for (int y = 0; y != Width; ++y)
{
bytes[index] = 0;
++index;
bytes[index] = 0;
++index;
bytes[index] = 0;
++index;
bytes[index] = 255;
++index;
}
}
Marshal.Copy(bytes, 0, buffer, size);
}
}
}
Does anyone have an idea why this could be happening? Much appreciated