Lightpack icon indicating copy to clipboard operation
Lightpack copied to clipboard

Prismatik HDR bug - Light blinking when moving mouse

Open nhac-lly opened this issue 6 years ago • 60 comments

I have the issue here: https://www.youtube.com/watch?v=NgSb_JKcttU FYI the controller is CH340 chinese one.

nhac-lly avatar Mar 07 '19 13:03 nhac-lly

Same here. I have used ATmega328 CH340 Chinese replica and 2-3 days from installing everything was working normally, but suddenly the LEDs start flickering with different colors when I move the mouse. And it only happens when any window or app are running in fullscreen.

MegaVat30 avatar May 07 '19 19:05 MegaVat30

Is it related to HDR? Does it occur if HDR is disabled?

psieg avatar May 16 '19 17:05 psieg

@psieg Yes, it's HDR related since it's does not happened on SDR. My workaround is to have mouse trail enabled, I guess it's linked to refresh rate.

nhac-lly avatar May 23 '19 07:05 nhac-lly

I have the same problem here: https://github.com/psieg/Lightpack/issues/355

sblantipodi avatar Jun 09 '20 14:06 sblantipodi

the problem happen if your grab interval is "too fast" for what your PC can capture.

If you can capture at 30FPS, set the grab interval under 33ms, if you can capture at 60FPS, set the grab interval under 16ms...

this is not a solution but a workaround, it should work.

and it is another reason why I don't understand how nvidia can deprecate NVFBC. https://github.com/psieg/Lightpack/issues/235#issuecomment-639397507

sblantipodi avatar Jun 09 '20 14:06 sblantipodi

Try running this build with flashes and without. It should save frames in your %tmp%. Hopefully we'll be able to see what's going on. Save frames in between sessions as it'll override the previous ones (don't run long sessions, depending on your disk space)

zomfg avatar Jun 09 '20 16:06 zomfg

I see nothing strange in the image produced by your build zomfg.

Imho the problem isn't in the capturing step but in the output of the software from the PC to the microcontroller. Most probably it's not even a problem of the software that sends data to the microcontroller but simply in the transmission that isn't synced well.

I was able to reproduce the problem on a software written by my own.

the problem is that some "dirty transmission" isn't blocked by the checksum check you use before displaying the colors on the led strip. It's not a big problem thoug, it happen every three or four minutes and it last the time of a lightning.

sblantipodi avatar Jul 06 '20 18:07 sblantipodi

if by checksum you mean the 3 bytes after "Ada", that only applies to the led count, the color values aren't taken into account if you set logs to 2, that'll log the color values the are sent to the device, if you can capture it while running something like this, maybe we'll see some pattern...

zomfg avatar Jul 06 '20 19:07 zomfg

I'm pretty sure this is unrelated to sending data to the microcontroller. I am using Prismatik without any external ledstrip connected to my computer. Instead I use the socket api that comes with Prismatik to send the color values to my own application, which then sends http requests to my lights. I'm seeing the same issue without any microcontroller for a ledstrip. In fact, if you look at the device tab, you can see the colors turning black sometimes.

Or at least, that's how it used to be for me anyway. I can't seem to replicate it anymore now, I recently switched from an amd card to one from nvidia, so perhaps that's related.

jespertheend avatar Jul 07 '20 18:07 jespertheend

Don't know what happened but I have the same problem of the opener. Prismatik is unusable when HDR is on

sblantipodi avatar Aug 01 '20 15:08 sblantipodi

In my case, the problem was solved by replacing all LED strips and wiring. Apparently I had some faulty LEDs.

MegaVat30 avatar Aug 01 '20 15:08 MegaVat30

In my case, the problem was solved by replacing all LED strips and wiring. Apparently I had some faulty LEDs.

I don't think that this can be the case since it works ok without HDR

sblantipodi avatar Aug 01 '20 20:08 sblantipodi

Ok I finally release my implementation of Screen Capture for Adalight devices and I don't have any problems with HDR.

Obviously I don't post the link to my implementation because it would not be correct to you guys, I love your community and your work here. If someone is interested in having a working HDR can try my implementation on my GitHub.

I still remain a big fan of prismatik and hope that this problem will be solved in the future.

PS: Zomfg, sorry I had no time to do that try, I will do it as soon as I can.

sblantipodi avatar Aug 02 '20 00:08 sblantipodi

Hello. I'm also interested in HDR fix. I have now HDR 144Hz monitor. When switching to 10bit support or opening game with HDR I have this blinking.
I tried to play with the source codes. I successfully updated dxgi to use FLIP SWAP CHAIN. Then I tried to change DXGI_FORMAT to R16G16B16A16_FLOAT without success. With R10G10B10A2_UNORM I have no flickering, but I got weird colors on the LEDs :/ DXGI and C++ is absolutely new to me, so it's hard to try something :D

