| 80 | } |
| 81 | |
| 82 | void ScreenWorker::runNative() { |
| 83 | traceScope(); |
| 84 | Message<ScreenCapture> msg; |
| 85 | float qual = getApp()->getServer()->getScreenQuality(); |
| 86 | PNGImageFormat png; |
| 87 | JPEGImageFormat jpg; |
| 88 | bool diffDetect = getApp()->getServer()->getScreenDiffDetection(); |
| 89 | uint32_t captureCount = 0; |
| 90 | while (!threadShouldExit() && isOk()) { |
| 91 | std::unique_lock<std::mutex> lock(m_currentImageLock); |
| 92 | m_currentImageCv.wait(lock, [this] { return m_updated; }); |
| 93 | m_updated = false; |
| 94 | |
| 95 | if (nullptr != m_currentImage) { |
| 96 | std::shared_ptr<Image> imgToSend = m_currentImage; |
| 97 | bool needsBrightnessCheckOrRefresh = (captureCount++ % 20) == 0; |
| 98 | bool forceFullImg = !diffDetect || needsBrightnessCheckOrRefresh; // send a full image once per second |
| 99 | |
| 100 | // For some reason the plugin window turns white or black sometimes, this should be investigated.. |
| 101 | // For now as a hack: Check if the image is mostly white, and reset the plugin window in this case. |
| 102 | float mostlyWhite = m_width * m_height * 0.99f; |
| 103 | float mostlyBlack = 0.1f; |
| 104 | float brightness = mostlyWhite / 2; |
| 105 | |
| 106 | // Calculate the difference between the current and the last image |
| 107 | auto diffPxCount = (uint64_t)(m_width * m_height); |
| 108 | if (!forceFullImg && m_lastImage != nullptr && m_currentImage->getBounds() == m_lastImage->getBounds() && |
| 109 | m_diffImage != nullptr) { |
| 110 | brightness = 0; |
| 111 | diffPxCount = ImageDiff::getDelta( |
| 112 | *m_lastImage, *m_currentImage, *m_diffImage, |
| 113 | [&brightness](const PixelARGB& px) { brightness += ImageDiff::getBrightness(px); }); |
| 114 | imgToSend = m_diffImage; |
| 115 | } else if (needsBrightnessCheckOrRefresh && !diffDetect) { |
| 116 | brightness = ImageDiff::getBrightness(*imgToSend); |
| 117 | } |
| 118 | |
| 119 | if (brightness >= mostlyWhite || brightness <= mostlyBlack) { |
| 120 | logln("resetting editor window"); |
| 121 | runOnMsgThreadAsync([this] { |
| 122 | traceScope(); |
| 123 | getApp()->resetEditor(m_currentTid); |
| 124 | }); |
| 125 | runOnMsgThreadAsync([this] { |
| 126 | traceScope(); |
| 127 | getApp()->restartEditor(m_currentTid); |
| 128 | }); |
| 129 | } else { |
| 130 | if (diffPxCount > 0) { |
| 131 | MemoryOutputStream mos; |
| 132 | if (diffDetect) { |
| 133 | png.writeImageToStream(*imgToSend, mos); |
| 134 | } else { |
| 135 | jpg.setQuality(qual); |
| 136 | jpg.writeImageToStream(*imgToSend, mos); |
| 137 | } |
| 138 | |
| 139 | lock.unlock(); |
nothing calls this directly
no test coverage detected