From 605ebab41f5ad9c0a9552c6311dd2bc65aa05055 Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 14:06:06 -0800 Subject: [PATCH 1/8] workinprog --- Example_CPP/Screen_Capture_Example.cpp | 5 ++--- include/ios/NSFrameProcessor.h | 5 +++-- src_cpp/ios/NSFrameProcessor.mm | 9 ++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Example_CPP/Screen_Capture_Example.cpp b/Example_CPP/Screen_Capture_Example.cpp index 17d0b68b..cac52747 100644 --- a/Example_CPP/Screen_Capture_Example.cpp +++ b/Example_CPP/Screen_Capture_Example.cpp @@ -175,15 +175,14 @@ void createframegrabber() }) ->onNewFrame([&](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { // Uncomment the below code to write the image to disk for debugging - /* + auto r = realcounter.fetch_add(1); auto s = std::to_string(r) + std::string("MONITORNEW_") + std::string(".jpg"); auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA); auto imgbuffer(std::make_unique(size)); ExtractAndConvertToRGBA(img, imgbuffer.get(), size); tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); - tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); - */ + if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - onNewFramestart).count() >= 1000) { std::cout << "onNewFrame fps" << onNewFramecounter << std::endl; diff --git a/include/ios/NSFrameProcessor.h b/include/ios/NSFrameProcessor.h index c69edb3c..9f76369e 100644 --- a/include/ios/NSFrameProcessor.h +++ b/include/ios/NSFrameProcessor.h @@ -10,8 +10,9 @@ namespace SL { void setMinFrameDuration(NSFrameProcessorImpl*, const std::chrono::microseconds& ); void Pause_(NSFrameProcessorImpl*); void Resume_(NSFrameProcessorImpl*); - - DUPL_RETURN Init(NSFrameProcessorImpl* createdimpl, NSFrameProcessor* parent, const std::chrono::microseconds& ); + bool IsScreenCaptureEnabled(); + + DUPL_RETURN Init(NSFrameProcessorImpl* createdimpl, NSFrameProcessor* parent, const std::chrono::microseconds& ); class NSFrameProcessor : public BaseFrameProcessor { NSFrameProcessorImpl* NSFrameProcessorImpl_ = nullptr; diff --git a/src_cpp/ios/NSFrameProcessor.mm b/src_cpp/ios/NSFrameProcessor.mm index 4f7d945c..f9f98aec 100644 --- a/src_cpp/ios/NSFrameProcessor.mm +++ b/src_cpp/ios/NSFrameProcessor.mm @@ -1,7 +1,8 @@ #include "NSFrameProcessorm.h" #include #include - +#include + @implementation FrameProcessor -(SL::Screen_Capture::DUPL_RETURN) Init:(SL::Screen_Capture::NSFrameProcessor*) parent second:(CMTime)interval @@ -194,5 +195,11 @@ void Resume_(NSFrameProcessorImpl* p){ return p->Resume(); } } + bool IsScreenCaptureEnabled(){ + if (@available(macOS 10.15, *)) { + return CGPreflightScreenCaptureAccess(); + } + return true; + } } } From e2fc2a9f0233437ac0823829bbc3459f95010076 Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 14:24:12 -0800 Subject: [PATCH 2/8] Adding permission checks for screen capture --- Example_CPP/Screen_Capture_Example.cpp | 80 +++++---- include/ScreenCapture.h | 2 +- include/ios/NSFrameProcessor.h | 1 - src_cpp/ScreenCapture.cpp | 230 +++++++++---------------- src_cpp/ios/NSFrameProcessor.mm | 2 +- src_cpp/linux/ThreadRunner.cpp | 26 +-- src_cpp/windows/ThreadRunner.cpp | 19 ++ 7 files changed, 152 insertions(+), 208 deletions(-) diff --git a/Example_CPP/Screen_Capture_Example.cpp b/Example_CPP/Screen_Capture_Example.cpp index cac52747..ee85e3a1 100644 --- a/Example_CPP/Screen_Capture_Example.cpp +++ b/Example_CPP/Screen_Capture_Example.cpp @@ -30,30 +30,28 @@ void TestCopyContiguous() std::vector strided; - for (unsigned row(0); row < HEIGHT; ++row) - { - for (unsigned col(0); col < WIDTH; ++col) - { + for (unsigned row(0); row < HEIGHT; ++row) { + for (unsigned col(0); col < WIDTH; ++col) { strided.push_back(SL::Screen_Capture::ImageBGRA{VALID, VALID, VALID, VALID}); } } auto bytes = strided.size() * PIXEL_DEPTH; std::vector contiguous(bytes, static_cast(0)); - auto image = SL::Screen_Capture::Image{{ 0, 0, WIDTH, HEIGHT }, 0, true, strided.data() }; + auto image = SL::Screen_Capture::Image{{0, 0, WIDTH, HEIGHT}, 0, true, strided.data()}; auto result = SCL_Utility_CopyToContiguous(contiguous.data(), &image); - auto distance = std::distance(contiguous.data(), static_cast(result)); + auto distance = std::distance(contiguous.data(), static_cast(result)); - if (distance != (WIDTH * HEIGHT * PIXEL_DEPTH)) std::abort(); + if (distance != (WIDTH * HEIGHT * PIXEL_DEPTH)) + std::abort(); auto const begin(contiguous.begin()), end(contiguous.end()); - for (auto current(begin); current != end; ++current) - { - if (*current != VALID) std::abort(); + for (auto current(begin); current != end; ++current) { + if (*current != VALID) + std::abort(); } - } void TestCopyNonContiguous() @@ -66,46 +64,42 @@ void TestCopyNonContiguous() std::vector strided; - for (unsigned row(0); row < HEIGHT; ++row) - { + for (unsigned row(0); row < HEIGHT; ++row) { - for (unsigned col(0); col < WIDTH; ++col) - { + for (unsigned col(0); col < WIDTH; ++col) { strided.push_back(SL::Screen_Capture::ImageBGRA{VALID, VALID, VALID, VALID}); } - for (unsigned pad(0); pad < PADDING; ++pad) - { + for (unsigned pad(0); pad < PADDING; ++pad) { strided.push_back(SL::Screen_Capture::ImageBGRA{INVALID, INVALID, INVALID, INVALID}); } - } auto bytes = strided.size() * PIXEL_DEPTH; std::vector contiguous(bytes, static_cast(0)); - auto image = SL::Screen_Capture::Image{{ 0, 0, WIDTH, HEIGHT }, STRIDE_IN_BYTES, false, strided.data() }; + auto image = SL::Screen_Capture::Image{{0, 0, WIDTH, HEIGHT}, STRIDE_IN_BYTES, false, strided.data()}; auto result = SCL_Utility_CopyToContiguous(contiguous.data(), &image); - auto distance = std::distance(contiguous.data(), static_cast(result)); + auto distance = std::distance(contiguous.data(), static_cast(result)); // Ensures that the pointer incremented by only the amount written. - if (distance != (WIDTH * HEIGHT * PIXEL_DEPTH)) std::abort(); + if (distance != (WIDTH * HEIGHT * PIXEL_DEPTH)) + std::abort(); auto const begin(contiguous.begin()); auto contiguousEnd(begin), absoluteEnd(contiguous.end()); std::advance(contiguousEnd, WIDTH * HEIGHT * PIXEL_DEPTH); - for (auto current(begin); current != contiguousEnd; ++current) - { - if (*current != VALID) std::abort(); + for (auto current(begin); current != contiguousEnd; ++current) { + if (*current != VALID) + std::abort(); } - for (auto current(contiguousEnd); current != absoluteEnd; ++current) - { - if (*current != 0) std::abort(); + for (auto current(contiguousEnd); current != absoluteEnd; ++current) { + if (*current != 0) + std::abort(); } - } void ExtractAndConvertToRGBA(const SL::Screen_Capture::Image &img, unsigned char *dst, size_t dst_size) @@ -116,7 +110,7 @@ void ExtractAndConvertToRGBA(const SL::Screen_Capture::Image &img, unsigned char if (img.isContiguous) { memcpy(imgdist, imgsrc, dst_size); } - else { + else { for (auto h = 0; h < Height(img); h++) { auto startimgsrc = imgsrc; for (auto w = 0; w < Width(img); w++) { @@ -175,14 +169,14 @@ void createframegrabber() }) ->onNewFrame([&](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { // Uncomment the below code to write the image to disk for debugging - - auto r = realcounter.fetch_add(1); - auto s = std::to_string(r) + std::string("MONITORNEW_") + std::string(".jpg"); - auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA); - auto imgbuffer(std::make_unique(size)); - ExtractAndConvertToRGBA(img, imgbuffer.get(), size); - tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); - + + auto r = realcounter.fetch_add(1); + auto s = std::to_string(r) + std::string("MONITORNEW_") + std::string(".jpg"); + auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA); + auto imgbuffer(std::make_unique(size)); + ExtractAndConvertToRGBA(img, imgbuffer.get(), size); + tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); + if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - onNewFramestart).count() >= 1000) { std::cout << "onNewFrame fps" << onNewFramecounter << std::endl; @@ -369,6 +363,18 @@ int main() TestCopyContiguous(); TestCopyNonContiguous(); + std::cout << "Checking for Permission to capture the screen" << std::endl; + if (SL::Screen_Capture::IsScreenCaptureEnabled()) { + std::cout << "Application Allowed to Capture the screen!" << std::endl; + } + else { + std::cout << "Application Not Allowed to Capture the screen. Waiting for permission " << std::endl; + while (!SL::Screen_Capture::IsScreenCaptureEnabled()) { + std::cout << " . "; + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + } + auto goodmonitors = SL::Screen_Capture::GetMonitors(); for (auto &m : goodmonitors) { std::cout << m << std::endl; diff --git a/include/ScreenCapture.h b/include/ScreenCapture.h index 4ecc851e..fd10bb18 100644 --- a/include/ScreenCapture.h +++ b/include/ScreenCapture.h @@ -175,7 +175,7 @@ namespace Screen_Capture { SC_LITE_EXTERN std::vector GetMonitors(); // will return all windows SC_LITE_EXTERN std::vector GetWindows(); - + SC_LITE_EXTERN bool IsScreenCaptureEnabled(); SC_LITE_EXTERN bool isMonitorInsideBounds(const std::vector &monitors, const Monitor &monitor); typedef std::function WindowCaptureCallback; typedef std::function ScreenCaptureCallback; diff --git a/include/ios/NSFrameProcessor.h b/include/ios/NSFrameProcessor.h index 9f76369e..6fc014ed 100644 --- a/include/ios/NSFrameProcessor.h +++ b/include/ios/NSFrameProcessor.h @@ -10,7 +10,6 @@ namespace SL { void setMinFrameDuration(NSFrameProcessorImpl*, const std::chrono::microseconds& ); void Pause_(NSFrameProcessorImpl*); void Resume_(NSFrameProcessorImpl*); - bool IsScreenCaptureEnabled(); DUPL_RETURN Init(NSFrameProcessorImpl* createdimpl, NSFrameProcessor* parent, const std::chrono::microseconds& ); diff --git a/src_cpp/ScreenCapture.cpp b/src_cpp/ScreenCapture.cpp index c22604a2..209c3bc1 100644 --- a/src_cpp/ScreenCapture.cpp +++ b/src_cpp/ScreenCapture.cpp @@ -36,42 +36,33 @@ template bool IsMonitorInsideBounds(MonitorT monitors, const Mo return false; } else if (Height(realmonitor) == Height(monitor) && Width(realmonitor) == Width(monitor) && - (OffsetX(realmonitor) != OffsetX(monitor) || OffsetY(realmonitor) != OffsetY(monitor))) - { + (OffsetX(realmonitor) != OffsetX(monitor) || OffsetY(realmonitor) != OffsetY(monitor))) { // if the entire screen is capture and the offsets changed, get out and rebuild return false; } return true; - } -bool isMonitorInsideBounds(const std::vector &monitors, const Monitor &monitor) -{ - return IsMonitorInsideBounds(monitors, monitor); -} +bool isMonitorInsideBounds(const std::vector &monitors, const Monitor &monitor) { return IsMonitorInsideBounds(monitors, monitor); } -namespace C_API -{ +namespace C_API { -struct ICaptureConfigurationScreenCaptureCallbackWrapper -{ - void * const context; - std::shared_ptr> ptr; - explicit ICaptureConfigurationScreenCaptureCallbackWrapper(void *context = nullptr) : context(context), ptr() {} -}; + struct ICaptureConfigurationScreenCaptureCallbackWrapper { + void *const context; + std::shared_ptr> ptr; + explicit ICaptureConfigurationScreenCaptureCallbackWrapper(void *context = nullptr) : context(context), ptr() {} + }; -struct ICaptureConfigurationWindowCaptureCallbackWrapper -{ - void * const context; - std::shared_ptr> ptr; - explicit ICaptureConfigurationWindowCaptureCallbackWrapper(void *context = nullptr) : context(context), ptr() {} -}; + struct ICaptureConfigurationWindowCaptureCallbackWrapper { + void *const context; + std::shared_ptr> ptr; + explicit ICaptureConfigurationWindowCaptureCallbackWrapper(void *context = nullptr) : context(context), ptr() {} + }; -struct IScreenCaptureManagerWrapper -{ - std::shared_ptr ptr; -}; + struct IScreenCaptureManagerWrapper { + std::shared_ptr ptr; + }; }; // namespace C_API @@ -154,16 +145,13 @@ class ScreenCaptureManager : public IScreenCaptureManager { virtual bool isPaused() const override { return Thread_Data_->CommonData_.Paused; } virtual void resume() override { Thread_Data_->CommonData_.Paused = false; } - }; -class ScreenCaptureConfiguration : public ICaptureConfiguration -{ +class ScreenCaptureConfiguration : public ICaptureConfiguration { std::shared_ptr Impl_; public: - ScreenCaptureConfiguration(const std::shared_ptr &impl) : Impl_(impl) {} virtual std::shared_ptr> onNewFrame(const ScreenCaptureCallback &cb) override @@ -197,11 +185,9 @@ class ScreenCaptureConfiguration : public ICaptureConfigurationstart(); return Impl_; } - }; -namespace C_API -{ +namespace C_API { }; // namespace C_API @@ -209,40 +195,38 @@ class WindowCaptureConfiguration : public ICaptureConfiguration Impl_; - public: - - WindowCaptureConfiguration(const std::shared_ptr &impl) : Impl_(impl) {} - - virtual std::shared_ptr> onNewFrame(const WindowCaptureCallback &cb) override - { - assert(!Impl_->Thread_Data_->WindowCaptureData.OnNewFrame); - Impl_->Thread_Data_->WindowCaptureData.OnNewFrame = cb; - return std::make_shared(Impl_); - } + public: + WindowCaptureConfiguration(const std::shared_ptr &impl) : Impl_(impl) {} - virtual std::shared_ptr> onFrameChanged(const WindowCaptureCallback &cb) override - { - assert(!Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged); - Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged = cb; - return std::make_shared(Impl_); - } + virtual std::shared_ptr> onNewFrame(const WindowCaptureCallback &cb) override + { + assert(!Impl_->Thread_Data_->WindowCaptureData.OnNewFrame); + Impl_->Thread_Data_->WindowCaptureData.OnNewFrame = cb; + return std::make_shared(Impl_); + } - virtual std::shared_ptr> onMouseChanged(const MouseCallback &cb) override - { + virtual std::shared_ptr> onFrameChanged(const WindowCaptureCallback &cb) override + { + assert(!Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged); + Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged = cb; + return std::make_shared(Impl_); + } - assert(!Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged); - Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged = cb; - return std::make_shared(Impl_); - } + virtual std::shared_ptr> onMouseChanged(const MouseCallback &cb) override + { - virtual std::shared_ptr start_capturing() override - { - assert(Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged || Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged || - Impl_->Thread_Data_->WindowCaptureData.OnNewFrame); - Impl_->start(); - return Impl_; - } + assert(!Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged); + Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged = cb; + return std::make_shared(Impl_); + } + virtual std::shared_ptr start_capturing() override + { + assert(Impl_->Thread_Data_->WindowCaptureData.OnMouseChanged || Impl_->Thread_Data_->WindowCaptureData.OnFrameChanged || + Impl_->Thread_Data_->WindowCaptureData.OnNewFrame); + Impl_->start(); + return Impl_; + } }; std::shared_ptr> CreateCaptureConfiguration(const MonitorCallback &monitorstocapture) @@ -260,7 +244,7 @@ std::shared_ptr> CreateCaptureConfi return std::make_shared(impl); } -}; // namespace SL::Screen_Capture::C_API +}; // namespace SL::Screen_Capture int SCL_GetMonitors(SCL_MonitorRef monitors, int monitors_size) { @@ -283,53 +267,39 @@ int SCL_IsMonitorInsideBounds(SCL_MonitorRefConst monitors, const int monitorsiz return int(IsMonitorInsideBounds(std::span(monitors, monitorsize), *monitor)); } - void SCL_MonitorOnNewFrame(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_ScreenCaptureCallback cb) { - ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) - { - cb(&img, &monitor); - }); + ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { cb(&img, &monitor); }); } void SCL_MonitorOnNewFrameWithContext(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_ScreenCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) - { - cb(&img, &monitor, ptr->context); - }); + ptr->ptr = ptr->ptr->onNewFrame( + [=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { cb(&img, &monitor, ptr->context); }); } void SCL_MonitorOnFrameChanged(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_ScreenCaptureCallback cb) { - ptr->ptr = ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) - { - cb(&img, &monitor); - }); + ptr->ptr = + ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { cb(&img, &monitor); }); } void SCL_MonitorOnFrameChangedWithContext(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_ScreenCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) - { - cb(&img, &monitor, ptr->context); - }); + ptr->ptr = ptr->ptr->onFrameChanged( + [=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { cb(&img, &monitor, ptr->context); }); } void SCL_MonitorOnMouseChanged(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_MouseCaptureCallback cb) { - ptr->ptr = ptr->ptr->onMouseChanged([=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) - { - cb(img, &mousepoint); - }); + ptr->ptr = ptr->ptr->onMouseChanged( + [=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) { cb(img, &mousepoint); }); } void SCL_MonitorOnMouseChangedWithContext(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr, SCL_MouseCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onMouseChanged([=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) - { - cb(img, &mousepoint, ptr->context); - }); + ptr->ptr = ptr->ptr->onMouseChanged( + [=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) { cb(img, &mousepoint, ptr->context); }); } SCL_IScreenCaptureManagerWrapperRef SCL_MonitorStartCapturing(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr) @@ -348,73 +318,46 @@ void SCL_SetMouseChangeInterval(SCL_IScreenCaptureManagerWrapperRef ptr, int mil ptr->ptr->setMouseChangeInterval(std::chrono::milliseconds(milliseconds)); } -void SCL_PauseCapturing(SCL_IScreenCaptureManagerWrapperRef ptr) -{ - ptr->ptr->pause(); -} +void SCL_PauseCapturing(SCL_IScreenCaptureManagerWrapperRef ptr) { ptr->ptr->pause(); } -int SCL_IsPaused(SCL_IScreenCaptureManagerWrapperRef ptr) -{ - return int(ptr->ptr->isPaused()); -} - -void SCL_Resume(SCL_IScreenCaptureManagerWrapperRef ptr) -{ - ptr->ptr->resume(); -} +int SCL_IsPaused(SCL_IScreenCaptureManagerWrapperRef ptr) { return int(ptr->ptr->isPaused()); } -void SCL_FreeIScreenCaptureManagerWrapper(SCL_IScreenCaptureManagerWrapperRef ptr) -{ - delete ptr; -} +void SCL_Resume(SCL_IScreenCaptureManagerWrapperRef ptr) { ptr->ptr->resume(); } +void SCL_FreeIScreenCaptureManagerWrapper(SCL_IScreenCaptureManagerWrapperRef ptr) { delete ptr; } void SCL_WindowOnNewFrame(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_WindowCaptureCallback cb) { - ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) - { - cb(&img, &window); - }); + ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) { cb(&img, &window); }); } void SCL_WindowOnNewFrameWithContext(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_WindowCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onNewFrame([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) - { - cb(&img, &window, ptr->context); - }); + ptr->ptr = ptr->ptr->onNewFrame( + [=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) { cb(&img, &window, ptr->context); }); } void SCL_WindowOnFrameChanged(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_WindowCaptureCallback cb) { - ptr->ptr = ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) - { - cb(&img, &window); - }); + ptr->ptr = ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) { cb(&img, &window); }); } void SCL_WindowOnFrameChangedWithContext(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_WindowCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onFrameChanged([=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) - { - cb(&img, &window, ptr->context); - }); + ptr->ptr = ptr->ptr->onFrameChanged( + [=](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Window &window) { cb(&img, &window, ptr->context); }); } void SCL_WindowOnMouseChanged(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_MouseCaptureCallback cb) { - ptr->ptr = ptr->ptr->onMouseChanged([=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) - { - cb(img, &mousepoint); - }); + ptr->ptr = ptr->ptr->onMouseChanged( + [=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) { cb(img, &mousepoint); }); } void SCL_WindowOnMouseChangedWithContext(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr, SCL_MouseCaptureCallbackWithContext cb) { - ptr->ptr = ptr->ptr->onMouseChanged([=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) - { - cb(img, &mousepoint, ptr->context); - }); + ptr->ptr = ptr->ptr->onMouseChanged( + [=](const SL::Screen_Capture::Image *img, const SL::Screen_Capture::MousePoint &mousepoint) { cb(img, &mousepoint, ptr->context); }); } SCL_IScreenCaptureManagerWrapperRef SCL_WindowStartCapturing(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr) @@ -423,7 +366,7 @@ SCL_IScreenCaptureManagerWrapperRef SCL_WindowStartCapturing(SCL_ICaptureConfigu return p; } -unsigned char* SCL_Utility_CopyToContiguous(unsigned char *dst, SCL_ImageRefConst image) +unsigned char *SCL_Utility_CopyToContiguous(unsigned char *dst, SCL_ImageRefConst image) { constexpr auto PIXEL_DEPTH = sizeof(SL::Screen_Capture::ImageBGRA); @@ -431,22 +374,19 @@ unsigned char* SCL_Utility_CopyToContiguous(unsigned char *dst, SCL_ImageRefCons auto tmp(dst); - if (image->isContiguous) - { + if (image->isContiguous) { auto size(Width(image->Bounds) * Height(image->Bounds) * PIXEL_DEPTH); std::memcpy(tmp, image->Data, size); std::advance(tmp, size); return tmp; } - else - { + else { auto const cols(SL::Screen_Capture::Width(image->Bounds)); auto const rows(SL::Screen_Capture::Height(image->Bounds)); auto const stride = image->RowStrideInBytes / PIXEL_DEPTH; - for (int row = 0; row < rows; ++row) - { + for (int row = 0; row < rows; ++row) { auto count = cols * PIXEL_DEPTH; auto start = image->Data + row * stride; std::memcpy(tmp, start, count); @@ -454,19 +394,16 @@ unsigned char* SCL_Utility_CopyToContiguous(unsigned char *dst, SCL_ImageRefCons } return tmp; - } } -SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef -SCL_CreateMonitorCaptureConfiguration(SCL_MonitorCallback monitorstocapture) +SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef SCL_CreateMonitorCaptureConfiguration(SCL_MonitorCallback monitorstocapture) { static auto maxbuffersize = 16; auto p = new SL::Screen_Capture::C_API::ICaptureConfigurationScreenCaptureCallbackWrapper(); p->ptr = SL::Screen_Capture::CreateCaptureConfiguration([=]() { - std::vector buffer; auto sizeguess = maxbuffersize; @@ -486,7 +423,6 @@ SCL_CreateMonitorCaptureConfiguration(SCL_MonitorCallback monitorstocapture) buffer.resize(sizeneeded); return buffer; - }); return p; @@ -500,7 +436,6 @@ SCL_CreateMonitorCaptureConfigurationWithContext(SCL_MonitorCallbackWithContext static auto maxbuffersize = 16; p->ptr = SL::Screen_Capture::CreateCaptureConfiguration([=]() { - std::vector buffer; auto sizeguess = maxbuffersize; @@ -521,8 +456,7 @@ SCL_CreateMonitorCaptureConfigurationWithContext(SCL_MonitorCallbackWithContext return p; } -SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef -SCL_CreateWindowCaptureConfiguration(SCL_WindowCallback windowstocapture) +SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef SCL_CreateWindowCaptureConfiguration(SCL_WindowCallback windowstocapture) { static auto maxbuffersize = 16; @@ -574,12 +508,6 @@ SCL_CreateWindowCaptureConfigurationWithContext(SCL_WindowCallbackWithContext wi return p; } -void SCL_FreeWindowCaptureConfiguration(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr) -{ - delete ptr; -} +void SCL_FreeWindowCaptureConfiguration(SCL_ICaptureConfigurationWindowCaptureCallbackWrapperRef ptr) { delete ptr; } -void SCL_FreeMonitorCaptureConfiguration(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr) -{ - delete ptr; -} +void SCL_FreeMonitorCaptureConfiguration(SCL_ICaptureConfigurationScreenCaptureCallbackWrapperRef ptr) { delete ptr; } diff --git a/src_cpp/ios/NSFrameProcessor.mm b/src_cpp/ios/NSFrameProcessor.mm index f9f98aec..0becd58e 100644 --- a/src_cpp/ios/NSFrameProcessor.mm +++ b/src_cpp/ios/NSFrameProcessor.mm @@ -195,7 +195,7 @@ void Resume_(NSFrameProcessorImpl* p){ return p->Resume(); } } - bool IsScreenCaptureEnabled(){ + bool IsScreenCaptureEnabled_(){ if (@available(macOS 10.15, *)) { return CGPreflightScreenCaptureAccess(); } diff --git a/src_cpp/linux/ThreadRunner.cpp b/src_cpp/linux/ThreadRunner.cpp index e44d64dd..6b1b0ffb 100644 --- a/src_cpp/linux/ThreadRunner.cpp +++ b/src_cpp/linux/ThreadRunner.cpp @@ -1,21 +1,13 @@ #include "ScreenCapture.h" -#include "internal/ThreadManager.h" #include "X11FrameProcessor.h" #include "X11MouseProcessor.h" +#include "internal/ThreadManager.h" -namespace SL{ - namespace Screen_Capture{ - void RunCaptureMouse(std::shared_ptr data) { - TryCaptureMouse(data); - } - void RunCaptureMonitor(std::shared_ptr data, Monitor monitor){ - TryCaptureMonitor(data, monitor); - } - void RunCaptureWindow(std::shared_ptr data, Window window){ - TryCaptureWindow(data, window); - } - } -} - - - +namespace SL { +namespace Screen_Capture { + void RunCaptureMouse(std::shared_ptr data) { TryCaptureMouse(data); } + void RunCaptureMonitor(std::shared_ptr data, Monitor monitor) { TryCaptureMonitor(data, monitor); } + void RunCaptureWindow(std::shared_ptr data, Window window) { TryCaptureWindow(data, window); } + bool IsScreenCaptureEnabled() { return true; }/// need someone to implement this +} // namespace Screen_Capture +} // namespace SL diff --git a/src_cpp/windows/ThreadRunner.cpp b/src_cpp/windows/ThreadRunner.cpp index 41f74a4c..d998be3e 100644 --- a/src_cpp/windows/ThreadRunner.cpp +++ b/src_cpp/windows/ThreadRunner.cpp @@ -27,6 +27,25 @@ namespace Screen_Capture { } } } + bool IsScreenCaptureEnabled() + { + HDESK CurrentDesktop = nullptr; + CurrentDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL); + if (!CurrentDesktop) { + // We do not have access to the desktop so request a retry + return false; + } + + // Attach desktop to this thread + bool DesktopAttached = SetThreadDesktop(CurrentDesktop) != 0; + CloseDesktop(CurrentDesktop); + CurrentDesktop = nullptr; + if (!DesktopAttached) { + // We do not have access to the desktop so request a retry + return false; + } + return true; + } template bool SwitchToInputDesktop(const std::shared_ptr data) { HDESK CurrentDesktop = nullptr; From 8be61ddb24a080953820deef70be19b5b7b11d40 Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 14:35:08 -0800 Subject: [PATCH 3/8] Adding more functions for permission screen stuffs --- include/ScreenCapture.h | 9 +++++++++ src_cpp/ios/NSFrameProcessor.mm | 8 +++++++- src_cpp/linux/ThreadRunner.cpp | 4 +++- src_cpp/windows/ThreadRunner.cpp | 4 ++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/ScreenCapture.h b/include/ScreenCapture.h index fd10bb18..bf7cc4a8 100644 --- a/include/ScreenCapture.h +++ b/include/ScreenCapture.h @@ -175,7 +175,16 @@ namespace Screen_Capture { SC_LITE_EXTERN std::vector GetMonitors(); // will return all windows SC_LITE_EXTERN std::vector GetWindows(); + // MAC, permission can be requested, but the app still needs to be restarted after permission is given. + // Linux/windows You cannot request permissions, You either have it or not! SC_LITE_EXTERN bool IsScreenCaptureEnabled(); + // MAC, permission can be requested, but the app still needs to be restarted after permission is given. + // Linux/windows You cannot request permissions, You either have it or not! + SC_LITE_EXTERN void RequestScreenCapture(); + //MAC, permission can be requested, but the app still needs to be restarted after permission is given. + //Linux/windows You cannot request permissions, You either have it or not! + SC_LITE_EXTERN bool CanRequestScreenCapture(); + SC_LITE_EXTERN bool isMonitorInsideBounds(const std::vector &monitors, const Monitor &monitor); typedef std::function WindowCaptureCallback; typedef std::function ScreenCaptureCallback; diff --git a/src_cpp/ios/NSFrameProcessor.mm b/src_cpp/ios/NSFrameProcessor.mm index 0becd58e..7585bcc9 100644 --- a/src_cpp/ios/NSFrameProcessor.mm +++ b/src_cpp/ios/NSFrameProcessor.mm @@ -195,11 +195,17 @@ void Resume_(NSFrameProcessorImpl* p){ return p->Resume(); } } - bool IsScreenCaptureEnabled_(){ + bool IsScreenCaptureEnabled(){ if (@available(macOS 10.15, *)) { return CGPreflightScreenCaptureAccess(); } return true; } + void RequestScreenCapture(){ + if (@available(macOS 10.15, *)) { + CGRequestScreenCaptureAccess(); + } + } + bool CanRequestScreenCapture() { return true; } } } diff --git a/src_cpp/linux/ThreadRunner.cpp b/src_cpp/linux/ThreadRunner.cpp index 6b1b0ffb..63ca658b 100644 --- a/src_cpp/linux/ThreadRunner.cpp +++ b/src_cpp/linux/ThreadRunner.cpp @@ -8,6 +8,8 @@ namespace Screen_Capture { void RunCaptureMouse(std::shared_ptr data) { TryCaptureMouse(data); } void RunCaptureMonitor(std::shared_ptr data, Monitor monitor) { TryCaptureMonitor(data, monitor); } void RunCaptureWindow(std::shared_ptr data, Window window) { TryCaptureWindow(data, window); } - bool IsScreenCaptureEnabled() { return true; }/// need someone to implement this + bool IsScreenCaptureEnabled() { return true; }/// need someone to implement this + void RequestScreenCapture() {} + bool CanRequestScreenCapture() { return false; } } // namespace Screen_Capture } // namespace SL diff --git a/src_cpp/windows/ThreadRunner.cpp b/src_cpp/windows/ThreadRunner.cpp index d998be3e..cf6740a5 100644 --- a/src_cpp/windows/ThreadRunner.cpp +++ b/src_cpp/windows/ThreadRunner.cpp @@ -27,6 +27,10 @@ namespace Screen_Capture { } } } + + void RequestScreenCapture() {} + bool CanRequestScreenCapture() { return false; } + bool IsScreenCaptureEnabled() { HDESK CurrentDesktop = nullptr; From 43858391993b3c7775a68a7f1d0ab411f5aff2bf Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 14:38:09 -0800 Subject: [PATCH 4/8] added to demo --- Example_CPP/Screen_Capture_Example.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Example_CPP/Screen_Capture_Example.cpp b/Example_CPP/Screen_Capture_Example.cpp index ee85e3a1..2bdd5962 100644 --- a/Example_CPP/Screen_Capture_Example.cpp +++ b/Example_CPP/Screen_Capture_Example.cpp @@ -367,13 +367,18 @@ int main() if (SL::Screen_Capture::IsScreenCaptureEnabled()) { std::cout << "Application Allowed to Capture the screen!" << std::endl; } - else { + else if (SL::Screen_Capture::CanRequestScreenCapture()){ std::cout << "Application Not Allowed to Capture the screen. Waiting for permission " << std::endl; while (!SL::Screen_Capture::IsScreenCaptureEnabled()) { + SL::Screen_Capture::RequestScreenCapture(); std::cout << " . "; std::this_thread::sleep_for(std::chrono::seconds(1)); } } + else { + std::cout << "Cannot Capture the screen due to permission issues. Exiting" << std::endl; + return 0; + } auto goodmonitors = SL::Screen_Capture::GetMonitors(); for (auto &m : goodmonitors) { From 26536a5a01d721f5e69ae09f07d62a489a0ab140 Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 16:01:43 -0800 Subject: [PATCH 5/8] added override for shitty mac --- include/internal/SCCommon.h | 22 ++++++++++++++-------- src_cpp/ios/CGFrameProcessor.cpp | 4 ++-- src_cpp/ios/NSFrameProcessor.mm | 3 ++- src_cpp/linux/X11FrameProcessor.cpp | 4 ++-- src_cpp/windows/DXFrameProcessor.cpp | 2 +- src_cpp/windows/GDIFrameProcessor.cpp | 7 +++---- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/internal/SCCommon.h b/include/internal/SCCommon.h index b7519002..ef2a775e 100644 --- a/include/internal/SCCommon.h +++ b/include/internal/SCCommon.h @@ -1,8 +1,8 @@ #pragma once #include "ScreenCapture.h" +#include #include #include -#include // this is INTERNAL DO NOT USE! namespace SL { namespace Screen_Capture { @@ -13,7 +13,7 @@ namespace Screen_Capture { std::shared_ptr MouseTimer; M OnMouseChanged; W getThingsToWatch; - }; + }; struct CommonData { // Used to indicate abnormal error condition std::atomic UnexpectedErrorEvent; @@ -49,14 +49,15 @@ namespace Screen_Capture { enum DUPL_RETURN { DUPL_RETURN_SUCCESS = 0, DUPL_RETURN_ERROR_EXPECTED = 1, DUPL_RETURN_ERROR_UNEXPECTED = 2 }; Monitor CreateMonitor(int index, int id, int h, int w, int ox, int oy, const std::string &n, float scale); - Monitor CreateMonitor(int index, int id, int adapter, int h, int w, int ox, int oy, const std::string &n, float scale); + Monitor CreateMonitor(int index, int id, int adapter, int h, int w, int ox, int oy, const std::string &n, float scale); SC_LITE_EXTERN Image CreateImage(const ImageRect &imgrect, int rowStrideInBytes, const ImageBGRA *data); // this function will copy data from the src into the dst. The only requirement is that src must not be larger than dst, but it can be smaller // void Copy(const Image& dst, const Image& src); SC_LITE_EXTERN std::vector GetDifs(const Image &oldimg, const Image &newimg); - template - void ProcessCapture(const F &data, BaseFrameProcessor &base, const C &mointor, const unsigned char *startsrc, int srcrowstride) + template + void ProcessCapture(const F &data, BaseFrameProcessor &base, const C &mointor, const unsigned char *startsrc, int srcrowstride, + bool *overridecontiguous) { ImageRect imageract; imageract.left = 0; @@ -76,6 +77,9 @@ namespace Screen_Capture { // first time through, just send the whole image auto wholeimg = CreateImage(imageract, srcrowstride, startimgsrc); wholeimg.isContiguous = dstrowstride == srcrowstride; + if (overridecontiguous) { + wholeimg.isContiguous = *overridecontiguous; + } data.OnFrameChanged(wholeimg, mointor); base.FirstRun = false; } @@ -100,13 +104,15 @@ namespace Screen_Capture { memcpy(startdst, startsrc, dstrowstride * Height(mointor)); } else { - auto monheight = std::max(Height(mointor) -1, 0); ///just in case height is 0 - assert(base.ImageBufferSize >= (monheight * srcrowstride) + dstrowstride);///the last row is all I care about, the inbetween rows will be moved up in chunk sizez of srcrowstride. This is a bounds assert + auto monheight = std::max(Height(mointor) - 1, 0); /// just in case height is 0 + assert(base.ImageBufferSize >= + (monheight * srcrowstride) + dstrowstride); /// the last row is all I care about, the inbetween rows will be moved up in chunk + /// sizez of srcrowstride. This is a bounds assert for (auto i = 0; i < Height(mointor); i++) { memcpy(startdst + (i * dstrowstride), startsrc + (i * srcrowstride), dstrowstride); } } } } -} // namespace Screen_Captures +} // namespace Screen_Capture } // namespace SL diff --git a/src_cpp/ios/CGFrameProcessor.cpp b/src_cpp/ios/CGFrameProcessor.cpp index ce336c76..a25f7940 100644 --- a/src_cpp/ios/CGFrameProcessor.cpp +++ b/src_cpp/ios/CGFrameProcessor.cpp @@ -42,8 +42,8 @@ namespace Screen_Capture { auto rawdatas = CGDataProviderCopyData(prov); auto buf = CFDataGetBytePtr(rawdatas); - - ProcessCapture(Data->WindowCaptureData, *this, window, buf, bytesperrow); + auto overridecontigousvalue = false; + ProcessCapture(Data->WindowCaptureData, *this, window, buf, bytesperrow, &overridecontigousvalue); CFRelease(rawdatas); CGImageRelease(imageRef); diff --git a/src_cpp/ios/NSFrameProcessor.mm b/src_cpp/ios/NSFrameProcessor.mm index 7585bcc9..dac42665 100644 --- a/src_cpp/ios/NSFrameProcessor.mm +++ b/src_cpp/ios/NSFrameProcessor.mm @@ -95,7 +95,8 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly); auto bytesperrow = CVPixelBufferGetBytesPerRow(imageBuffer); auto buf = static_cast(CVPixelBufferGetBaseAddress(imageBuffer)); - SL::Screen_Capture::ProcessCapture(data->ScreenCaptureData, *(self.nsframeprocessor), selectedmonitor, buf, bytesperrow); + auto overridecontigousvalue = false; + SL::Screen_Capture::ProcessCapture(data->ScreenCaptureData, *(self.nsframeprocessor), selectedmonitor, buf, bytesperrow, &overridecontigousvalue); CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly); self.Working = false; } diff --git a/src_cpp/linux/X11FrameProcessor.cpp b/src_cpp/linux/X11FrameProcessor.cpp index 680243fd..1eb9d8f5 100644 --- a/src_cpp/linux/X11FrameProcessor.cpp +++ b/src_cpp/linux/X11FrameProcessor.cpp @@ -98,7 +98,7 @@ namespace Screen_Capture AllPlanes)) { return DUPL_RETURN_ERROR_EXPECTED; } - ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, (unsigned char*)XImage_->data, XImage_->bytes_per_line); + ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, (unsigned char*)XImage_->data, XImage_->bytes_per_line, nullptr); return Ret; } DUPL_RETURN X11FrameProcessor::ProcessFrame(Window& selectedwindow){ @@ -119,7 +119,7 @@ namespace Screen_Capture AllPlanes)) { return DUPL_RETURN_ERROR_EXPECTED; } - ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, (unsigned char*)XImage_->data, XImage_->bytes_per_line); + ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, (unsigned char*)XImage_->data, XImage_->bytes_per_line, nullptr); return Ret; } } diff --git a/src_cpp/windows/DXFrameProcessor.cpp b/src_cpp/windows/DXFrameProcessor.cpp index 4a4a1b79..7a4777f3 100644 --- a/src_cpp/windows/DXFrameProcessor.cpp +++ b/src_cpp/windows/DXFrameProcessor.cpp @@ -364,7 +364,7 @@ namespace Screen_Capture { } auto startsrc = reinterpret_cast(MappingDesc.pData); - ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, startsrc, MappingDesc.RowPitch); + ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, startsrc, MappingDesc.RowPitch, nullptr); return DUPL_RETURN_SUCCESS; } } // namespace Screen_Capture diff --git a/src_cpp/windows/GDIFrameProcessor.cpp b/src_cpp/windows/GDIFrameProcessor.cpp index fe1a736d..0f95d3af 100644 --- a/src_cpp/windows/GDIFrameProcessor.cpp +++ b/src_cpp/windows/GDIFrameProcessor.cpp @@ -43,8 +43,7 @@ namespace Screen_Capture { return Ret; } DUPL_RETURN GDIFrameProcessor::ProcessFrame(const Monitor ¤tmonitorinfo) - { - + { auto Ret = DUPL_RETURN_SUCCESS; ImageRect ret; @@ -75,7 +74,7 @@ namespace Screen_Capture { bi.biSizeImage = ((ret.right * bi.biBitCount + 31) / (sizeof(ImageBGRA) * 8)) * sizeof(ImageBGRA) * ret.bottom; GetDIBits(MonitorDC.DC, CaptureBMP.Bitmap, 0, (UINT)ret.bottom, NewImageBuffer.get(), (BITMAPINFO *)&bi, DIB_RGB_COLORS); SelectObject(CaptureDC.DC, originalBmp); - ProcessCapture(Data->ScreenCaptureData, *this, currentmonitorinfo, NewImageBuffer.get(), Width(SelectedMonitor)* sizeof(ImageBGRA)); + ProcessCapture(Data->ScreenCaptureData, *this, currentmonitorinfo, NewImageBuffer.get(), Width(SelectedMonitor)* sizeof(ImageBGRA), nullptr); } return Ret; @@ -146,7 +145,7 @@ namespace Screen_Capture { bi.biSizeImage = ((Width(ret) * bi.biBitCount + 31) / (sizeof(ImageBGRA) * 8)) * sizeof(ImageBGRA) * Height(ret); GetDIBits(MonitorDC.DC, CaptureBMP.Bitmap, 0, (UINT)Height(ret), NewImageBuffer.get(), (BITMAPINFO *)&bi, DIB_RGB_COLORS); SelectObject(CaptureDC.DC, originalBmp); - ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, NewImageBuffer.get(), Width(selectedwindow)* sizeof(ImageBGRA)); + ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, NewImageBuffer.get(), Width(selectedwindow)* sizeof(ImageBGRA), nullptr); return Ret; } From 6e9e2e9aad07ae48330beedf152b5a3c396b0d9c Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 16:23:07 -0800 Subject: [PATCH 6/8] Fixing example --- Example_CPP/Screen_Capture_Example.cpp | 27 +++++++++++--------------- include/internal/SCCommon.h | 6 +----- src_cpp/ios/CGFrameProcessor.cpp | 3 +-- src_cpp/ios/NSFrameProcessor.mm | 3 +-- src_cpp/linux/X11FrameProcessor.cpp | 4 ++-- src_cpp/windows/DXFrameProcessor.cpp | 2 +- src_cpp/windows/GDIFrameProcessor.cpp | 4 ++-- 7 files changed, 19 insertions(+), 30 deletions(-) diff --git a/Example_CPP/Screen_Capture_Example.cpp b/Example_CPP/Screen_Capture_Example.cpp index 2bdd5962..74723063 100644 --- a/Example_CPP/Screen_Capture_Example.cpp +++ b/Example_CPP/Screen_Capture_Example.cpp @@ -106,22 +106,17 @@ void ExtractAndConvertToRGBA(const SL::Screen_Capture::Image &img, unsigned char { assert(dst_size >= static_cast(SL::Screen_Capture::Width(img) * SL::Screen_Capture::Height(img) * sizeof(SL::Screen_Capture::ImageBGRA))); auto imgsrc = StartSrc(img); - auto imgdist = dst; - if (img.isContiguous) { - memcpy(imgdist, imgsrc, dst_size); - } - else { - for (auto h = 0; h < Height(img); h++) { - auto startimgsrc = imgsrc; - for (auto w = 0; w < Width(img); w++) { - *imgdist++ = imgsrc->R; - *imgdist++ = imgsrc->G; - *imgdist++ = imgsrc->B; - *imgdist++ = 0; // alpha should be zero - imgsrc++; - } - imgsrc = SL::Screen_Capture::GotoNextRow(img, startimgsrc); + auto imgdist = dst; + for (auto h = 0; h < Height(img); h++) { + auto startimgsrc = imgsrc; + for (auto w = 0; w < Width(img); w++) { + *imgdist++ = imgsrc->R; + *imgdist++ = imgsrc->G; + *imgdist++ = imgsrc->B; + *imgdist++ = 0; // alpha should be zero + imgsrc++; } + imgsrc = SL::Screen_Capture::GotoNextRow(img, startimgsrc); } } @@ -367,7 +362,7 @@ int main() if (SL::Screen_Capture::IsScreenCaptureEnabled()) { std::cout << "Application Allowed to Capture the screen!" << std::endl; } - else if (SL::Screen_Capture::CanRequestScreenCapture()){ + else if (SL::Screen_Capture::CanRequestScreenCapture()) { std::cout << "Application Not Allowed to Capture the screen. Waiting for permission " << std::endl; while (!SL::Screen_Capture::IsScreenCaptureEnabled()) { SL::Screen_Capture::RequestScreenCapture(); diff --git a/include/internal/SCCommon.h b/include/internal/SCCommon.h index ef2a775e..1c55bf73 100644 --- a/include/internal/SCCommon.h +++ b/include/internal/SCCommon.h @@ -56,8 +56,7 @@ namespace Screen_Capture { SC_LITE_EXTERN std::vector GetDifs(const Image &oldimg, const Image &newimg); template - void ProcessCapture(const F &data, BaseFrameProcessor &base, const C &mointor, const unsigned char *startsrc, int srcrowstride, - bool *overridecontiguous) + void ProcessCapture(const F &data, BaseFrameProcessor &base, const C &mointor, const unsigned char *startsrc, int srcrowstride) { ImageRect imageract; imageract.left = 0; @@ -77,9 +76,6 @@ namespace Screen_Capture { // first time through, just send the whole image auto wholeimg = CreateImage(imageract, srcrowstride, startimgsrc); wholeimg.isContiguous = dstrowstride == srcrowstride; - if (overridecontiguous) { - wholeimg.isContiguous = *overridecontiguous; - } data.OnFrameChanged(wholeimg, mointor); base.FirstRun = false; } diff --git a/src_cpp/ios/CGFrameProcessor.cpp b/src_cpp/ios/CGFrameProcessor.cpp index a25f7940..a1711d8f 100644 --- a/src_cpp/ios/CGFrameProcessor.cpp +++ b/src_cpp/ios/CGFrameProcessor.cpp @@ -42,8 +42,7 @@ namespace Screen_Capture { auto rawdatas = CGDataProviderCopyData(prov); auto buf = CFDataGetBytePtr(rawdatas); - auto overridecontigousvalue = false; - ProcessCapture(Data->WindowCaptureData, *this, window, buf, bytesperrow, &overridecontigousvalue); + ProcessCapture(Data->WindowCaptureData, *this, window, buf, bytesperrow); CFRelease(rawdatas); CGImageRelease(imageRef); diff --git a/src_cpp/ios/NSFrameProcessor.mm b/src_cpp/ios/NSFrameProcessor.mm index dac42665..7585bcc9 100644 --- a/src_cpp/ios/NSFrameProcessor.mm +++ b/src_cpp/ios/NSFrameProcessor.mm @@ -95,8 +95,7 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly); auto bytesperrow = CVPixelBufferGetBytesPerRow(imageBuffer); auto buf = static_cast(CVPixelBufferGetBaseAddress(imageBuffer)); - auto overridecontigousvalue = false; - SL::Screen_Capture::ProcessCapture(data->ScreenCaptureData, *(self.nsframeprocessor), selectedmonitor, buf, bytesperrow, &overridecontigousvalue); + SL::Screen_Capture::ProcessCapture(data->ScreenCaptureData, *(self.nsframeprocessor), selectedmonitor, buf, bytesperrow); CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly); self.Working = false; } diff --git a/src_cpp/linux/X11FrameProcessor.cpp b/src_cpp/linux/X11FrameProcessor.cpp index 1eb9d8f5..680243fd 100644 --- a/src_cpp/linux/X11FrameProcessor.cpp +++ b/src_cpp/linux/X11FrameProcessor.cpp @@ -98,7 +98,7 @@ namespace Screen_Capture AllPlanes)) { return DUPL_RETURN_ERROR_EXPECTED; } - ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, (unsigned char*)XImage_->data, XImage_->bytes_per_line, nullptr); + ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, (unsigned char*)XImage_->data, XImage_->bytes_per_line); return Ret; } DUPL_RETURN X11FrameProcessor::ProcessFrame(Window& selectedwindow){ @@ -119,7 +119,7 @@ namespace Screen_Capture AllPlanes)) { return DUPL_RETURN_ERROR_EXPECTED; } - ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, (unsigned char*)XImage_->data, XImage_->bytes_per_line, nullptr); + ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, (unsigned char*)XImage_->data, XImage_->bytes_per_line); return Ret; } } diff --git a/src_cpp/windows/DXFrameProcessor.cpp b/src_cpp/windows/DXFrameProcessor.cpp index 7a4777f3..4a4a1b79 100644 --- a/src_cpp/windows/DXFrameProcessor.cpp +++ b/src_cpp/windows/DXFrameProcessor.cpp @@ -364,7 +364,7 @@ namespace Screen_Capture { } auto startsrc = reinterpret_cast(MappingDesc.pData); - ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, startsrc, MappingDesc.RowPitch, nullptr); + ProcessCapture(Data->ScreenCaptureData, *this, SelectedMonitor, startsrc, MappingDesc.RowPitch); return DUPL_RETURN_SUCCESS; } } // namespace Screen_Capture diff --git a/src_cpp/windows/GDIFrameProcessor.cpp b/src_cpp/windows/GDIFrameProcessor.cpp index 0f95d3af..4cf5b99a 100644 --- a/src_cpp/windows/GDIFrameProcessor.cpp +++ b/src_cpp/windows/GDIFrameProcessor.cpp @@ -74,7 +74,7 @@ namespace Screen_Capture { bi.biSizeImage = ((ret.right * bi.biBitCount + 31) / (sizeof(ImageBGRA) * 8)) * sizeof(ImageBGRA) * ret.bottom; GetDIBits(MonitorDC.DC, CaptureBMP.Bitmap, 0, (UINT)ret.bottom, NewImageBuffer.get(), (BITMAPINFO *)&bi, DIB_RGB_COLORS); SelectObject(CaptureDC.DC, originalBmp); - ProcessCapture(Data->ScreenCaptureData, *this, currentmonitorinfo, NewImageBuffer.get(), Width(SelectedMonitor)* sizeof(ImageBGRA), nullptr); + ProcessCapture(Data->ScreenCaptureData, *this, currentmonitorinfo, NewImageBuffer.get(), Width(SelectedMonitor)* sizeof(ImageBGRA)); } return Ret; @@ -145,7 +145,7 @@ namespace Screen_Capture { bi.biSizeImage = ((Width(ret) * bi.biBitCount + 31) / (sizeof(ImageBGRA) * 8)) * sizeof(ImageBGRA) * Height(ret); GetDIBits(MonitorDC.DC, CaptureBMP.Bitmap, 0, (UINT)Height(ret), NewImageBuffer.get(), (BITMAPINFO *)&bi, DIB_RGB_COLORS); SelectObject(CaptureDC.DC, originalBmp); - ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, NewImageBuffer.get(), Width(selectedwindow)* sizeof(ImageBGRA), nullptr); + ProcessCapture(Data->WindowCaptureData, *this, selectedwindow, NewImageBuffer.get(), Width(selectedwindow)* sizeof(ImageBGRA)); return Ret; } From 83290122d239ebb5c2766c0a349cd22a3c30b59b Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 16:28:01 -0800 Subject: [PATCH 7/8] Fixed example --- Example_CPP/Screen_Capture_Example.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Example_CPP/Screen_Capture_Example.cpp b/Example_CPP/Screen_Capture_Example.cpp index 74723063..a14843b0 100644 --- a/Example_CPP/Screen_Capture_Example.cpp +++ b/Example_CPP/Screen_Capture_Example.cpp @@ -165,12 +165,12 @@ void createframegrabber() ->onNewFrame([&](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) { // Uncomment the below code to write the image to disk for debugging - auto r = realcounter.fetch_add(1); - auto s = std::to_string(r) + std::string("MONITORNEW_") + std::string(".jpg"); - auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA); - auto imgbuffer(std::make_unique(size)); - ExtractAndConvertToRGBA(img, imgbuffer.get(), size); - tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); + //auto r = realcounter.fetch_add(1); + //auto s = std::to_string(r) + std::string("MONITORNEW_") + std::string(".jpg"); + //auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA); + //auto imgbuffer(std::make_unique(size)); + //ExtractAndConvertToRGBA(img, imgbuffer.get(), size); + //tje_encode_to_file(s.c_str(), Width(img), Height(img), 4, (const unsigned char *)imgbuffer.get()); if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - onNewFramestart).count() >= 1000) { From 3343eeac4e93519f35fd699fb6dd77973f971767 Mon Sep 17 00:00:00 2001 From: scott lee Date: Fri, 26 Nov 2021 16:31:28 -0800 Subject: [PATCH 8/8] added readme --- releasenotes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/releasenotes.txt b/releasenotes.txt index 0b6f38d8..f1addcb3 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1 +1,2 @@ -Added OpenGL example \ No newline at end of file +Fixed Example Code Extract to RGB code +Added functions to check if application has permission to capture the screen, Request permission, and can request permission \ No newline at end of file