EDIT: Is interesting that it flash really only when actual FPS are lower then grab interval (or something like this) EDIT2: Ok it's not only about FPS. But it happens always when you move with mouse, but what is interesting if you grab e.g. window and move with window, it works ok

P.S. You can simulate this behaviour on SDR monitor by setting const DXGI_FORMAT DesktopFormats[] = { DXGI_FORMAT_R10G10B10A2_UNORM }; under DDUplGrabber.cpp

Benik3 avatar Nov 15 '20 15:11 Benik3

interesting... could you push this to a branch on your fork? this issue is very confusing since the documentation says you'll always get 8bit data, so I assumed it would shift rgb30 to rgb24 before passing data... with HDR on, could you capture and save 1 raw frame with stock/8bit DDupl grabber, and 1 with your 10bit change with something like this (change file path) make half of your screen red/0xff0000 (fullscreen would be best), don't use a video source, make an image or html page maybe do a couple of other colors, just note the hex values thanks

diff --git a/Software/grab/GrabberBase.cpp b/Software/grab/GrabberBase.cpp
index 56a0b571..87278bf5 100644
--- a/Software/grab/GrabberBase.cpp
+++ b/Software/grab/GrabberBase.cpp
@@ -28,6 +28,7 @@
 #include "GrabberBase.hpp"
 #include "src/debug.h"
 #include <cmath>
+#include <QFile>
 
 namespace
 {
@@ -140,6 +141,7 @@ void GrabberBase::grab()
 		++grabScreensCount;
 		_context->grabResult->clear();
 
+		const GrabbedScreen *gs = NULL;
 		for (int i = 0; i < _context->grabWidgets->size(); ++i) {
 			if (!_context->grabWidgets->at(i)->isAreaEnabled()) {
 				_context->grabResult->append(qRgb(0,0,0));
@@ -149,6 +151,7 @@ void GrabberBase::grab()
 			getValidRect(widgetRect);
 
 			const GrabbedScreen *grabbedScreen = screenOfRect(widgetRect);
+			gs = grabbedScreen;
 			if (grabbedScreen == NULL) {
 				DEBUG_HIGH_LEVEL << Q_FUNC_INFO << " widget is out of screen " << Debug::toString(widgetRect);
 				_context->grabResult->append(0);
@@ -222,7 +225,9 @@ void GrabberBase::grab()
 				preparedRect);
 			_context->grabResult->append(avgColor);
 		}
-
+		QFile frameFile("/tmp/frame.dat");
+		frameFile.open(QIODevice::WriteOnly);
+		frameFile.write(QByteArray::fromRawData((const char*)gs->imgData, gs->imgDataSize));
 	}
 	emit frameGrabAttempted(_lastGrabResult);
 }

zomfg avatar Nov 15 '20 23:11 zomfg

I will try it.
Here you can find my updated repository:
https://github.com/Benik3/Lightpack/tree/HDR

EDIT: Hmm with later version of Lightpack I got this error in log. No problem with version 5.11.2.23 7aa0be41 13:00:45:079 Warning: void __cdecl SettingsWindow::updateVirtualLedsColors(const class QList<unsigned int> &) colors.count() 131 != m_labelsGrabbedColors.count() 110 . Cancel updating virtual colors. LedDeviceManager(0x1e77e1f2270) EDIT2: It looks like it use virtual LEDs even I have Ambilight in config. When I change num LED under Virtual in main.conf I don't get this error but LEDs doesn't work.

Anyway i found that the problem with color happens also if you change white balance in wizard.

Benik3 avatar Nov 16 '20 11:11 Benik3

OK, I tried saving the frame as you mentioned. First interesting thing, it doesn't happen with colors with full value (e.g. R255 G0 B0, but also R255 G255 B0 ...).
With R10G10B10 on SDR the grab it see it like this: When I try full screen "dirty" yellow (R 0xFF G0xF2 B0), when LEDs are really yellow there is 00F2FFFF, but when the LEDs changes blinks to red, there is FF2F0FC0. It looks like some problem between RGB and BGR. When enabling 10bit in drivers, it see only FF2F0FC0. The same is with the blinking with using original B8G8R8.
Is true that normally Prismatik use B8G8R8, but 10bit and 16bit format is only in order R10G10B10 (R16G16B16).

P.S. I made another brach in my repository from older version of Prismatik, which works for me: https://github.com/Benik3/Lightpack/tree/dxgi%2BHDR_older

Benik3 avatar Nov 16 '20 16:11 Benik3

I think that I found some trace.
Always when the LEDs blinks, it's when AcquireNextFrame returns DXGI_ERROR_WAIT_TIMEOUT. Otherwise I think that the 10bit DXGI_FORMAT is not the way, because when we use the 8bit, the dxgi should simply convert it and that's what we wont (LEDs are 8bit anyway)

Benik3 avatar Nov 16 '20 18:11 Benik3

