Skip to content
This repository was archived by the owner on Jul 19, 2024. It is now read-only.

Commit 5c9e832

Browse files
https://github.com/Microsoft/HoloLensCompanionKit/issues/113
Update spectator view to the latest HoloToolkit (1.5.7) Update color frame caching to increase stability of composited holograms. - With this change, a few actions are required: 1. Updated spectator view code will need to be merged into existing projects. 2. The compositor DLLs will need to be rebuilt and copied into existing projects.
1 parent 712972b commit 5c9e832

File tree

473 files changed

+60455
-55305
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

473 files changed

+60455
-55305
lines changed

SpectatorView/Calibration/Calibration/CalibrationApp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void CalibrationApp::Initialize(HWND window, int width, int height)
100100
frameProvider = new DeckLinkManager(true, true);
101101
#endif
102102
#if USE_OPENCV
103-
frameProvider = new OpenCVFrameProvider();
103+
frameProvider = new OpenCVFrameProvider(false);
104104
#endif
105105

106106
frameProvider->Initialize(srv, nullptr);

SpectatorView/Compositor/CompositorDLL/CompositorInterface.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ bool CompositorInterface::Initialize(ID3D11Device* device, ID3D11ShaderResourceV
5050

5151
_device = device;
5252

53-
hologramQueue = new HologramQueue(device);
53+
hologramQueue = new HologramQueue();
5454

5555
return SUCCEEDED(frameProvider->Initialize(colorSRV, outputTexture));
5656
}
@@ -124,7 +124,7 @@ void CompositorInterface::StopFrameProvider()
124124
#endif
125125
}
126126

