diff --git a/modules/v4d/include/opencv2/v4d/v4d.hpp b/modules/v4d/include/opencv2/v4d/v4d.hpp index cf93cb715..c0cceccb6 100644 --- a/modules/v4d/include/opencv2/v4d/v4d.hpp +++ b/modules/v4d/include/opencv2/v4d/v4d.hpp @@ -125,6 +125,7 @@ class CV_EXPORTS V4D { std::future futureReader_; std::future futureWriter_; std::function keyEventCb_; + cv::Point mousePos_; uint64_t frameCnt_ = 0; bool showFPS_ = true; bool printFPS_ = true; @@ -381,6 +382,9 @@ private: bool keyboard_event(int key, int scancode, int action, int modifiers); + cv::Point getMousePosition(); + void setMousePosition(const cv::Point& pt); + FrameBufferContext& fbCtx(); CLVAContext& clvaCtx(); NanoVGContext& nvgCtx(); diff --git a/modules/v4d/src/detail/framebuffercontext.cpp b/modules/v4d/src/detail/framebuffercontext.cpp index 2146ed830..90a5844e9 100644 --- a/modules/v4d/src/detail/framebuffercontext.cpp +++ b/modules/v4d/src/detail/framebuffercontext.cpp @@ -299,33 +299,24 @@ void FrameBufferContext::init() { glfwSetWindowUserPointer(getGLFWWindow(), &getV4D()); glfwSetCursorPosCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, double x, double y) { -// V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); -//#ifdef __EMSCRIPTEN__ -// x *= v4d->pixelRatioX(); -// y *= v4d->pixelRatioY(); -//#endif -// -// if(v4d->hasNguiCtx()) { -// v4d->nguiCtx().screen().cursor_pos_callback_event(x, y); -// } -//#ifndef __EMSCRIPTEN__ -// auto cursor = v4d->getMousePosition(); -// auto diff = cursor - cv::Vec2f(x, y); -// if (v4d->isMouseDrag()) { -// v4d->pan(diff[0], -diff[1]); -// } -//#endif -// v4d->setMousePosition(x, y); + V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); +#ifdef __EMSCRIPTEN__ + x *= v4d->pixelRatioX(); + y *= v4d->pixelRatioY(); +#endif + + if(v4d->hasNguiCtx()) { + v4d->nguiCtx().screen().cursor_pos_callback_event(x, y); + } + + v4d->setMousePosition(cv::Point{x, y}); } ); glfwSetMouseButtonCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, int button, int action, int modifiers) { -// V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); -// if(v4d->hasNguiCtx()) -// v4d->nguiCtx().screen().mouse_button_callback_event(button, action, modifiers); -// if (button == GLFW_MOUSE_BUTTON_RIGHT) { -// v4d->setMouseDrag(action == GLFW_PRESS); -// } + V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); + if(v4d->hasNguiCtx()) + v4d->nguiCtx().screen().mouse_button_callback_event(button, action, modifiers); } ); glfwSetKeyCallback(getGLFWWindow(), @@ -350,21 +341,19 @@ void FrameBufferContext::init() { ); glfwSetScrollCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, double x, double y) { -// V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); -// std::vector widgets; -// if(v4d->hasNguiCtx()) { -// for (auto* w : v4d->nguiCtx().screen().children()) { -// auto pt = v4d->getMousePosition(); -// auto mousePos = nanogui::Vector2i(pt[0], pt[1]); -// if(cv::v4d::detail::contains_absolute(w, mousePos)) { -// v4d->nguiCtx().screen().scroll_callback_event(x, y); -// return; -// } -// } -// } -//#ifndef __EMSCRIPTEN__ -// v4d->zoom(y < 0 ? 1.1 : 0.9); -//#endif + V4D* v4d = reinterpret_cast(glfwGetWindowUserPointer(glfwWin)); + std::vector widgets; + if(v4d->hasNguiCtx()) { + for (auto* w : v4d->nguiCtx().screen().children()) { + auto pt = v4d->getMousePosition(); + auto mousePos = nanogui::Vector2i(pt.x, pt.y); + if(cv::v4d::detail::contains_absolute(w, mousePos)) { + v4d->nguiCtx().screen().scroll_callback_event(x, y); + return; + } + } + } + } ); diff --git a/modules/v4d/src/util.cpp b/modules/v4d/src/util.cpp index 98a2e3929..78d2abf9c 100644 --- a/modules/v4d/src/util.cpp +++ b/modules/v4d/src/util.cpp @@ -309,6 +309,34 @@ Source makeVaSource(const string& inputFilename, const int vaDeviceIndex) { return !frame.empty(); }, fps); } + +Sink makeAnyHWSink(const string& outputFilename, const int fourcc, const float fps, + const cv::Size& frameSize) { + cv::Ptr writer = new cv::VideoWriter(outputFilename, cv::CAP_FFMPEG, + fourcc, fps, frameSize, { cv::VIDEOWRITER_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_ANY }); + + if(writer->isOpened()) { + return Sink([=](const cv::UMat& frame) { + static cv::UMat resized; + cv::resize(frame, resized, frameSize); + (*writer) << resized; + return writer->isOpened(); + }); + } else { + return Sink(); + } +} + +Source makeAnyHWSource(const string& inputFilename) { + cv::Ptr capture = new cv::VideoCapture(inputFilename, cv::CAP_FFMPEG, { + cv::CAP_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_ANY }); + float fps = capture->get(cv::CAP_PROP_FPS); + + return Source([=](cv::UMat& frame) { + (*capture) >> frame; + return !frame.empty(); + }, fps); +} #endif #ifndef __EMSCRIPTEN__ @@ -316,6 +344,11 @@ Sink makeWriterSink(const string& outputFilename, const int fourcc, const float const cv::Size& frameSize) { if (isIntelVaSupported()) { return makeVaSink(outputFilename, fourcc, fps, frameSize, 0); + } else { + try { + return makeAnyHWSink(outputFilename, fourcc, fps, frameSize); + } catch(...) { + } } cv::Ptr writer = new cv::VideoWriter(outputFilename, cv::CAP_FFMPEG, @@ -336,6 +369,11 @@ Sink makeWriterSink(const string& outputFilename, const int fourcc, const float Source makeCaptureSource(const string& inputFilename) { if (isIntelVaSupported()) { return makeVaSource(inputFilename, 0); + } else { + try { + return makeAnyHWSource(inputFilename); + } catch(...) { + } } cv::Ptr capture = new cv::VideoCapture(inputFilename, cv::CAP_FFMPEG); @@ -425,24 +463,8 @@ public: return true; } -// cerr << "not captured" << endl; return false; } - - void captureCPU() { - EM_ASM( - if(globalThis.doCapture) { - if(typeof globalThis.v4dCopyCanvasContext === 'undefined' || globalThis.v4dCopyCanvasContext === null) - globalThis.v4dCopyCanvasContext = globalThis.v4dCopyCanvasElement.getContext('2d', { willReadFrequently: true }); - if(typeof globalThis.v4dFrameData === 'undefined' || globalThis.v4dFrameData === null) - globalThis.v4dFrameData = Module._malloc(width_ * height_ * 4); - - globalThis.v4dCopyCanvasElement.drawImage(globalThis.v4dVideoElement, 0, 0, 1280, 720); - var cameraArrayBuffer = globalThis.v4dCopyCanvasContext.getImageData(0, 0, 1280, 720); - Module.HEAPU8.set(cameraArrayBuffer.data, globalThis.v4dFrameData); - } - ); - } }; cv::Ptr capture = nullptr; diff --git a/modules/v4d/src/v4d.cpp b/modules/v4d/src/v4d.cpp index 02fd02a3e..0429b90a3 100644 --- a/modules/v4d/src/v4d.cpp +++ b/modules/v4d/src/v4d.cpp @@ -69,6 +69,14 @@ bool V4D::keyboard_event(int key, int scancode, int action, int modifiers) { return nguiCtx().screen().keyboard_event(key, scancode, action, modifiers); } +cv::Point V4D::getMousePosition() { + return mousePos_; +} + +void V4D::setMousePosition(const cv::Point& pt) { + mousePos_ = pt; +} + FrameBufferContext& V4D::fbCtx() { assert(mainFbContext_ != nullptr); return *mainFbContext_;