re-reading remarks here now makes more sense so according to this the current grabber should produce 8888 colors no matter what, and upgrading the API only allows for bypassing the 8888 conversion from whatever and yes, we don't want to convert 1010102 (or anything) ourselves because it's probably already very efficient as is but someone reported weird colors with 10bit mode iirc, so just to be sure it would be nice to look at what's captured you could alter my code snippet from above with something like this instead of QByteArray stuff

QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
QImage imog(gs->imgData, gs->bytesPerRow / 4, gs->imgDataSize / gs->bytesPerRow, QImage::Format_RGB32);
imog.save(QString("%1/priz_%2_og.png").arg(path).arg(grabScreensCount), "PNG");

try this with master build (so old API), and the new API with everything 8888, and check if images look weird I guess (but look closely, it might be subtle)

now why would AcquireNextFrame timeout all of a sudden while moving mouse?... try looking into #373, maybe it's related

zomfg avatar Nov 16 '20 23:11 zomfg

True, after re-reading the remarks I understand it also more.
I also investigated more the AcquireNextFrame. For better view I replaced the if statement with returnBlackBuffer. It looks like it's opposite. When it returns timeout, the picture is OK.
What is weird, if I have window with the "yellow" pattern and I move mouse over it, it's grabbed like the "red", but when I catch the window and move with the window, it's right grabbed like yellow.
Maybe it's some problem with Full screen grabbing and that the picture is in 8bit, but desktop maybe be in 10bit?
Anyway what is second investigation, that with that returnBlackBuffer I got white flashes e.g. when I'm in the visual studio.

The #373 also came to my mind, but making releaseFrame just before Acquire didn't change anything.

I will try tomorrow more :)

Benik3 avatar Nov 16 '20 23:11 Benik3

Good vs bad captured image:
priz_26_og priz_27_og

And it looks like the DXGI_ERROR_WAIT_TIMEOUT is not really connected with it (black is when error is returned) obrazek

BTW for some reason the saved pictures are wider then they should be (the black bar on the right). It happens even with DownscaleMipLevel = 0 (picture has 3456 instead of 3440 px) EDIT: I found that's because surfaceMap.Pitch return different number of bytes then is width*4 (e.g. it returns 1792=>448px, but texture is 430px (3440 >> 3))

Benik3 avatar Nov 17 '20 13:11 Benik3

Good vs bad captured image:

what was the test setup here? old api? new? 8bit?..

And it looks like the DXGI_ERROR_WAIT_TIMEOUT is not really connected with it (black is when error is returned)

so it's both, crazy colors and timeouts (I don't have either in SDR) can you check the captured desc.Format for each frame, in case crazy colors spit out something different if they all are DXGI_FORMAT_B8G8R8A8_UNORM that's bad news (API bug?)

BTW for some reason the saved pictures are wider then they should be (the black bar on the right). It happens even with DownscaleMipLevel = 0 (picture has 3456 instead of 3440 px)

this is normal, it's just padding for memory alignment

zomfg avatar Nov 17 '20 16:11 zomfg

It was on the new API 8bit (in Prismatik) monitor is in 10bit.
For sure I tested some DDupl sample app and didn't notice this.

Benik3 avatar Nov 17 '20 16:11 Benik3

On old API the result looks same: priz_268_og priz_269_og

When I use new API and R10G10B10A2 DXGI format, it always looks this ugly, so it looks like it doesn't convert the image to 8bit in some cases?

Benik3 avatar Nov 17 '20 16:11 Benik3

that's what I'd suspect yeah, and if desc.Format says 8888 we have no way of knowing that it's borked I guess

have you tried this one? if that works consistently, try moving things in Prismatik til it works... or in the sample til it's broken in same way :D

zomfg avatar Nov 17 '20 16:11 zomfg

I just tried to write desc.Format and texDesc.Format to txt file and is true, that this value changes.
Sometimes it returns 24 (10bit) and sometimes 87 (8bit). It looks like that that's the problem. When it returns 24, the image is broken.

screenData->duplication->GetDesc always return format 24.

Benik3 avatar Nov 17 '20 16:11 Benik3

what if you set scaledTextureDesc.Format to 8888?

zomfg avatar Nov 17 '20 17:11 zomfg

If I set scaledTextureDesc.Format it still flickers (but is interesting that saved png of screen.imgData is OK), but when I forced also screen.imgFormat = mapDXGIFormatToBufferFormat(DXGI_FORMAT_B8G8R8A8_UNORM); it looks working OK :) Changing also texture.Format cause black image.

Benik3 avatar Nov 17 '20 20:11 Benik3

so no issues now?.. you still get black frames?

zomfg avatar Nov 17 '20 20:11 zomfg

does this work?

// ...
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
// ...
scaledTextureDesc.Format = texDesc.Format;
// ...
screen.imgFormat = mapDXGIFormatToBufferFormat(texDesc.Format);
// ...

zomfg avatar Nov 17 '20 21:11 zomfg