127-
LONGLONG CompositorInterface::GetColorTime()
127+
LONGLONG CompositorInterface::GetTimestamp()
128128
{
129129
if (frameProvider != nullptr)
130130
{

SpectatorView/Compositor/CompositorDLL/CompositorInterface.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class CompositorInterface
5757
DLLEXPORT void Update();
5858
DLLEXPORT void StopFrameProvider();
5959

60-
DLLEXPORT LONGLONG GetColorTime();
60+
DLLEXPORT LONGLONG GetTimestamp();
61+
6162
DLLEXPORT LONGLONG GetColorDuration();
6263

6364
DLLEXPORT void TakePicture(ID3D11Device* device, int width, int height, int bpp,

SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
445455
void 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;

SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,20 @@ class DeckLinkDevice : public IDeckLinkInputCallback
5757
CRITICAL_SECTION m_outputCriticalSection;
5858

5959
BYTE* localFrameBuffer;
60-
BYTE* rawBuffer = new BYTE[FRAME_BUFSIZE_RAW];
60+
BYTE* rawBuffer = new BYTE[FRAME_BUFSIZE_RAW];
6161

62-
BYTE* cachedBuffer = new BYTE[FRAME_BUFSIZE];
63-
BYTE* stagingBuffer = new BYTE[FRAME_BUFSIZE];
64-
BYTE* latestBuffer = new BYTE[FRAME_BUFSIZE];
65-
BYTE* outputBuffer = new BYTE[FRAME_BUFSIZE];
66-
BYTE* outputBufferRaw = new BYTE[FRAME_BUFSIZE_RAW];
62+
BYTE* thirdCachedBuffer = new BYTE[FRAME_BUFSIZE];
63+
BYTE* secondCachedBuffer = new BYTE[FRAME_BUFSIZE];
64+
BYTE* latestBuffer = new BYTE[FRAME_BUFSIZE];
65+
BYTE* stagingBuffer = new BYTE[FRAME_BUFSIZE];
66+
BYTE* outputBuffer = new BYTE[FRAME_BUFSIZE];
67+
BYTE* outputBufferRaw = new BYTE[FRAME_BUFSIZE_RAW];
6768

6869
BMDTimeValue frameDuration = 0;
6970

7071
LONGLONG latestTimeStamp = 0;
71-
LONGLONG cachedTimeStamp = 0;
72+
LONGLONG secondTimeStamp = 0;
73+
LONGLONG thirdTimeStamp = 0;
7274

7375
bool dirtyFrame = true;
7476
bool isVideoFrameReady = false;
@@ -104,9 +106,9 @@ class DeckLinkDevice : public IDeckLinkInputCallback
104106
virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags);
105107
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* frame, /* in */ IDeckLinkAudioInputPacket* audioPacket);
106108

107-
LONGLONG GetTimeStamp()
109+
LONGLONG GetTimestamp()
108110
{
109-
return cachedTimeStamp;
111+
return thirdTimeStamp;
110112
}
111113

112114
LONGLONG GetDurationHNS()

SpectatorView/Compositor/CompositorDLL/DeckLinkManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ LONGLONG DeckLinkManager::GetTimestamp()
123123
{
124124
if (IsEnabled())
125125
{
126-
return deckLinkDevice->GetTimeStamp();
126+
return deckLinkDevice->GetTimestamp();
127127
}
128128

129129
return 0;

SpectatorView/Compositor/CompositorDLL/DeckLinkManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ class DeckLinkManager : public IFrameProvider
1616

1717
HRESULT Initialize(ID3D11ShaderResourceView* colorSRV, ID3D11Texture2D* outputTexture);
1818

19+
// 3 frames are caches for reliable hologram stability:
20+
// Get the timestamp of the earliest (and currently rendered) cached frame.
1921
LONGLONG GetTimestamp();
22+
2023
LONGLONG GetDurationHNS();
2124

2225
void Update();

SpectatorView/Compositor/CompositorDLL/ElgatoFrameProvider.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ class ElgatoFrameProvider : public IFrameProvider
106106
IBaseFilter *pNullF = NULL;
107107
ElgatoSampleCallback *frameCallback = NULL;
108108
IElgatoVideoCaptureFilter6 *filter = NULL;
109-
110-
BYTE* cachedBuffer = new BYTE[FRAME_BUFSIZE];
111109
};
112110

113111
#endif

SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ STDMETHODIMP ElgatoSampleCallback::BufferCB(double time, BYTE *pBuffer, long len
2020
// Get frame time.
2121
LARGE_INTEGER t;
2222
QueryPerformanceCounter(&t);
23-
cachedTimestamp = t.QuadPart;
23+
thirdTimeStamp = secondTimeStamp;
24+
secondTimeStamp = latestTimeStamp;
25+
latestTimeStamp = t.QuadPart;
2426

2527
int copyLength = length;
2628
if (copyLength > FRAME_BUFSIZE)
@@ -29,7 +31,10 @@ STDMETHODIMP ElgatoSampleCallback::BufferCB(double time, BYTE *pBuffer, long len
2931
copyLength = FRAME_BUFSIZE;
3032
}
3133

32-
memcpy(cachedBytes, pBuffer, copyLength);
34+
memcpy(thirdCachedBuffer, secondCachedBuffer, FRAME_BUFSIZE);
35+
memcpy(secondCachedBuffer, latestBuffer, FRAME_BUFSIZE);
36+
memcpy(latestBuffer, pBuffer, copyLength);
37+
3338
EnterCriticalSection(&frameAccessCriticalSection);
3439
isVideoFrameReady = true;
3540
LeaveCriticalSection(&frameAccessCriticalSection);
@@ -42,13 +47,14 @@ void ElgatoSampleCallback::UpdateSRV(ID3D11ShaderResourceView* srv, bool useCPU)
4247
if (useCPU)
4348
{
4449
BYTE* stagingBytes = new BYTE[FRAME_BUFSIZE];
45-
DirectXHelper::ConvertYUVtoBGRA(cachedBytes, stagingBytes, FRAME_WIDTH, FRAME_HEIGHT, true);
50+
// Do not cache when using the CPU
51+
DirectXHelper::ConvertYUVtoBGRA(latestBuffer, stagingBytes, FRAME_WIDTH, FRAME_HEIGHT, true);
4652
DirectXHelper::UpdateSRV(_device, srv, stagingBytes, FRAME_WIDTH * FRAME_BPP);
4753
delete[] stagingBytes;
4854
}
4955
else
5056
{
51-
DirectXHelper::UpdateSRV(_device, srv, cachedBytes, FRAME_WIDTH * FRAME_BPP);
57+
DirectXHelper::UpdateSRV(_device, srv, thirdCachedBuffer, FRAME_WIDTH * FRAME_BPP);
5258
}
5359
}
5460

SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class ElgatoSampleCallback : public ISampleGrabberCB
5656

5757
LONGLONG GetTimestamp()
5858
{
59-
return cachedTimestamp;
59+
return thirdTimeStamp;
6060
}
6161

6262
bool IsVideoFrameReady();
@@ -65,8 +65,13 @@ class ElgatoSampleCallback : public ISampleGrabberCB
6565
ULONG m_cRef = 0;
6666

6767
ID3D11Device* _device;
68-
BYTE* cachedBytes = new BYTE[FRAME_BUFSIZE];
69-
LONGLONG cachedTimestamp = -1;
68+
BYTE* thirdCachedBuffer = new BYTE[FRAME_BUFSIZE];
69+
BYTE* secondCachedBuffer = new BYTE[FRAME_BUFSIZE];
70+
BYTE* latestBuffer = new BYTE[FRAME_BUFSIZE];
71+
72+
LONGLONG latestTimeStamp = 0;
73+
LONGLONG secondTimeStamp = 0;
74+
LONGLONG thirdTimeStamp = 0;
7075

7176
CRITICAL_SECTION frameAccessCriticalSection;
7277
bool isVideoFrameReady = false;

0 commit comments

Comments
 (0)