@@ -79,9 +79,10 @@ DeckLinkDevice::~DeckLinkDevice()
7979 DeleteCriticalSection (&m_outputCriticalSection);
8080 DeleteCriticalSection (&m_frameAccessCriticalSection);
8181
82- delete[] cachedBuffer ;
83- delete[] stagingBuffer ;
82+ delete[] thirdCachedBuffer ;
83+ delete[] secondCachedBuffer ;
8484 delete[] latestBuffer;
85+ delete[] stagingBuffer;
8586 delete[] outputBuffer;
8687 delete[] outputBufferRaw;
8788}
@@ -148,7 +149,8 @@ bool DeckLinkDevice::Init(ID3D11ShaderResourceView* colorSRV, ID3D11Texture2D* o
148149 BSTR deviceNameBSTR = NULL ;
149150
150151 ZeroMemory (rawBuffer, FRAME_BUFSIZE_RAW);
151- ZeroMemory (cachedBuffer, FRAME_BUFSIZE);
152+ ZeroMemory (thirdCachedBuffer, FRAME_BUFSIZE);
153+ ZeroMemory (secondCachedBuffer, FRAME_BUFSIZE);
152154 ZeroMemory (latestBuffer, FRAME_BUFSIZE);
153155 ZeroMemory (outputBuffer, FRAME_BUFSIZE);
154156 ZeroMemory (outputBufferRaw, FRAME_BUFSIZE_RAW);
@@ -372,13 +374,16 @@ HRESULT DeckLinkDevice::VideoInputFrameArrived(/* in */ IDeckLinkVideoInputFrame
372374 {
373375 if (frame->GetBytes ((void **)&rawBuffer) == S_OK)
374376 {
377+ // Always return the latest buffer when using the CPU.
375378 if (_useCPU)
376379 {
377- DirectXHelper::ConvertYUVtoBGRA (rawBuffer, cachedBuffer , FRAME_WIDTH, FRAME_HEIGHT, true );
380+ DirectXHelper::ConvertYUVtoBGRA (rawBuffer, latestBuffer , FRAME_WIDTH, FRAME_HEIGHT, true );
378381 }
379382 else
380383 {
381- memcpy (cachedBuffer, rawBuffer, FRAME_BUFSIZE_RAW);
384+ memcpy (thirdCachedBuffer, secondCachedBuffer, FRAME_BUFSIZE_RAW);
385+ memcpy (secondCachedBuffer, latestBuffer, FRAME_BUFSIZE_RAW);
386+ memcpy (latestBuffer, rawBuffer, FRAME_BUFSIZE_RAW);
382387 }
383388 }
384389 }
@@ -391,11 +396,14 @@ HRESULT DeckLinkDevice::VideoInputFrameArrived(/* in */ IDeckLinkVideoInputFrame
391396 // TODO: Remove this block if R and B components are swapped in color feed.
392397 memcpy (stagingBuffer, localFrameBuffer, FRAME_BUFSIZE);
393398 DirectXHelper::ConvertBGRAtoRGBA (stagingBuffer, FRAME_WIDTH, FRAME_HEIGHT, true );
394- memcpy (cachedBuffer, stagingBuffer, FRAME_BUFSIZE);
399+ // Do not cache frames when using the CPU
400+ memcpy (latestBuffer, stagingBuffer, FRAME_BUFSIZE);
395401 }
396402 else
397403 {
398- memcpy (cachedBuffer, localFrameBuffer, FRAME_BUFSIZE);
404+ memcpy (thirdCachedBuffer, secondCachedBuffer, FRAME_BUFSIZE);
405+ memcpy (secondCachedBuffer, latestBuffer, FRAME_BUFSIZE);
406+ memcpy (latestBuffer, localFrameBuffer, FRAME_BUFSIZE);
399407 }
400408 }
401409 }
@@ -404,7 +412,9 @@ HRESULT DeckLinkDevice::VideoInputFrameArrived(/* in */ IDeckLinkVideoInputFrame
404412 frame->GetStreamTime (&t, &frameDuration, QPC_MULTIPLIER);
405413
406414 // Get frame time.
407- cachedTimeStamp = time.QuadPart ;
415+ thirdTimeStamp = secondTimeStamp;
416+ secondTimeStamp = latestTimeStamp;
417+ latestTimeStamp = time.QuadPart ;
408418
409419 dirtyFrame = false ;
410420
@@ -445,13 +455,20 @@ HRESULT DeckLinkDevice::VideoInputFrameArrived(/* in */ IDeckLinkVideoInputFrame
445455void DeckLinkDevice::Update ()
446456{
447457 if (_colorSRV != nullptr &&
448- cachedBuffer != nullptr &&
449458 device != nullptr )
450459 {
451460 if (!dirtyFrame)
452461 {
453462 dirtyFrame = true ;
454- DirectXHelper::UpdateSRV (device, _colorSRV, cachedBuffer, FRAME_WIDTH * FRAME_BPP);
463+ if (_useCPU && latestBuffer != nullptr )
464+ {
465+ // Do not cache when using CPU.
466+ DirectXHelper::UpdateSRV (device, _colorSRV, latestBuffer, FRAME_WIDTH * FRAME_BPP);
467+ }
468+ else if (!_useCPU && thirdCachedBuffer != nullptr )
469+ {
470+ DirectXHelper::UpdateSRV (device, _colorSRV, thirdCachedBuffer, FRAME_WIDTH * FRAME_BPP);
471+ }
455472
456473 EnterCriticalSection (&m_frameAccessCriticalSection);
457474 isVideoFrameReady = true ;
0 commit comments