242 Commits
Author SHA1 Message Date
jfmcarreira 944bc0116b fix: build errors 2024-10-03 01:31:38 +01:00
jfmcarreira 303d15cbc2 Merge remote-tracking branch 'upstream/devel' into devel 2024-10-02 23:51:57 +01:00
jfmcarreira 05be89459e refactor: modernize code 2024-10-02 23:33:21 +01:00
jfmcarreira 0cf79bf7a5 ci: update build workflow 2024-04-28 01:06:14 +01:00
jfmcarreira e0db35d087 build: remove libfmt dependency 2024-04-27 22:18:18 +01:00
jfmcarreira 0d70ab8a84 build(fmt): find missing depency to libfmt 2023-09-24 21:58:58 +01:00
jfmcarreira d1e9a1cb2d fix(lib): add missing include and replace vector with span 2023-09-24 21:05:03 +01:00
Joao Carreira 18c69b8529 build(app): remove Qt6 dependency from qcustomplot 2023-04-29 01:56:40 +01:00
Joao Carreira 2f9abe7e47 fix(qt): make Qt6 optional 2023-04-28 23:32:36 +01:00
Joao Carreira 2f1d8dbb8b ci: add coverage to build without Qt6 2023-04-28 22:38:25 +01:00
Joao Carreira a2262ca3a7 feat(tests): update catch to version 3 2023-04-02 22:29:25 +01:00
Joao Carreira acb04c2360 fix: build errors and add support for Qt6 2023-03-28 01:07:32 +01:00
Joao Carreira cbefa2be2e refactor(pixel): add nameless namespace to CalypPixel 2022-11-13 21:34:43 +00:00
Joao Carreira 7dedd2f388 refactor(modules): remove the use of a macro to create a module 2022-11-13 21:33:54 +00:00
Joao Carreira aa2725e427 Merge branch 'master' into devel 2022-03-07 00:17:00 +00:00
Joao Carreira 8358ea0a3a Fix build on mac due to FFmpeg 2022-02-18 23:35:21 +00:00
jfmcarreira 8e15de8ce5 Merge branch 'master' into devel 2022-02-05 14:06:25 +00:00
jfmcarreira da40950ebe Minor changes in code format and repo 2022-02-05 14:06:09 +00:00
jfmcarreira 3380ad18b8 Work on resources 2022-02-05 14:01:20 +00:00
jfmcarreira d3c665605e Remove ivars that keep the active subwindow 2021-12-26 12:23:08 +00:00
jfmcarreira d01a91651b Finish refactor of load and format stream 2021-12-26 12:09:18 +00:00
jfmcarreira cd547a964b Fix keeping an history of open files 2021-12-25 02:51:02 +00:00
jfmcarreira f43e6e2634 Inital refactor to use resource independent from the video windows 2021-12-24 16:43:23 +00:00
jfmcarreira 7f8be0cb0e Merge branch 'master' into devel 2021-12-19 15:25:20 +00:00
jfmcarreira 17e2a6084a Fix resouce worker stop 2021-12-19 15:25:01 +00:00
jfmcarreira c1dd45662a Code formatting 2021-12-19 14:16:07 +00:00
jfmcarreira 77617ce53a Replace atomic_flag with plain atomic 2021-12-19 01:15:39 +00:00
jfmcarreira 6789ada346 Remove spin lock from the resource handler and avoid threads on a single frame stream 2021-12-19 00:55:42 +00:00
jfmcarreira f4c69fd894 Fix module tests 2021-12-18 23:53:10 +00:00
jfmcarreira c24ddcdc59 Cast to avoid recursion std::string 2021-12-18 23:44:54 +00:00
jfmcarreira 496bb54450 Fix scroll bug 2021-12-18 23:44:22 +00:00
jfmcarreira a048d2e0df Clean constructor of SubWindowAbstract 2021-12-18 23:42:40 +00:00
jfmcarreira 9d28051f38 Use std::span to give access to RGB buffer 2021-12-18 22:24:46 +00:00
jfmcarreira 8717338bf9 Modernise CalypModules factory 2021-12-18 22:24:03 +00:00
jfmcarreira 84865a039f Version bump 2.2.0 2021-12-05 00:41:03 +00:00
jfmcarreira 96b7576a1d Fix optional opencv dependency 2021-12-03 23:08:40 +00:00
jfmcarreira b61fd9d0e0 Remove type_safe library 2021-12-03 22:36:11 +00:00
jfmcarreira 5b4cdddde4 Disable DEBUG_ASSERT 2021-11-28 23:27:33 +00:00
jfmcarreira c43cb2bd0a Version bump 2.1.0 2021-11-28 20:36:33 +00:00
jfmcarreira e6970fb953 Fix windows build 2021-11-28 20:34:41 +00:00
jfmcarreira aac02a9959 Fix missing include 2021-11-28 18:23:05 +00:00
jfmcarreira 500e0e85ba Add macro to protect against the Qt version 2021-11-28 01:46:37 +00:00
jfmcarreira d4886a7fee Fix fetch content to build main product 2021-11-27 23:28:27 +00:00
jfmcarreira f3919ac8e8 Change cmake fetch content 2021-11-27 22:51:58 +00:00
jfmcarreira 562fd915fe Add build checks 2021-11-27 01:04:51 +00:00
jfmcarreira f3df40cdf7 Code cleanup 2021-11-27 00:52:32 +00:00
jfmcarreira 1bb2773abc Add support to filter components to display 2021-11-27 00:45:56 +00:00
jfmcarreira a5e0554286 Tidy up CalypFrame 2021-10-30 20:01:20 +01:00
jfmcarreira dc56de6f30 Fix memory leak in modules tests 2021-10-30 17:53:12 +01:00
jfmcarreira 0cc89ab949 Fix problem creating opencv mat from CalypFrame 2021-10-30 17:49:24 +01:00
jfmcarreira 480a7f1d38 Refactor ClpPixelFormats enum 2021-10-27 23:17:32 +01:00
jfmcarreira bb2a1ac228 Refactor pixel formats enum 2021-10-27 23:07:46 +01:00
jfmcarreira 90a5c32bb6 Fix option errors and add dummy module 2021-10-24 22:18:25 +01:00
jfmcarreira acc9d8ea98 Fix modules errors 2021-10-24 17:55:52 +01:00
jfmcarreira 6f91b6c04f Refactor CalypOption 2021-10-24 17:26:13 +01:00
jfmcarreira b1ca7dff0b Improve safety of class methods 2021-10-24 11:25:22 +01:00
jfmcarreira f5df1b3f9d Refactor code based on lib changes 2021-10-24 00:56:39 +01:00
jfmcarreira bd1bbef22b Fix CalypStream and CalypFrame methods 2021-10-23 23:38:03 +01:00
jfmcarreira 3a9aa5e498 Fix warnings and remove warnings are erros from tests checks 2021-10-20 00:54:10 +01:00
jfmcarreira 5499312fca Fix compilation erros 2021-10-20 00:28:49 +01:00
jfmcarreira 93cf60e34a Improvements on CalypModuleIf
Add type safe flags
Replace MACRO with templates (WIP)
2021-10-19 23:42:18 +01:00
jfmcarreira 09ec5213c3 Fix compilation errors and add new tests 2021-10-15 23:40:41 +01:00
jfmcarreira 26f3dc7612 Fix wrong filename in tests 2021-10-13 00:21:22 +01:00
jfmcarreira 6ce220be82 Check if file exists before running tests 2021-10-13 00:08:33 +01:00
jfmcarreira cc84c42fd4 Checkout LFS content for tests 2021-10-12 23:57:08 +01:00
jfmcarreira 8d2a9e6100 Fix build.yml 2021-10-12 21:10:56 +01:00
jfmcarreira c05aa73e86 Fix github action 2021-10-11 23:25:03 +01:00
jfmcarreira ddc9f40329 Fix repository with test data (fix last commit) 2021-10-11 23:14:10 +01:00
jfmcarreira e87049dccf Fix repository with test data 2021-10-11 23:12:50 +01:00
jfmcarreira 1c1afa7bfc Code clean up and add initial support to run tests in CI enviroment 2021-10-11 23:07:08 +01:00
jfmcarreira 366d69b5c9 Always use RAW format if first try to open file fails 2021-10-10 23:04:39 +01:00
jfmcarreira 26a718a06a Open .raw formats as raw video 2021-10-10 22:26:31 +01:00
jfmcarreira 3b31453221 Add support to signall if the format supports user configuration 2021-10-10 22:25:32 +01:00
jfmcarreira b7ad00a4c5 Minor refactor CalypStream header and format handler 2021-10-10 19:48:14 +01:00
jfmcarreira fbbd77bfbf Merge branch 'devel' 2021-10-10 18:05:23 +01:00
jfmcarreira be06ca656d Add new window classes for modules and streams 2021-10-10 15:13:42 +01:00
jfmcarreira 665cd0bb1c Add new window classes 2021-10-09 20:02:19 +01:00
jfmcarreira 1c0321a705 Fix histogram widget 2021-10-09 20:01:02 +01:00
jfmcarreira 5b9e16a708 Make CalypPixel work on stack 2021-10-09 18:31:21 +01:00
jfmcarreira 5b6d3e9031 Add iwyu 2021-10-03 19:19:21 +01:00
jfmcarreira 12c3b26580 appveyor: revert opencv dir change 2021-10-03 18:44:29 +01:00
jfmcarreira 574c712207 appveyor: Fix qt dll dir 2021-10-03 18:18:07 +01:00
jfmcarreira 4deef9e11c appveyor: fix Qt dir 2021-10-03 16:15:53 +01:00
jfmcarreira c7c8074cf8 appveyor: use visual studio 16 2019 generator 2021-10-03 16:02:06 +01:00
jfmcarreira a7ca36d252 appveyor: use latest cmake generator 2021-10-03 15:37:31 +01:00
jfmcarreira 8940ede351 appveyor: add executable name to the command 2021-10-03 15:34:05 +01:00
jfmcarreira b57e887d55 Fix last commit 2021-10-03 15:31:45 +01:00
jfmcarreira 3502b5df0d Fix script location in appveyor 2021-10-03 15:27:14 +01:00
jfmcarreira 15007d7784 Upgrade visual studio version in appveyor 2021-10-03 15:20:37 +01:00
jfmcarreira 9790ef3e31 Fix generator 2021-10-03 15:15:20 +01:00
jfmcarreira 5f0bdb30b5 Change CMake generator for appveyor 2021-10-03 14:48:15 +01:00
jfmcarreira 900c9c0418 Remove some files from the Calyp lib and clean up code 2021-10-03 14:30:15 +01:00
jfmcarreira 54f9f185e2 Add compile options and put Qt definitions in app CMakeLists 2021-10-03 14:13:02 +01:00
jfmcarreira dda88d8334 Fix c++20 compiler flag 2021-10-03 00:21:25 +01:00
jfmcarreira 73e5608624 Print the full log 2021-10-02 23:40:43 +01:00
jfmcarreira 317123c7b9 Remove flags not available on windows 2021-10-02 23:28:24 +01:00
jfmcarreira 0a40a8bdb6 Fix c++ flags for windows 2021-10-02 22:52:52 +01:00
jfmcarreira 5f66af794c Clean up code of HistogramWidget 2021-10-02 22:31:50 +01:00
jfmcarreira a6e1acd406 Update Cmake to fix config file 2021-10-02 22:29:51 +01:00
jfmcarreira 7818dbc9e3 Upate repo before install dependencies 2021-09-30 00:10:51 +01:00
jfmcarreira 448b64a8e3 Fix examples and tests 2021-09-30 00:06:57 +01:00
jfmcarreira 612f147639 Merge branch 'master' into devel 2021-09-29 23:37:30 +01:00
jfmcarreira 53bb100ad4 Fix bug removing a module 2021-09-29 23:36:53 +01:00
jfmcarreira d7b1d58b4b Merge branch 'master' into devel 2021-09-29 22:06:08 +01:00
jfmcarreira 58ce738026 Add devel build badge 2021-09-29 22:04:17 +01:00
jfmcarreira c8382ccaff Add github actions to devel 2021-09-28 01:21:39 +01:00
jfmcarreira 1a00bd328c Guard method position against Qt version 2021-09-28 01:13:55 +01:00
jfmcarreira 095d1863c2 Specify gcc-10 in the actions 2021-09-28 01:03:12 +01:00
jfmcarreira 3a56f532c1 Use GCC 10 in Github actions 2021-09-28 00:50:50 +01:00
jfmcarreira 2c89e47b8a Fix warnings to build with Werror flag 2021-09-28 00:38:33 +01:00
jfmcarreira 4aebcb979c Version bump 2.0.1 2021-09-26 01:13:24 +01:00
jfmcarreira f8aa92b7fa Remove C++20 methods not available on Windows 2021-09-26 01:11:44 +01:00
jfmcarreira a2f7f10fea Merge remote-tracking branch 'upstream/master' 2021-09-25 17:56:17 +01:00
jfmcarreira 223bd859a9 Version bump 2.0.0 2021-09-25 17:47:18 +01:00
jfmcarreira b148f28dab Update README.md 2021-09-25 17:44:23 +01:00
jfmcarreira b383eff34f Update CI and fix compilation errors on windows 2021-09-25 17:41:16 +01:00
jfmcarreira 1ec77b64c6 Merge remote-tracking branch 'upstream/master' 2021-09-25 17:25:24 +01:00
jfmcarreira 237bc1cc2e CI - Fix cmake config step 2021-09-25 17:20:38 +01:00
jfmcarreira d4913ed2d2 Update build.yml 2021-09-25 17:18:17 +01:00
jfmcarreira 113e86e583 Updata build action 2021-09-25 17:16:29 +01:00
jfmcarreira 9ea9d845c7 Update version CI config and README 2021-09-25 17:02:03 +01:00
jfmcarreira 48afd0be45 Remove the use of QRecursiveMutex 2021-09-22 01:20:01 +01:00
jfmcarreira 1e4de99fba Remove span include 2021-09-22 00:59:13 +01:00
jfmcarreira d446ee7ac1 Fix compiler flags 2021-09-22 00:31:45 +01:00
jfmcarreira 357971c68b Make the use of FetchContent optional 2021-09-21 22:31:08 +01:00
jfmcarreira 6be534d00c Fix warnings 2021-09-21 01:09:37 +01:00
jfmcarreira 437325c96f Clean up some redundant code 2021-09-20 01:51:54 +01:00
jfmcarreira 94444e38ec Refactor modules ownership 2021-09-19 21:50:15 +01:00
jfmcarreira a093efce9c Changes in CalypStream buffers 2021-09-18 16:26:14 +01:00
jfmcarreira de80c85596 Refactor the use of multiple threads for streams 2021-09-12 23:43:11 +01:00
jfmcarreira 9a63a57458 Reset window title when the last subwindow is closed 2021-09-12 14:35:44 +01:00
jfmcarreira 2451494677 Change CalypStream to RAII management with two buffers 2021-09-12 13:01:26 +01:00
jfmcarreira ffe1bf688d Improve the use of threads and sleep when not in use 2021-09-07 02:00:30 +01:00
jfmcarreira bf5235352b Start using resource handler to manage different streams 2021-09-06 22:43:21 +01:00
jfmcarreira 463e1a58b9 Make module instances unique ptrs 2021-09-04 13:57:12 +01:00
jfmcarreira 8ef5b31268 Reduce the use of C-pointers in CalypFrame and CalypStream 2021-07-10 16:28:10 +01:00
jfmcarreira be82c6ca89 Merge remote-tracking branch 'origin/devel' into devel 2021-07-10 12:40:25 +01:00
jfmcarreira eaa9987314 Change includes and minor fixes 2021-07-10 12:33:27 +01:00
jfmcarreira 304c0f6683 Fix the module skip while playing 2021-06-10 23:45:09 +01:00
jfmcarreira 83a9decc26 Remove compiler flag exclusively from MacOS 2021-06-10 11:32:20 +01:00
jfmcarreira 2a1b0abb2f Improve histogram drawing and refresh of module window
- Now histogram update if some windows is playing but not the current window
- If the current window is a module window it will check if the source
  window is playing
- The white fill of the window is only drawn after 500ms. Trying to
  reduce the continuous refreshing even on simple modules
2021-06-10 02:16:04 +01:00
jfmcarreira cad1f6d7a6 Merge branch 'feature/Vectorization' into devel 2021-06-07 00:22:16 +01:00
jfmcarreira d330ecfd0d Improve time critical functions in CalypFrame 2021-06-07 00:05:45 +01:00
jfmcarreira 7b5e5d5694 Add -O3 compiler optimisation option 2021-06-06 21:33:08 +01:00
jfmcarreira f2a636baa1 Add specific function to convert from YUV420 to RGB 2021-06-06 21:28:21 +01:00
jfmcarreira 9e3fb9c0a0 Fix threads for histogram and modules 2021-06-06 12:12:16 +01:00
jfmcarreira 420aeb89a6 Update qcustomplot to version 2.1.0 2021-05-31 03:10:02 +01:00
jfmcarreira a1b44895b8 For-loop clenups 2021-05-30 21:36:49 +01:00
jfmcarreira e1e5c4eb3c Add fps labels in the status bar 2021-05-30 20:48:55 +01:00
jfmcarreira 206613d08a Cleanups in CalypStream 2021-05-30 17:08:31 +01:00
jfmcarreira b7e8087163 Remove hard-coded frame rate in Raw video handler 2021-05-29 12:53:48 +01:00
jfmcarreira f4cf81b63c Make both google and catch2 test framework include in the project 2021-05-29 03:36:56 +01:00
jfmcarreira 47504ff46f Merge branch 'devel' 2021-05-29 03:16:43 +01:00
jfmcarreira bdc5317ccc Merge remote-tracking branch 'origin/devel' into devel 2021-05-29 03:16:30 +01:00
jfmcarreira 1dfddcf7fb Use threaded modules by default 2021-05-29 03:14:15 +01:00
jfmcarreira cea720f8e9 Improve the use of separate threads for each module
FramePropertiesDock now copies an instance of the CalypFrame that
is always kept valid until updated
2021-05-29 03:14:15 +01:00
jfmcarreira 48907ef614 Extend CalypFrame constructors
Add copy-assignement constructor
Add move and move assignement constructor
2021-05-29 03:14:15 +01:00
jfmcarreira cdff468904 Do not compensate flow if point outside the image 2021-05-29 03:14:15 +01:00
jfmcarreira dea3dd93d5 Add icon to MacOS build 2021-05-29 03:14:15 +01:00
jfmcarreira 3745a687cb Add missing header to QThread 2021-05-29 03:14:15 +01:00
jfmcarreira a1ebf62e21 Add Catch2 testing into the Calyp library 2021-05-29 03:14:15 +01:00
jfmcarreira 3c85c96769 Add modules to calyp 2021-05-29 03:14:15 +01:00
jfmcarreira e7e1a8534b Fix cmake warnings for devs 2021-05-29 03:14:15 +01:00
João Carreira 8807c14b59 Ignore any build dir starting with build-* 2021-05-29 03:14:15 +01:00
jfmcarreira 039887f2e6 Fix deprecated Qt functions
Change the way to get the screen size
Remove Qt::WindowFlags
Change function to process events from mouse wheel
2021-05-29 03:14:15 +01:00
jfmcarreira 4c6a4aba65 Remove deprecated av_register_all() 2021-05-29 03:14:15 +01:00
jfmcarreira 910ab8024e Add GitHub action to build code using cmake 2021-05-29 03:14:15 +01:00
jfmcarreira 6b0f7f6de3 Fix missing include in the windows build
Add missing QStyleFactory include
Minor version bump
2021-05-29 03:14:15 +01:00
jfmcarreira 6b8b4cbb6a Bump version 2021-05-29 03:14:15 +01:00
jfmcarreira 0a70267ab7 Add details to about dialog and change theme for windows 2021-05-29 03:14:15 +01:00
jfmcarreira 4a4f985ac1 Define style on windows 2021-05-29 03:14:15 +01:00
jfmcarreira 58424b8f4e Update last commit 2021-05-29 03:14:15 +01:00
jfmcarreira 3bbbf81ca2 Remove ffmpeg exe before building against it 2021-05-29 03:14:15 +01:00
jfmcarreira 7ea1db3202 Change ffmpeg installation on windows 2021-05-29 03:14:15 +01:00
jfmcarreira 0e26fd8964 Add libswresample to FindFFmpeg 2021-05-29 03:14:15 +01:00
jfmcarreira 27ecd818e8 Complete ffmpeg def in appveyor
Add missing variable definitions for avdevice and postproc library
Define variable FFMPEG_DIR
2021-05-29 03:14:15 +01:00
jfmcarreira d5d21a458f Remove testing from travis ci 2021-05-29 03:14:15 +01:00
jfmcarreira 1066aaa73c Add missing dependency to gtest in travis env 2021-05-29 03:14:15 +01:00
jfmcarreira ddd5eeb6b9 Revert changes to travis CI 2021-05-29 03:14:15 +01:00
jfmcarreira 876e1ba9e3 Use threaded modules by default 2021-05-29 03:13:49 +01:00
jfmcarreira 47dd2ad3f9 Improve the use of separate threads for each module
FramePropertiesDock now copies an instance of the CalypFrame that
is always kept valid until updated
2021-05-29 03:13:49 +01:00
jfmcarreira e77e0a82fa Extend CalypFrame constructors
Add copy-assignement constructor
Add move and move assignement constructor
2021-05-29 03:13:49 +01:00
jfmcarreira 2181fd6add Do not compensate flow if point outside the image 2021-05-29 03:13:49 +01:00
jfmcarreira eda28d1380 Add icon to MacOS build 2021-05-29 03:13:49 +01:00
jfmcarreira 1599a80d46 Add missing header to QThread 2021-05-29 03:13:49 +01:00
jfmcarreira 42c4e3b388 Use threaded modules by default 2021-05-29 03:13:22 +01:00
jfmcarreira d86ed3508b Improve the use of separate threads for each module
FramePropertiesDock now copies an instance of the CalypFrame that
is always kept valid until updated
2021-05-29 03:08:56 +01:00
jfmcarreira cd18227b8b Extend CalypFrame constructors
Add copy-assignement constructor
Add move and move assignement constructor
2021-05-29 03:05:55 +01:00
jfmcarreira fc913fdc08 Do not compensate flow if point outside the image 2021-05-29 03:02:53 +01:00
jfmcarreira f90c681788 Add icon to MacOS build 2021-05-29 00:41:52 +01:00
jfmcarreira 44f7a9b02e Add missing header to QThread 2021-05-28 19:11:49 +01:00
jfmcarreira 624612d49b Merge branch 'devel' 2021-05-09 23:25:13 +01:00
jfmcarreira 70db70a7cf Add Catch2 testing into the Calyp library 2021-05-09 23:24:16 +01:00
jfmcarreira 33bf02ba0f Add modules to calyp 2021-05-08 22:56:07 +01:00
jfmcarreira 864c3253f1 Fix cmake warnings for devs 2021-05-03 01:31:21 +01:00
João Carreira a2d452fd64 Ignore any build dir starting with build-* 2021-05-02 23:23:42 +01:00
jfmcarreira 3732810f9e Fix deprecated Qt functions
Change the way to get the screen size
Remove Qt::WindowFlags
Change function to process events from mouse wheel
2021-05-01 01:35:28 +01:00
jfmcarreira 56fc2e45bb Remove deprecated av_register_all() 2021-05-01 01:34:38 +01:00
jfmcarreira 7ff939c33a Fix missing include in the windows build
Add missing QStyleFactory include
Minor version bump
2021-04-17 23:18:39 +01:00
jfmcarreira fa23256955 Add GitHub action to build code using cmake 2021-04-17 18:33:13 +01:00
jfmcarreira ffe0c38427 Bump version 2021-04-17 18:29:08 +01:00
jfmcarreira 12bd1a4c2c Add details to about dialog and change theme for windows 2021-04-17 18:27:47 +01:00
jfmcarreira b830b700ca Define style on windows 2021-04-17 12:59:55 +01:00
jfmcarreira 3109250471 Update last commit 2021-04-17 02:19:07 +01:00
jfmcarreira c6b43ac7fa Remove ffmpeg exe before building against it 2021-04-17 02:09:27 +01:00
jfmcarreira beed955e3f Change ffmpeg installation on windows 2021-04-17 01:57:27 +01:00
jfmcarreira 1f003ec2ac Add libswresample to FindFFmpeg 2021-04-17 01:22:34 +01:00
jfmcarreira c718d01700 Complete ffmpeg def in appveyor
Add missing variable definitions for avdevice and postproc library
Define variable FFMPEG_DIR
2021-04-17 00:44:34 +01:00
jfmcarreira 847f4f06b9 Remove testing from travis ci 2021-04-16 22:47:07 +01:00
jfmcarreira 344188234b Add missing dependency to gtest in travis env 2021-04-16 22:25:40 +01:00
jfmcarreira 5439fd1af5 Revert changes to travis CI 2021-04-07 15:56:57 +01:00
jfmcarreira 2f434d269b Run tests in travisCI 2021-04-06 22:58:20 +01:00
jfmcarreira a72208f0e6 Remove unused file and update .gitignore 2021-04-06 22:57:31 +01:00
jfmcarreira c3c4e229d8 Tests: Add general tests for modules
The idea of these tests is to check whether the modules will work
with different kinds of inputs. The modules should be able to initialize
or return an error indication. But in all cases they should be able to handle
default arguments all different inputs
2021-04-06 22:57:12 +01:00
jfmcarreira fedcb2e03a Add pre-commit checks and reformat code 2021-02-14 01:39:41 +00:00
jfmcarreira e755608b02 Merge branch 'master' into devel 2021-02-14 01:35:55 +00:00
jfmcarreira 2debe78ed8 Refactoring lib CMakeLists.txt 2021-02-14 00:51:21 +00:00
jfmcarreira 4d1730f928 Explicitly use static library for modules 2021-02-13 23:49:36 +00:00
jfmcarreira 521e56202c Remove clang-tidy 2021-02-13 04:16:25 +00:00
jfmcarreira d0933f43c9 Add cmake and clang format and linter 2021-02-13 04:08:43 +00:00
jfmcarreira 1674ec4061 Add missing information 2021-02-13 03:40:56 +00:00
jfmcarreira ab58ca44f2 Fix copyright 2021-02-13 03:16:17 +00:00
jfmcarreira 11bf3f6bfd Format code 2021-02-13 03:12:28 +00:00
jfmcarreira 669f3db250 Add modules test for create operation 2021-02-13 02:27:39 +00:00
jfmcarreira 3c6e0555bc Update doc and gitignore 2021-02-13 02:26:39 +00:00
jfmcarreira fca79a7992 Add cmake variable to define test data location 2021-02-13 02:07:43 +00:00
jfmcarreira b507b61ce4 Pre fill configuration dialog with the last used values 2021-02-02 00:03:29 +00:00
jfmcarreira 72bfaf6796 Update github token 2020-12-18 22:39:05 +00:00
jfmcarreira 0998d98375 Fix 7z extract command 2020-12-18 20:28:54 +00:00
jfmcarreira 3afa6eeb6f Run extract ffmpeg script 2020-12-18 20:18:18 +00:00
jfmcarreira 41c65dcac4 Fix ffmpeg download for appveyor windows build 2020-12-16 02:58:02 +00:00
jfmcarreira 25d40cadbe Merge remote-tracking branch 'upstream/master' 2020-12-12 13:20:14 +00:00
jfmcarreira ca68f5a78f Remove IDE related files 2020-12-12 13:18:48 +00:00
Joao Santos f2e1e4bfc7 Removed decimal places from the median value. 2020-12-12 13:11:09 +00:00
Joao Santos b5edc60794 Added option to print statistics to calypTools. 2020-12-12 13:08:53 +00:00
Joao Santos 6b084c1a7e Fixed minor issue with getEntropy function. 2020-12-12 13:06:52 +00:00
jfmcarreira 7b712bb232 Fix parsing cli args in Calyp 2020-12-12 11:05:39 +00:00
jfmcarreira 684cecd632 Minor bug fixes in the help of calypTools 2020-12-11 18:00:12 +00:00
Joao Santos f6cc0ffd29 The entropy of the image was added to the statistics. 2020-12-10 17:16:38 +00:00
jfmcarreira c1cef58de1 Fix extract command in appveyor 2020-10-24 00:08:55 +01:00
jfmcarreira f9e62c73ac Update appveyor to fetch ffmpeg from a new source 2020-10-23 23:13:02 +01:00
jfmcarreira 6486104db2 Minor changes in optimise display 2020-10-23 18:36:52 +01:00
206 changed files with 18768 additions and 6872 deletions

No files matched your search

+17 -16
View File
@@ -1,45 +1,46 @@
image: Visual Studio 2017
image: Visual Studio 2019
configuration: Release
platform:
- x64
environment:
access_token:
secure: WAV5LfCSAtwE1JuZh4HrDlxOOClimLoslYAJlf5KRgc3f7WIkX591PrSSua/Zo2C
secure: SMxOWNKN0RkPvICWhIet2FJM5g/zx5mguM/XAPjM2OrC3U2/LAqcBZw0veS9peS4
clone_folder: C:\Projects\calyp
init:
- ps: Add-Content "$HOME\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n"
- git config --global credential.helper store
- git config --global user.email "jfmcarreira@gmail.com"
- git config --global user.name "AppVeyor"
- git config --global user.name "AppVeyor"
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
install:
- '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64'
#- '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64'
- '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64'
- choco install nsis
- choco install opencv
- 'C:\Tools\opencv\build\setup_vars_opencv4.cmd'
- cd C:\Projects
- ps: Start-FileDownload 'https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.1.1-win64-dev.zip'
- 7z x ffmpeg-4.1.1-win64-dev.zip -y
- ps: Start-FileDownload 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full-shared.7z' ffmpeg.7z
- 7z x ffmpeg.7z -y -offmpeg
- git clone https://github.com/pixlra/calyp-deployment.git
- CALL calyp-deployment/scripts/extract_ffmpeg.bat
- ps: rm C:\Projects\ffmpeg_libraries\bin\*.exe
build_script:
- mv C:\Projects\calyp C:\Projects\calyp-deployment\cmake-helper\
- mkdir C:\Projects\calyp-build
- cd C:\Projects\calyp-build
- cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DUSE_DYNLOAD=OFF -DOpenCV_DIR="C:/Tools/opencv/build" -DOpenCV_DLL_DIR="C:/Tools/opencv/build/x64/vc15/bin" -DOpenCV_INSTALL_MODULES="world" -DQT_DIR="C:\Qt\latest\msvc2017_64" -DQt5_DIR="C:\Qt\latest\msvc2017_64\lib\cmake\Qt5" -DUSE_QTDBUS=OFF -DAVFORMAT_LIBRARIES=C:/Projects/ffmpeg-4.1.1-win64-dev/lib/avformat.lib -DAVFORMAT_INCLUDE_DIRS=C:/Projects/ffmpeg-4.1.1-win64-dev/include -DAVCODEC_LIBRARIES=C:/Projects/ffmpeg-4.1.1-win64-dev/lib/avcodec.lib -DAVCODEC_INCLUDE_DIRS=C:/Projects/ffmpeg-4.1.1-win64-dev/include -DAVUTIL_LIBRARIES=C:/Projects/ffmpeg-4.1.1-win64-dev/lib/avutil.lib -DAVUTIL_INCLUDE_DIRS=C:/Projects/ffmpeg-4.1.1-win64-dev/include -DSWSCALE_LIBRARIES=C:/Projects/ffmpeg-4.1.1-win64-dev/lib/swscale.lib -DSWSCALE_INCLUDE_DIRS=C:/Projects/ffmpeg-4.1.1-win64-dev/include -G "Visual Studio 15 2017 Win64" C:\Projects\calyp-deployment\cmake-helper
- cmake --build . --target ALL_BUILD -- /p:Configuration=Release > log_build
- cmake --build . --target INSTALL -- /p:Configuration=Release > log_install
- cmake --build . --target PACKAGE -- /p:Configuration=Release > log_pkg
- cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install -DUSE_DYNLOAD=OFF -DOpenCV_DIR="C:/Tools/opencv/build" -DOpenCV_DLL_DIR="C:/Tools/opencv/build/x64/vc15/bin" -DOpenCV_INSTALL_MODULES="world" -DQT_DIR="C:\Qt\latest\msvc2019_64" -DQt5_DIR="C:\Qt\latest\msvc2019_64\lib\cmake\Qt5" -DUSE_QTDBUS=OFF -DAVFORMAT_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/avformat.lib -DAVFORMAT_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DAVCODEC_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/avcodec.lib -DAVCODEC_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DAVUTIL_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/avutil.lib -DAVUTIL_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DSWSCALE_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/swscale.lib -DSWSCALE_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DAVDEVICE_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/avdevice.lib -DAVDEVICE_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DPOSTPROC_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/postproc.lib -DPOSTPROC_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -DFFMPEG_DIR=C:\Projects\ffmpeg_libraries -DSWRESAMPLE_LIBRARIES=C:/Projects/ffmpeg_libraries/lib/swresample.lib -DSWRESAMPLE_INCLUDE_DIRS=C:/Projects/ffmpeg_libraries/include -G "Visual Studio 16 2019" -A x64 C:\Projects\calyp-deployment\cmake-helper
- cmake --build . --target ALL_BUILD -- /p:Configuration=Release
- cmake --build . --target INSTALL -- /p:Configuration=Release
- cmake --build . --target PACKAGE -- /p:Configuration=Release
after_build:
- IF "%APPVEYOR_REPO_BRANCH%" == "master" (CALL ..\calyp-deployment\scripts\deploy-to-github.bat)
on_failure:
- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+37 -38
View File
@@ -1,19 +1,19 @@
---
BasedOnStyle: Google
Language: Cpp
ColumnLimit: 0
BasedOnStyle: Google
Language: Cpp
ColumnLimit: 120
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
@@ -21,17 +21,17 @@ AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterNamespace: true
AfterClass: true
AfterEnum: true
AfterFunction: true
AfterStruct: true
AfterUnion: true
AfterControlStatement: true
AfterObjCDeclaration: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
AfterNamespace: true
AfterClass: true
AfterEnum: true
AfterFunction: true
AfterStruct: true
AfterUnion: true
AfterControlStatement: true
AfterObjCDeclaration: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBraces: Custom
BreakBeforeBinaryOperators: None
BreakBeforeInheritanceComma: false
@@ -40,31 +40,31 @@ BreakConstructorInitializersBeforeComma: true
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
CommentPragmas: '^ IWYU pragma:'
CommentPragmas: "^ IWYU pragma:"
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH]
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
- Regex: '^<.*\.h>'
Priority: 1
- Regex: "^<.*"
Priority: 2
- Regex: ".*"
Priority: 3
IncludeIsMainRegex: "([-_](test|unittest))?$"
IndentCaseLabels: false
IndentWidth: 2
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
@@ -77,21 +77,20 @@ PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
ReflowComments: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SortIncludes: true
SortIncludes: true
SpacesInParentheses: true
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 2
UseTab: Never
...
Standard: Auto
TabWidth: 2
UseTab: Never
---
+66
View File
@@ -0,0 +1,66 @@
---
Checks: "*,-modernize-use-nodiscard,-llvmlibc-*,-fuchsia-trailing-return,-fuchsia*,-altera-*,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-implicit-widening-of-multiplication-result,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers, -readability-identifier-length"
WarningsAsErrors: ""
HeaderFilterRegex: ""
FormatStyle: file
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.ClassMemberCase
value: camelBack
- key: readability-identifier-naming.ClassMethodCase
value: camelBack
- key: readability-identifier-naming.ParameterCase
value: camelBack
- key: readability-identifier-naming.PrivateMemberCase
value: camelBack
- key: readability-identifier-naming.PrivateMemberPrefix
value: m_
- key: readability-identifier-length.IgnoredVariableNames
value: "^(id|to)$"
- key: llvm-else-after-return.WarnOnConditionVariables
value: "0"
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons
value: "0"
- key: google-readability-namespace-comments.ShortNamespaceLines
value: "10"
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: "0"
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: "1"
- key: cert-dcl16-c.NewSuffixes
value: "L;LL;LU;LLU"
- key: google-readability-braces-around-statements.ShortStatementLines
value: "1"
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: google-readability-namespace-comments.SpacesBeforeComments
value: "2"
- key: modernize-loop-convert.MaxCopySize
value: "16"
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: "1"
- key: modernize-use-nullptr.NullMacros
value: "NULL"
- key: llvm-qualified-auto.AddConstToQualified
value: "0"
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: llvm-else-after-return.WarnOnUnfixable
value: "0"
- key: google-readability-function-size.StatementThreshold
value: "800"
- key: readability-magic-numbers.IgnorePowersOf2IntegerValues
value: "1"
- key: readability-braces-around-statements.ShortStatementLines
value: "1"
- key: google-readability-braces-around-statements.ShortStatementLines
value: "1"
- key: hicpp-braces-around-statements.ShortStatementLines
value: "1"
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: "1"
+117
View File
@@ -0,0 +1,117 @@
# ----------------------------------
# Options affecting listfile parsing
# ----------------------------------
with section("parse"):
# Specify structure for custom cmake functions
additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'],
'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}}
## Override configurations per-command where available
#override_spec = {}
# Specify variable tags.
vartags = []
# Specify property tags.
proptags = []
# -----------------------------
# Options affecting formatting.
# -----------------------------
with section("format"):
# How wide to allow formatted cmake files
line_width = 150
# How many spaces to tab for indent
tab_size = 2
# If an argument group contains more than this many sub-groups (parg or kwarg
# groups) then force it to a vertical layout.
max_subgroups_hwrap = 2
# If a positional argument group contains more than this many arguments, then
# force it to a vertical layout.
max_pargs_hwrap = 6
dangle_parens = True
# Format command names consistently as 'lower' or 'upper' case
command_case = 'upper'
# Format keywords consistently as 'lower' or 'upper' case
keyword_case = 'upper'
# ----------------------------
# Options affecting the linter
# ----------------------------
with section("lint"):
# a list of lint codes to disable
disabled_codes = ["C0103"]
# regular expression pattern describing valid function names
function_pattern = '[0-9a-z_]+'
# regular expression pattern describing valid macro names
macro_pattern = '[0-9A-Z_]+'
# regular expression pattern describing valid names for variables with global
# (cache) scope
global_var_pattern = '[A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for variables with global
# scope (but internal semantic)
internal_var_pattern = '_[A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for variables with local
# scope
local_var_pattern = '[a-z][a-z0-9_]+'
# regular expression pattern describing valid names for privatedirectory
# variables
private_var_pattern = '_[0-9a-z_]+'
# regular expression pattern describing valid names for public directory
# variables
public_var_pattern = '[A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for function/macro
# arguments and loop variables.
argument_var_pattern = '[a-z][a-z0-9_]+'
# regular expression pattern describing valid names for keywords used in
# functions or macros
keyword_pattern = '[A-Z][0-9A-Z_]+'
# In the heuristic for C0201, how many conditionals to match within a loop in
# before considering the loop a parser.
max_conditionals_custom_parser = 2
# Require at least this many newlines between statements
min_statement_spacing = 1
# Require no more than this many newlines between statements
max_statement_spacing = 2
max_returns = 6
max_branches = 12
max_arguments = 5
max_localvars = 15
max_statements = 50
# -------------------------------
# Options affecting file encoding
# -------------------------------
with section("encode"):
# If true, emit the unicode byte-order mark (BOM) at the start of the file
emit_byteorder_mark = False
# Specify the encoding of the input file. Defaults to utf-8
input_encoding = 'utf-8'
# Specify the encoding of the output file. Defaults to utf-8. Note that cmake
# only claims to support utf-8 so be careful when using anything else
output_encoding = 'utf-8'
+92
View File
@@ -0,0 +1,92 @@
name: Build/Test Pipeline
on:
push:
branches:
- master
- devel
pull_request:
branches: [master]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
check-build-linux:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-24.04
name: Build (Linux)
steps:
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install cmake qtbase5-dev libavcodec-dev libavformat-dev libavutil-dev libopencv-dev libopencv-video-dev libopencv-contrib-dev
- uses: actions/checkout@v4
- name: Build with default options
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_WERROR=ON
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Build without threads
run: |
cmake -B ${{github.workspace}}/build-without-thread -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_WERROR=ON -DCALYP_MANAGED_RESOURCES=OFF -DCALYP_THREADED_MODULES=OFF
cmake --build ${{github.workspace}}/build-without-thread --config ${{env.BUILD_TYPE}}
- name: Build without dependencies
run: |
cmake -B ${{github.workspace}}/build-without-deps -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_WERROR=ON -DUSE_OPENCV=OFF -DUSE_FFMPEG=OFF
cmake --build ${{github.workspace}}/build-without-deps --config ${{env.BUILD_TYPE}}
- name: Install Qt&
run: sudo apt-get install qt6-base-dev
- name: Build with Qt& (autodetect)
run: |
cmake -B ${{github.workspace}}/build-qt6 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_WERROR=ON
cmake --build ${{github.workspace}}/build-qt6 --config ${{env.BUILD_TYPE}}
check-build-macos:
name: Build (macOS)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: brew install cmake qt opencv ffmpeg
- name: Build with default options
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_WERROR=ON
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
check-tests-linux:
name: Tests (Linux)
runs-on: ubuntu-24.04
needs: check-build-linux
steps:
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install cmake qtbase5-dev qt6-base-dev libavcodec-dev libavformat-dev libavutil-dev libopencv-dev libopencv-video-dev libopencv-contrib-dev
- uses: actions/checkout@v4
- name: Check out tests data
uses: actions/checkout@master
with:
repository: "pixlra/calyp-testdata"
path: ${{github.workspace}}/tests_data
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON -DCALYP_TEST_DATA_DIR=${{github.workspace}}/tests_data
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: CalypLib tests
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t test
+17 -1
View File
@@ -1,9 +1,13 @@
# Created by https://www.gitignore.io/api/c++,clion,linux
# Edit at https://www.gitignore.io/?templates=c++,clion,linux
deps/**
templates/**
### C++ ###
# Prerequisites
*.d
# Clang
.cache/
# Compiled Object files
*.slo
@@ -74,6 +78,7 @@
# CMake
bin/
build/
build-*
cmake-build-*/
# Mongo Explorer plugin
@@ -132,4 +137,15 @@ fabric.properties
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# End of https://www.gitignore.io/api/c++,clion,linux
### vscode ###
.vscode/*
*.code-workspace
# Documentation
doc/
# CLang
compile_commands.json
# Build dirs
build*
-2
View File
@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/calyp.iml" filepath="$PROJECT_DIR$/.idea/calyp.iml" />
</modules>
</component>
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+29
View File
@@ -0,0 +1,29 @@
fail_fast: false
repos:
- repo: https://github.com/cheshirekow/cmake-format-precommit
rev: v0.6.10
hooks:
- id: cmake-format
- id: cmake-lint
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.1.1
hooks:
- id: clang-format
args: [--style=file, -i]
- repo: local
hooks:
- id: cmake-configure
name: Cmake Configure
entry: cmake -B build
pass_filenames: false
language: system
#- id: cmake-build
#name: Cmake Build
#entry: cmake --build build
#pass_filenames: false
#language: system
+2 -2
View File
@@ -1,7 +1,7 @@
language: cpp
dist: xenial
dist: bionic
before_install:
- sudo apt-get -qq update
- sudo apt-get install build-essential cmake qtbase5-dev libavcodec-dev libavformat-dev libavutil-dev libopencv-dev libopencv-video-dev libopencv-contrib-dev
- sudo apt-get install build-essential cmake qtbase5-dev libavcodec-dev libavformat-dev libavutil-dev libopencv-dev libopencv-video-dev libopencv-contrib-dev libgtest-dev
script:
- mkdir -p build && cd build && cmake .. && make && cd ..
+224 -157
View File
@@ -1,240 +1,307 @@
###
### CMakeLists for calyp
###
#
# CMakeLists for calyp
#
cmake_minimum_required( VERSION 3.2.0 )
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.0)
######################################################################################
# ####################################################################################################################################################
# Project Definition
# ####################################################################################################################################################
SET(PROJECT_NAME
"calyp"
CACHE INTERNAL "" FORCE
)
SET(PROJECT_LIBRARY
"Calyp"
CACHE INTERNAL "" FORCE
)
SET(CALYP_VERSION_MAJOR "2")
SET(CALYP_VERSION_MINOR "2")
SET(CALYP_VERSION_PATCH "0")
SET(CALYP_VERSION
"${CALYP_VERSION_MAJOR}.${CALYP_VERSION_MINOR}.${CALYP_VERSION_PATCH}"
CACHE INTERNAL "" FORCE
)
PROJECT(
${PROJECT_NAME}
VERSION ${CALYP_VERSION}
LANGUAGES "CXX"
)
# ####################################################################################################################################################
# CMake functions
######################################################################################
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
INCLUDE( cmake/ModulesFct.cmake )
# ####################################################################################################################################################
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
INCLUDE(cmake/ModulesFct.cmake)
INCLUDE(FeatureSummary)
INCLUDE(GNUInstallDirs)
######################################################################################
# Project Definition
######################################################################################
SET( PROJECT_NAME "calyp" CACHE INTERNAL "" FORCE )
SET( PROJECT_LIBRARY "Calyp" CACHE INTERNAL "" FORCE )
PROJECT( ${PROJECT_NAME} )
SET( CALYP_VERSION_MAJOR "1" )
SET( CALYP_VERSION_MINOR "1" )
SET( CALYP_VERSION_PATCH "0" )
SET( CALYP_VERSION "${CALYP_VERSION_MAJOR}.${CALYP_VERSION_MINOR}.${CALYP_VERSION_PATCH}" CACHE INTERNAL "" FORCE )
######################################################################################
# ####################################################################################################################################################
# Variables
######################################################################################
# ####################################################################################################################################################
OPTION( BUILD_APP "Build GUI Application" ON )
OPTION( BUILD_TOOLS "Build Command Line Application" ON )
OPTION( BUILD_EXAMPLES "Build Examples" OFF )
OPTION( BUILD_DOC "Build Documentation" OFF )
OPTION( BUILD_TESTS "Build Google Tests" OFF )
OPTION(BUILD_APP "Build GUI Application" ON)
OPTION(BUILD_TOOLS "Build Command Line Application" ON)
OPTION(BUILD_EXAMPLES "Build Examples" OFF)
OPTION(BUILD_DOC "Build Documentation" OFF)
OPTION(BUILD_TESTS "Build Tests" OFF)
OPTION(BUILD_WITH_SANITIZERS "Build with sanitizers" OFF)
OPTION(BUILD_WITH_THREAD_SANITIZER "Build with thread sanitizer" OFF)
OPTION( USE_FERVOR "Add Fervor support" OFF )
OPTION(USE_FERVOR "Add Fervor support" OFF)
OPTION( USE_DYNLOAD "Use dynamic load of modules" ON )
OPTION( USE_SSE "Build with SSE support" OFF )
OPTION( USE_WERROR "Warnings as errors" OFF )
OPTION( USE_STATIC "Use static libs" OFF )
OPTION(USE_DYNLOAD "Use dynamic load of modules" ON)
OPTION(USE_SSE "Build with SSE support" ON)
OPTION(USE_WERROR "Warnings as errors" OFF)
OPTION(USE_STATIC "Use static libs" OFF)
OPTION(USE_IWYU "Use include what you use tool" OFF)
######################################################################################
# ####################################################################################################################################################
# Release configuration
######################################################################################
# ####################################################################################################################################################
# To be switched on when releasing.
OPTION(RELEASE_BUILD "Remove Git revision from program version (use for stable releases)" ON)
# Get current version.
set(CALYP_VERSION_STRING "${CALYP_VERSION}")
if(NOT RELEASE_BUILD AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
SET(CALYP_VERSION_STRING "${CALYP_VERSION}")
IF(NOT RELEASE_BUILD AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
# Probably a Git workspace; determine the revision.
FIND_PACKAGE(Git QUIET)
if(GIT_FOUND)
exec_program(${GIT_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}
IF(GIT_FOUND)
EXEC_PROGRAM(
${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}
ARGS "describe --tags"
OUTPUT_VARIABLE CALYP_GIT_REVISION
RETURN_VALUE TAG_RESULT
)
# git describe --tags failed; maybe the repository was checked with depth=1.
if(NOT ${TAG_RESULT} EQUAL 0)
exec_program(${GIT_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}
IF(NOT ${TAG_RESULT} EQUAL 0)
EXEC_PROGRAM(
${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}
ARGS "describe --always"
OUTPUT_VARIABLE CALYP_GIT_REVISION
)
endif()
message(STATUS "Calyp Git revision: ${CALYP_GIT_REVISION}")
set(CALYP_VERSION_STRING "${CALYP_VERSION} (rev. ${CALYP_GIT_REVISION})")
else()
message(STATUS "Calyp Git revision could not be determined")
endif()
endif()
ENDIF()
MESSAGE(STATUS "Calyp Git revision: ${CALYP_GIT_REVISION}")
SET(CALYP_VERSION_STRING "${CALYP_VERSION} (rev. ${CALYP_GIT_REVISION})")
ELSE()
MESSAGE(STATUS "Calyp Git revision could not be determined")
ENDIF()
ENDIF()
SET(UPDATE_CHANNEL "stable" CACHE STRING "Update channel" )
SET(UPDATE_CHANNEL
"stable"
CACHE STRING "Update channel"
)
# CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/CalypUpdate.xml.in ${CMAKE_CURRENT_BINARY_DIR}/CalypUpdate-${UPDATE_CHANNEL}.xml )
######################################################################################
# ####################################################################################################################################################
# Dependencies
######################################################################################
# ####################################################################################################################################################
INCLUDE(FetchContent)
IF( BUILD_DOC )
SET(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/deps")
# Doxygen
IF(BUILD_DOC)
FIND_PACKAGE(Doxygen)
SET( BUILD_DOC ${Doxygen_FOUND} )
SET(BUILD_DOC ${Doxygen_FOUND})
ENDIF()
SET_PACKAGE_PROPERTIES(Doxygen PROPERTIES URL "http://www.doxygen.org/" DESCRIPTION "Doxygen" TYPE OPTIONAL)
SET_PACKAGE_PROPERTIES(
Doxygen PROPERTIES
URL "http://www.doxygen.org/"
DESCRIPTION "Doxygen"
TYPE OPTIONAL
)
# Catch2 and Google Tests
IF(BUILD_TESTS)
FETCHCONTENT_DECLARE(googletest URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip)
# For Windows: Prevent overriding the parent project's compiler/linker settings
SET(gtest_force_shared_crt
ON
CACHE BOOL "" FORCE
)
FETCHCONTENT_DECLARE(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.3.2
)
IF( BUILD_TESTS )
FIND_PACKAGE(GTest)
SET( BUILD_DOC ${GTEST_FOUND} )
IF( GTEST_FOUND )
ENABLE_TESTING()
INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
ENDIF()
SET_PACKAGE_PROPERTIES(
googletest PROPERTIES
URL "https://github.com/google/googletest"
DESCRIPTION "Google unit tests"
TYPE OPTIONAL
)
SET_PACKAGE_PROPERTIES(
Catch2 PROPERTIES
URL "https://github.com/catchorg/Catch2"
DESCRIPTION "Catch2 unit tests"
TYPE OPTIONAL
)
FETCHCONTENT_MAKEAVAILABLE(googletest Catch2)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}/deps/catch2-src/extras)
INCLUDE(CTest)
INCLUDE(Catch)
ENABLE_TESTING()
SET(CALYP_TEST_DATA_DIR
"CALYP_TEST_DATA_DIR"
CACHE PATH "Location of video information for testing"
)
ENDIF()
OPTION( USE_OPENCV "Add OpenCV support" ON )
IF( USE_OPENCV )
# OpenCV
OPTION(USE_OPENCV "Add OpenCV support" ON)
IF(USE_OPENCV)
FIND_PACKAGE( OpenCV COMPONENTS core highgui imgproc video )
IF( ${OpenCV_FOUND} )
SET(USE_OPENCV TRUE )
LIST(APPEND OPENCV_MODULES core highgui imgproc video )
FIND_PACKAGE( OpenCV COMPONENTS videoio photo )
IF( ${OPENCV_VIDEOIO_FOUND} )
LIST(APPEND OPENCV_MODULES videoio )
FIND_PACKAGE(OpenCV COMPONENTS core highgui imgproc video)
IF(${OpenCV_FOUND})
SET(USE_OPENCV TRUE)
LIST(APPEND OPENCV_MODULES core highgui imgproc video)
FIND_PACKAGE(OpenCV COMPONENTS videoio photo)
IF(${OPENCV_VIDEOIO_FOUND})
LIST(APPEND OPENCV_MODULES videoio)
ENDIF()
IF( ${OPENCV_PHOTO_FOUND} )
LIST(APPEND OPENCV_MODULES photo )
IF(${OPENCV_PHOTO_FOUND})
LIST(APPEND OPENCV_MODULES photo)
ENDIF()
ELSE()
SET(USE_OPENCV FALSE )
SET(USE_OPENCV FALSE)
ENDIF()
ENDIF()
SET_PACKAGE_PROPERTIES(OpenCV PROPERTIES URL "http://opencv.willowgarage.com" DESCRIPTION "OpenCV library support in CalypFrame" TYPE OPTIONAL)
SET_PACKAGE_PROPERTIES(
OpenCV PROPERTIES
URL "http://opencv.willowgarage.com"
DESCRIPTION "OpenCV library support in CalypFrame"
TYPE OPTIONAL
)
OPTION( USE_FFMPEG "Add FFMPEG support" ON )
IF( USE_FFMPEG )
FIND_PACKAGE( FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE )
IF( "${AVCODEC_VERSION}" VERSION_LESS "56.0.0" )
SET(FFMPEG_FOUND FALSE )
SET(FFmpeg_FOUND FALSE )
ENDIF()
# FFmpeg
OPTION(USE_FFMPEG "Add FFMPEG support" ON)
IF(USE_FFMPEG)
FIND_PACKAGE(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
SET(USE_FFMPEG ${FFMPEG_FOUND})
ENDIF()
SET_PACKAGE_PROPERTIES(FFmpeg PROPERTIES URL "http://ffmpeg.org/" DESCRIPTION "Libav library support in CalypStream" TYPE OPTIONAL)
SET_PACKAGE_PROPERTIES(
FFmpeg PROPERTIES
URL "http://ffmpeg.org/"
DESCRIPTION "Libav library support in CalypStream"
TYPE OPTIONAL
)
IF( WIN32 )
SET( USE_STATIC ON )
INCLUDE( cmake/Win32.cmake )
IF(WIN32)
SET(USE_STATIC ON)
INCLUDE(cmake/Win32.cmake)
ENDIF()
######################################################################################
# ####################################################################################################################################################
# CMake Defin1itions
######################################################################################
# ####################################################################################################################################################
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
INCLUDE(FeatureSummary)
# must go before the project command
SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE)
SET(CMAKE_CONFIGURATION_TYPES
"Debug;Release"
CACHE STRING "Configs" FORCE
)
IF(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8")
SET_PROPERTY( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} )
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES})
ENDIF()
SET( CMAKE_CXX_FLAGS "" )
SET(CMAKE_CXX_FLAGS "")
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
######################################################################################
# ####################################################################################################################################################
# Compiler options
######################################################################################
# ####################################################################################################################################################
SET(CMAKE_CXX_STANDARD 14)
if(CMAKE_COMPILER_IS_GNUCXX)
ADD_DEFINITIONS(-std=gnu++0x)
endif()
IF (NOT CMAKE_BUILD_TYPE )
MESSAGE(STATUS "No build type selected, default to Release")
SET(CMAKE_BUILD_TYPE "Release")
SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
IF(MSVC)
ADD_COMPILE_OPTIONS(/std:c++20)
ELSE()
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
ADD_DEFINITIONS(-std=gnu++2a)
ELSE()
ADD_DEFINITIONS(-std=c++20)
ENDIF()
ENDIF()
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
ADD_DEFINITIONS(-DQT_NO_CAST_TO_ASCII
#-DQT_NO_CAST_FROM_ASCII
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
#-DQT_NO_SIGNALS_SLOTS_KEYWORDS
#-DQT_USE_QSTRINGBUILDER
)
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
# endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlogical-op" )
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations" )
endif()
IF( USE_WERROR )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror" )
IF(NOT CMAKE_BUILD_TYPE)
MESSAGE(STATUS "No build type selected, default to Release")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF()
SET( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0" )
SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -funroll-loops")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") endif()
######################################################################################
IF(USE_WERROR)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -DCLP_DEBUG")
IF(BUILD_WITH_SANITIZERS)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fsanitize=leak -fsanitize=undefined")
ENDIF()
IF(BUILD_WITH_THREAD_SANITIZER)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread")
ENDIF()
IF(USE_IWYU)
FIND_PROGRAM(iwyu_path NAMES include-what-you-use iwyu REQUIRED)
SET(CXX_INCLUDE_WHAT_YOU_USE ON)
ENDIF()
# ####################################################################################################################################################
# Configure targets
######################################################################################
# ####################################################################################################################################################
ADD_FEATURE_INFO(CalypApp BUILD_APP "Build Graphical interface")
ADD_FEATURE_INFO(CalypTools BUILD_TOOLS "Build Command line tool" )
ADD_FEATURE_INFO(DynLoad USE_DYNLOAD "Support for dynamic module load" )
ADD_FEATURE_INFO(SSE USE_SSE "SSE instructions support" )
ADD_FEATURE_INFO(WErrors USE_WERROR "Warnings as errors" )
ADD_FEATURE_INFO(CalypApp BUILD_APP "Build Graphical interface")
ADD_FEATURE_INFO(CalypTools BUILD_TOOLS "Build Command line tool")
ADD_FEATURE_INFO(DynLoad USE_DYNLOAD "Support for dynamic module load")
ADD_FEATURE_INFO(SSE USE_SSE "SSE instructions support")
ADD_FEATURE_INFO(WErrors USE_WERROR "Warnings as errors")
ADD_SUBDIRECTORY( lib )
ADD_SUBDIRECTORY( modules )
ADD_SUBDIRECTORY(lib)
IF( ${BUILD_TOOLS} )
ADD_SUBDIRECTORY( tools )
IF(${BUILD_TOOLS} OR ${BUILD_APP})
ADD_SUBDIRECTORY(modules)
ENDIF()
IF( ${BUILD_APP} )
ADD_SUBDIRECTORY( app )
IF(${BUILD_TOOLS})
ADD_SUBDIRECTORY(tools)
ENDIF()
IF( ${BUILD_EXAMPLES} )
ADD_SUBDIRECTORY( examples )
IF(${BUILD_APP})
ADD_SUBDIRECTORY(app)
ENDIF()
IF(${BUILD_EXAMPLES})
ADD_SUBDIRECTORY(examples)
ENDIF()
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h )
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
######################################################################################
# ####################################################################################################################################################
# Final information dump
######################################################################################
# ####################################################################################################################################################
MESSAGE("")
MESSAGE( STATUS "${PROJECT_NAME} INFORMATION" )
MESSAGE( STATUS "Version: " "${CALYP_VERSION_STRING}" )
MESSAGE( STATUS "Configuration:" )
MESSAGE( STATUS " Static libs: " "${USE_STATIC}" )
MESSAGE( STATUS " Build type: " "${CMAKE_BUILD_TYPE}" )
MESSAGE( STATUS " Build flags: " "${CMAKE_CXX_FLAGS}" )
MESSAGE(STATUS "${PROJECT_NAME} INFORMATION")
MESSAGE(STATUS "Version: " "${CALYP_VERSION_STRING}")
MESSAGE(STATUS "Configuration:")
MESSAGE(STATUS " Static libs: " "${USE_STATIC}")
MESSAGE(STATUS " Build type: " "${CMAKE_BUILD_TYPE}")
MESSAGE(STATUS " Build flags: " "${CMAKE_CXX_FLAGS}")
FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
+12 -36
View File
@@ -27,19 +27,21 @@ Modules
Supported Quality Metrics
----------------------------------------------------------------
- PSNR
- SSIM
- MSE
- Peak Signal-to-Noise Ratio (PSNR)
- Structural SIMilarity (SSIM)
- Mean Square Error (MSE)
- Weighted Spherical PSNR (WS-PSNR)
Frame Processing Modules
----------------------------------------------------------------
- Component filtering
- Frame difference, crop, shift, binarization
- Frame difference, crop, shift, binarization and rotation
- Sub-sampling operations
- Measuring modules
- Modules based on opencv:
* Disparity estimation
* Motion estimation
- Disparity estimation
- Motion estimation
Supported Formats
----------------------------------------------------------------
@@ -62,35 +64,9 @@ Supported Formats
Developers
----------------------------------------------------------------
- Joao Carreira (jfmcarreira@gmail.com)
- Lui­s Lucas (luisfrlucas@gmail.com)
Builds
----------------------------------------------------------------
Download update build for windows and linux from our <a href="https://sourceforge.net/projects/playuver/">SourceForge project page</a>
Build/Install using cmake
----------------------------------------------------------------
1. The following are required for compilation:
- an ordinary C++ development environment (g++, make, C++ libraries and headers, ...)
- cmake
- a Qt development environment (libraries, headers, qmake, ...): only QtCore, QtGui and QtWidgets are required, at least in version 4
2. Optional Dependencies:
- QtDBus
- OpenCv
- FFmpeg
3. Run the following commands: (this will create an executable named calyp)
```
mkdir build
cd build
cmake -DUSE_QT4=OFF -DUSE_FFMPEG=ON -DUSE_OPENCV=ON .. (for FFmpeg and OpenCV support)
make
make install
```
- [**Joao Carreira**](https://github.com/jfmcarreira) (Founder, Main Developer)
- [**Lui­s Lucas** ](https://github.com/lfrlucas) (Founder, Developer)
- [**Joao Santos** ](https://github.com/jpataias) (Contributor)
- [**JNSFilipe** ](https://github.com/JNSFilipe) (Contributor)
*/
+9 -7
View File
@@ -3,9 +3,11 @@
## Build Status
Master branch | Development branch
------------ | -------------
[![Linux Status](https://travis-ci.org/pixlra/calyp.svg?branch=master)](https://travis-ci.org/pixlra/calyp.svg?branch=master) [![Windows status](https://ci.appveyor.com/api/projects/status/ea2ktvtg7uqwrika/branch/master?svg=true)](https://ci.appveyor.com/project/jfmcarreira/calyp/branch/master) | Comming soon!
| Master | Development |
|--|--|
| ![master branch](https://github.com/pixlra/calyp/actions/workflows/build.yml/badge.svg?branch=master) | ![devel branch](https://github.com/pixlra/calyp/actions/workflows/build.yml/badge.svg?branch=master) |
[![Windows status](https://ci.appveyor.com/api/projects/status/ea2ktvtg7uqwrika/branch/master?svg=true)](https://ci.appveyor.com/project/jfmcarreira/calyp/branch/master)
## Features
@@ -20,7 +22,7 @@ Master branch | Development branch
- Constant growing libs for stream and frame processing (CalypStream and CalypFrame)
- Advanced API for frame/video processing algorithms
- Frame level quality measurement API based on the CalypFrame class
- Powefull command-line tool for quality and frame processing algorithms (uses the referred APIs)
- Powerful command-line tool for quality and frame processing algorithms (uses the referred APIs)
## Modules
- CalypLib: Low level library
@@ -30,7 +32,7 @@ Master branch | Development branch
## Supported Quality Metrics
- Peak Signal-to-Noise Ratio (PSNR)
- Structural SIMilarity (SSIM)
- Structural SIMilarity (SSIM)
- Mean Square Error (MSE)
- Weighted Spherical PSNR (WS-PSNR)
@@ -73,13 +75,13 @@ Master branch | Development branch
* **Dependencies**
1. an ordinary C++ development environment (g++, make, C++ libraries and headers, ...)
2. cmake
3. a Qt development environment: QtCore, QtGui, QtWidgets, QtPrintSupport and QtConcurrent (version 4 or higher)
3. a Qt development environment: QtCore, QtGui, QtWidgets, QtPrintSupport and QtConcurrent (version 5 or higher)
4. Optional: QtDBus, OpenCV, FFmpeg
* **List of required commands**
```
mkdir build
cd build
cmake -DUSE_QT4=OFF -DUSE_FFMPEG=ON -DUSE_OPENCV=ON .. (for FFmpeg and OpenCV support)
cmake -DUSE_FFMPEG=ON -DUSE_OPENCV=ON .. (for FFmpeg and OpenCV support)
make
make install
```
+140 -87
View File
@@ -1,148 +1,201 @@
###
### CMakeLists for calyp app component
###
#
# CMakeLists for calyp app component
#
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/external
${CMAKE_CURRENT_SOURCE_DIR}/dialog
${CMAKE_CURRENT_SOURCE_DIR}/docks
${CMAKE_CURRENT_SOURCE_DIR}/widgets )
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/external
${CMAKE_CURRENT_SOURCE_DIR}/dialog
${CMAKE_CURRENT_SOURCE_DIR}/docks
${CMAKE_CURRENT_SOURCE_DIR}/widgets
${CMAKE_CURRENT_SOURCE_DIR}/models
)
OPTION( USE_QTDBUS "Build with QtDBus" ON )
OPTION( USE_FERVOR "Add Fervor support" OFF )
OPTION(USE_QT6 "Build with Qt6" ON)
OPTION(USE_QTDBUS "Build with QtDBus" OFF)
OPTION(USE_FERVOR "Add Fervor support" OFF)
OPTION(CALYP_MANAGED_RESOURCES "Handle streams in separate threads" ON)
OPTION(CALYP_THREADED_MODULES "Use threads for modules" ON)
ADD_SUBDIRECTORY( external )
IF(${USE_QT6})
FIND_PACKAGE(Qt6 QUIET COMPONENTS Core Gui Widgets Concurrent)
IF (NOT Qt6_FOUND)
FIND_PACKAGE(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent)
ENDIF()
ELSE()
FIND_PACKAGE(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent)
ENDIF()
FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent )
LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent )
LIST(APPEND QT_MODULES Core Gui Widgets Concurrent )
ADD_SUBDIRECTORY(external)
IF( USE_QTDBUS )
FIND_PACKAGE( Qt5DBus )
SET_PACKAGE_PROPERTIES(Qt5DBus PROPERTIES DESCRIPTION "Support for Qt5 DBus messages between instances" TYPE OPTIONAL )
IF( ${Qt5DBus_FOUND} )
SET( USE_QTDBUS ${Qt5DBus_FOUND} ) # TODO: fix this stupid variable
SET( USE_QTDBUS ${Qt5DBus_FOUND} PARENT_SCOPE)
LIST(APPEND QT_LINKER_LIBS Qt5::DBus )
LIST(APPEND QT_MODULES DBus )
LIST(APPEND QT_LINKER_LIBS Qt::Core Qt::Gui Qt::Widgets Qt::Concurrent)
LIST(APPEND QT_MODULES Core Gui Widgets Concurrent)
IF(USE_QTDBUS)
FIND_PACKAGE(Qt5DBus)
SET_PACKAGE_PROPERTIES(
Qt5DBus PROPERTIES
DESCRIPTION "Support for Qt5 DBus messages between instances"
TYPE OPTIONAL
)
IF(${Qt5DBus_FOUND})
SET(USE_QTDBUS ${Qt5DBus_FOUND}) # TODO: fix this stupid variable
SET(USE_QTDBUS
${Qt5DBus_FOUND}
PARENT_SCOPE
)
LIST(APPEND QT_LINKER_LIBS Qt::DBus)
LIST(APPEND QT_MODULES DBus)
ENDIF()
ENDIF()
set(Calyp_App_SRCS
# Main
ADD_DEFINITIONS(
-DQT_NO_CAST_TO_ASCII
# -DQT_NO_CAST_FROM_ASCII
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
# -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_USE_QSTRINGBUILDER
)
SET(Calyp_App_Module_SRCS # Module Video
models/VideostreamResource.cpp ResourceHandle.cpp
)
SET(Calyp_App_GUI_SRCS
${Calyp_App_Module_SRCS}
# Models
ModulesHandle.cpp
SubWindowHandle.cpp
VideoHandle.cpp
CalypAppModuleIf.cpp
QualityHandle.cpp
# Main
main.cpp
MainWindow.cpp
# Module SubWindow
SubWindowHandle.cpp
# Module SubWindow
MdiSubWindow.cpp
SubWindowAbstract.cpp
# Module Video
VideoHandle.cpp
VideoSubWindow.cpp
VideoStreamSubWindow.cpp
ModuleSubWindow.cpp
ViewArea.cpp
GridManager.cpp
# Module Quality
QualityHandle.cpp
PlotSubWindow.cpp
external/qcustomplot/qcustomplot.cpp
# Module Plugins
ModulesHandle.cpp
CalypAppModuleIf.cpp
# Dialogs
# Dialogs
dialog/AboutDialog.cpp
dialog/ConfigureFormatDialog.cpp
dialog/SubWindowSelectorDialog.cpp
dialog/ProgressBar.cpp
dialog/SeekStreamDialog.cpp
dialog/ModulesHandleOptDialog.cpp
# Widgets
# Widgets
widgets/HistogramWidget.cpp
widgets/FrameNumberWidget.cpp
# Docks
# Docks
docks/FramePropertiesDock.cpp
docks/ModuleHandleDock.cpp
docks/QualityMeasurementSidebar.cpp
)
IF( USE_QTDBUS )
LIST( APPEND Calyp_App_SRCS DBusAppAdaptor.cpp )
IF(USE_QTDBUS)
LIST(APPEND Calyp_App_GUI_SRCS DBusAppAdaptor.cpp)
ENDIF()
SET(Calyp_App_UI "")
set(Calyp_App_UI "" )
SET(Calyp_App_RCC resources/${PROJECT_NAME}.qrc)
set(Calyp_App_RCC
resources/${PROJECT_NAME}.qrc
)
IF(USE_FERVOR)
SET(FERVOR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/fervor)
IF( USE_FERVOR )
IF(EXISTS ${FERVOR_DIR})
SET( FERVOR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/fervor )
SET(FERVOR_APP_NAME ${PROJECT_NAME})
SET(FERVOR_APP_VERSION ${CALYP_VERSION_STRING})
IF(EXISTS ${FERVOR_DIR} )
ADD_SUBDIRECTORY(${FERVOR_DIR})
SET( FERVOR_APP_NAME ${PROJECT_NAME} )
SET( FERVOR_APP_VERSION ${CALYP_VERSION_STRING} )
INCLUDE_DIRECTORIES(${FERVOR_DIR})
ADD_SUBDIRECTORY( ${FERVOR_DIR} )
LIST(APPEND APP_LINKER_LIBS Fervor)
INCLUDE_DIRECTORIES( ${FERVOR_DIR} )
FIND_PACKAGE(Qt5 REQUIRED Network WebKit WebKitWidgets)
LIST(APPEND APP_LINKER_LIBS Fervor )
LIST(APPEND QT_LINKER_LIBS Qt::Network Qt::WebKit Qt::WebKitWidgets)
LIST(APPEND QT_MODULES Network WebKit WebKitWidgets)
FIND_PACKAGE( Qt5 REQUIRED Network WebKit WebKitWidgets )
LIST(APPEND QT_LINKER_LIBS Qt5::Network Qt5::WebKit Qt5::WebKitWidgets )
LIST(APPEND QT_MODULES Network WebKit WebKitWidgets )
# LIST(APPEND APP_LINKER_LIBS ${FERVOR_DEPENDENCIES} )
INCLUDE_DIRECTORIES( ${FERVOR_INCLUDE_DIRS} )
# LIST(APPEND APP_LINKER_LIBS ${FERVOR_DEPENDENCIES} )
INCLUDE_DIRECTORIES(${FERVOR_INCLUDE_DIRS})
SET(QT_USE_QTNETWORK true)
SET(QT_USE_QTWEBKIT true)
ELSE()
MESSAGE( "Fervor lib source code is not find in ${FERVOR_DIR}... Disabling it!" )
SET( USE_FERVOR False )
MESSAGE("Fervor lib source code is not find in ${FERVOR_DIR}... Disabling it!")
SET(USE_FERVOR False)
ENDIF()
ENDIF()
SET_PACKAGE_PROPERTIES(Fervor PROPERTIES URL "https://github.com/pypt/fervor" DESCRIPTION "Fervor lib includes check for updates feature" TYPE OPTIONAL )
SET_PACKAGE_PROPERTIES(
Fervor PROPERTIES
URL "https://github.com/pypt/fervor"
DESCRIPTION "Fervor lib includes check for updates feature"
TYPE OPTIONAL
)
ADD_FEATURE_INFO(Fervor USE_FERVOR "Fervor lib includes check for updates feature.")
QT5_WRAP_UI( Calyp_App_UI_Wrap ${Calyp_App_UI} )
QT5_ADD_RESOURCES( Calyp_App_RCC ${Calyp_App_RCC} )
QT_WRAP_UI(Calyp_App_UI_Wrap ${Calyp_App_UI})
QT_ADD_RESOURCES(Calyp_App_RCC ${Calyp_App_RCC})
# Instruct CMake to run moc automatically when needed.
SET( CMAKE_AUTOMOC ON )
SET(CMAKE_AUTOMOC ON)
# Windows application icon
IF( WIN32 )
set(WINDOWS_RES_FILE ${CMAKE_CURRENT_BINARY_DIR}/resources.obj)
IF( MSVC )
add_custom_command(OUTPUT ${WINDOWS_RES_FILE}
COMMAND rc.exe /fo ${WINDOWS_RES_FILE} ${PROJECT_NAME}.rc
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
)
ELSE()
add_custom_command(OUTPUT ${WINDOWS_RES_FILE}
COMMAND windres.exe ${PROJECT_NAME}.rc ${WINDOWS_RES_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
)
ENDIF()
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-enum-enum-conversion")
ENDIF()
ADD_EXECUTABLE( ${PROJECT_NAME} ${Calyp_App_SRCS} ${HEADERS_MOC_FILES} ${Calyp_App_UI_Wrap} ${Calyp_App_RCC} ${WINDOWS_RES_FILE} )
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${PROJECT_LIBRARY} CalypModules ${APP_LINKER_LIBS} ${QT_LINKER_LIBS} QCustomPlotLib )
# Windows application icon
IF(WIN32)
SET(WINDOWS_RES_FILE ${CMAKE_CURRENT_BINARY_DIR}/resources.obj)
IF(MSVC)
ADD_CUSTOM_COMMAND(
OUTPUT ${WINDOWS_RES_FILE}
COMMAND rc.exe /fo ${WINDOWS_RES_FILE} ${PROJECT_NAME}.rc
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
COMMENT "Add icon on windows platform"
)
ELSE()
ADD_CUSTOM_COMMAND(
OUTPUT ${WINDOWS_RES_FILE}
COMMAND windres.exe ${PROJECT_NAME}.rc ${WINDOWS_RES_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
COMMENT "Add icon on windows platform"
)
ENDIF()
ADD_EXECUTABLE(${PROJECT_NAME} ${Calyp_App_GUI_SRCS} ${HEADERS_MOC_FILES} ${Calyp_App_UI_Wrap} ${Calyp_App_RCC} ${WINDOWS_RES_FILE})
ELSEIF(CMAKE_HOST_APPLE)
SET(CMAKE_MACOSX_BUNDLE ON)
SET(MACOSX_BUNDLE_EXECUTABLE_NAME ${PROJECT_NAME})
SET(MACOSX_BUNDLE_ICON_FILE Contents/Resources/calyp.icns)
SET(MACOSX_BUNDLE_BUNDLE_NAME Calyp)
SET(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/resources/calyp.icns)
SET_SOURCE_FILES_PROPERTIES(${APP_ICON_MACOSX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
ADD_EXECUTABLE(${PROJECT_NAME} MACOSX_BUNDLE ${Calyp_App_GUI_SRCS} ${HEADERS_MOC_FILES} ${Calyp_App_UI_Wrap} ${Calyp_App_RCC} ${APP_ICON_MACOSX})
ELSE()
ADD_EXECUTABLE(${PROJECT_NAME} ${Calyp_App_GUI_SRCS} ${HEADERS_MOC_FILES} ${Calyp_App_UI_Wrap} ${Calyp_App_RCC})
ENDIF()
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PROJECT_LIBRARY} CalypModules ${APP_LINKER_LIBS} ${QT_LINKER_LIBS} QCustomPlotLib)
# QT5_USE_MODULES( ${PROJECT_NAME} ${QT_MODULES} )
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin )
INSTALL(FILES resources/calyp.desktop DESTINATION share/applications )
INSTALL(FILES resources/calyp.png DESTINATION share/pixmaps )
INSTALL(FILES resources/calyp.xml DESTINATION share/mime/packages )
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
INSTALL(FILES resources/calyp.desktop DESTINATION share/applications)
INSTALL(FILES resources/calyp.png DESTINATION share/pixmaps)
INSTALL(FILES resources/calyp.xml DESTINATION share/mime/packages)
IF(BUILD_TESTS)
ADD_SUBDIRECTORY(catch2)
ENDIF()
+144 -108
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,43 +24,80 @@
#include "CalypAppModuleIf.h"
#include "VideoSubWindow.h"
#include <QAction>
#include <QApplication>
#include <QDockWidget>
CalypAppModuleIf::CalypAppModuleIf( QObject* parent, QAction* action, CalypModuleIf* module )
: m_bIsRunning( false )
, m_pcModuleAction( action )
, m_pcModule( module )
, m_pcDisplaySubWindow( NULL )
, m_pcDockWidget( NULL )
, m_pcModuleDock( NULL )
, m_pcModuleStream( NULL )
, m_pcProcessedFrame( NULL )
, m_dMeasurementResult( 0 )
#include "ModuleHandleDock.h"
#include "ModuleSubWindow.h"
#include "VideoSubWindow.h"
#include "lib/CalypFrame.h"
#include "lib/CalypStream.h"
CalypAppModuleIf::CalypAppModuleIf( QObject* parent, QAction* action, CalypModulePtr&& module )
: m_pcModuleAction( action ), m_pcModule( std ::move( module ) )
{
setParent( parent );
for( int i = 0; i < CLP_MODULE_MAX_NUM_FRAMES; i++ )
#ifdef CALYP_THREADED_MODULES
setObjectName( m_pcModule->m_pchModuleName );
#endif
m_frameList.reserve( m_pcModule->m_uiNumberOfFrames );
m_frameListPtr.reserve( m_pcModule->m_uiNumberOfFrames );
m_pcSubWindow.resize( m_pcModule->m_uiNumberOfFrames, nullptr );
}
CalypAppModuleIf::~CalypAppModuleIf()
{
#ifdef CALYP_THREADED_MODULES
wait();
#endif
if( m_pcModuleDock )
{
m_pcSubWindow[i] = NULL;
auto* ptr = m_pcModuleDock;
m_pcModuleDock = NULL;
ptr->close();
delete ptr;
}
if( m_pcDisplaySubWindow )
{
auto* ptr = m_pcDisplaySubWindow;
m_pcDisplaySubWindow = NULL;
ptr->closeSubWindow();
delete ptr;
}
if( m_pcDockWidget )
{
m_pcDockWidget->close();
delete m_pcDockWidget;
}
if( m_pcModule )
{
m_pcModule->destroy();
m_pcModule = nullptr;
}
}
void CalypAppModuleIf::update()
void CalypAppModuleIf::update( bool isPlaying )
{
if( m_pcDisplaySubWindow )
{
m_pcDisplaySubWindow->refreshFrame();
m_pcDisplaySubWindow->refreshSubWindow();
}
else
{
apply();
apply( isPlaying );
}
}
bool CalypAppModuleIf::isRunning()
// void CalypAppModuleIf::setPlaying( bool isPlaying )
// {
// if( m_pcDisplaySubWindow )
// {
// m_pcDisplaySubWindow->setPlaying( isPlaying );
// }
// }
bool CalypAppModuleIf::isRunning() const
{
#ifdef CALYP_THREADED_MODULES
return QThread::isRunning();
@@ -69,12 +106,20 @@ bool CalypAppModuleIf::isRunning()
#endif
}
void CalypAppModuleIf::run()
{
bool result = process();
if( result )
{
EventData* eventData = new EventData( m_bSuccess, this );
QCoreApplication::postEvent( parent(), eventData );
}
}
bool CalypAppModuleIf::apply( bool isPlaying, bool disableThreads )
{
bool bRet = false;
QApplication::setOverrideCursor( Qt::WaitCursor );
if( m_pcModule->m_iModuleType == CLP_FRAME_PROCESSING_MODULE )
bool moduleExecuted = false;
if( m_pcModule->m_iModuleType == ClpModuleType::FrameProcessing )
{
if( m_pcDisplaySubWindow )
{
@@ -85,8 +130,20 @@ bool CalypAppModuleIf::apply( bool isPlaying, bool disableThreads )
m_pcSubWindow[0]->setFillWindow( true );
}
}
if( !( isPlaying && ( m_pcModule->m_uiModuleRequirements & CLP_MODULE_REQUIRES_SKIP_WHILE_PLAY ) ) )
if( !( isPlaying && m_pcModule->has( ClpModuleFeature::SkipWhilePlaying ) ) )
{
m_frameList.clear();
for( unsigned int i = 0; i < m_pcModule->m_uiNumberOfFrames; i++ )
{
m_frameList.push_back( m_pcSubWindow[i]->getCurrFrameAsset() );
}
// Skip module is is already running
if( isRunning() )
return moduleExecuted;
moduleExecuted = true;
#ifdef CALYP_THREADED_MODULES
if( !disableThreads )
{
@@ -96,49 +153,51 @@ bool CalypAppModuleIf::apply( bool isPlaying, bool disableThreads )
else
#endif
{
run();
QApplication::setOverrideCursor( Qt::WaitCursor );
process();
QApplication::restoreOverrideCursor();
show();
}
if( m_pcDisplaySubWindow || m_pcModule->m_iModuleType == CLP_FRAME_MEASUREMENT_MODULE )
{
bRet = true;
}
}
else
{
bRet = true;
}
QApplication::restoreOverrideCursor();
return bRet;
return moduleExecuted;
}
void CalypAppModuleIf::run()
bool CalypAppModuleIf::process()
{
m_bIsRunning = true;
m_bSuccess = false;
std::vector<CalypFrame*> apcFrameList;
for( unsigned int i = 0; i < m_pcModule->m_uiNumberOfFrames; i++ )
if( m_frameList.empty() )
return false;
#ifdef CALYP_THREADED_MODULES
QMutexLocker locker( &m_Mutex );
#endif
m_frameListPtr.clear();
for( auto& frame : m_frameList )
{
apcFrameList.push_back( m_pcSubWindow[i]->getCurrFrame() );
m_frameListPtr.push_back( frame.get() );
}
if( m_pcModule->m_iModuleType == CLP_FRAME_PROCESSING_MODULE )
if( m_pcModule->m_iModuleType == ClpModuleType::FrameProcessing )
{
CalypFrame* framePtr{ nullptr };
if( m_pcModule->m_iModuleAPI >= CLP_MODULE_API_2 )
{
m_pcProcessedFrame = m_pcModule->process( apcFrameList );
framePtr = m_pcModule->process( m_frameListPtr );
}
else
{
m_pcProcessedFrame = m_pcModule->process( m_pcSubWindow[0]->getCurrFrame() );
framePtr = m_pcModule->process( m_pcSubWindow[0]->getCurrFrame() );
}
assert( framePtr != nullptr );
m_pcProcessedFrame = std::shared_ptr<CalypFrame>{ framePtr, []( CalypFrame* ptr ) {} };
}
else if( m_pcModule->m_iModuleType == CLP_FRAME_MEASUREMENT_MODULE )
else if( m_pcModule->m_iModuleType == ClpModuleType::FrameMeasurement )
{
if( m_pcModule->m_iModuleAPI >= CLP_MODULE_API_2 )
{
m_dMeasurementResult = m_pcModule->measure( apcFrameList );
m_dMeasurementResult = m_pcModule->measure( m_frameListPtr );
}
else
{
@@ -147,84 +206,61 @@ void CalypAppModuleIf::run()
}
else
{
return;
return false;
}
m_bSuccess = true;
m_bIsRunning = false;
#ifdef CALYP_THREADED_MODULES
EventData* eventData = new EventData( m_bSuccess, this );
if( parent() )
QCoreApplication::postEvent( parent(), eventData );
#endif
return;
return true;
}
void CalypAppModuleIf::show()
{
#ifdef CALYP_THREADED_MODULES
if( m_canceling )
return;
#endif
switch( m_pcModule->m_iModuleType )
{
case CLP_FRAME_PROCESSING_MODULE:
if( m_pcDisplaySubWindow )
case ClpModuleType::FrameProcessing: {
auto displayWindow = qobject_cast<VideoSubWindow*>( m_pcDisplaySubWindow );
if( displayWindow == nullptr )
displayWindow = m_pcSubWindow[0];
#ifdef CALYP_THREADED_MODULES
if( m_Mutex.try_lock() )
{
m_pcDisplaySubWindow->setCurrFrame( m_pcProcessedFrame );
m_pcDisplaySubWindow->setFillWindow( false );
m_pcDisplaySubWindow->clearWindowBusy();
}
else
{
m_pcSubWindow[0]->setCurrFrame( m_pcProcessedFrame );
m_pcSubWindow[0]->setFillWindow( false );
m_pcSubWindow[0]->clearWindowBusy();
displayWindow->setFillWindow( false );
displayWindow->setCurrFrame( m_pcProcessedFrame );
m_Mutex.unlock();
}
#else
displayWindow->setFillWindow( false );
displayWindow->setCurrFrame( m_pcProcessedFrame );
#endif
break;
case CLP_FRAME_MEASUREMENT_MODULE:
m_pcModuleDock->setModulueReturnValue( m_dMeasurementResult );
}
case ClpModuleType::FrameMeasurement:
m_pcModuleDock->setModuleReturnValue( m_dMeasurementResult );
break;
default:
assert( false );
}
}
void CalypAppModuleIf::destroy()
void CalypAppModuleIf::disable()
{
if( m_bIsRunning )
QApplication::setOverrideCursor( Qt::WaitCursor );
#ifdef CALYP_THREADED_MODULES
m_canceling = true;
m_Mutex.lock();
m_Mutex.unlock();
#endif
m_frameList.clear();
m_frameListPtr.clear();
while( m_pcSubWindow.size() > 0 )
{
QApplication::setOverrideCursor( Qt::WaitCursor );
while( m_bIsRunning )
{
}
QApplication::restoreOverrideCursor();
}
if( m_pcModuleDock )
{
m_pcModuleDock->close();
m_pcModuleDock = NULL;
}
if( m_pcDockWidget )
{
m_pcDockWidget->close();
m_pcDockWidget = NULL;
}
if( m_pcDisplaySubWindow )
m_pcDisplaySubWindow->closeSubWindow();
m_pcDisplaySubWindow = NULL;
for( int i = 0; i < CLP_MODULE_MAX_NUM_FRAMES; i++ )
{
if( m_pcSubWindow[i] )
{
m_pcSubWindow[i]->disableModule( this );
m_pcSubWindow[i] = NULL;
}
}
if( m_pcModuleStream )
{
m_pcModuleStream->close();
delete m_pcModuleStream;
m_pcModuleStream = NULL;
}
if( m_pcModule )
{
m_pcModule->destroy();
m_pcModule->Delete();
m_pcModule = NULL;
auto window = m_pcSubWindow.back();
m_pcSubWindow.erase( m_pcSubWindow.end() - 1 );
if( window != nullptr )
window->disableModule( this );
}
QApplication::restoreOverrideCursor();
}
+60 -51
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,90 +25,99 @@
#ifndef __CALYPAPPMODULESIF_H__
#define __CALYPAPPMODULESIF_H__
#include "CommonDefs.h"
#include "ModuleHandleDock.h"
#include "config.h"
#include "lib/CalypFrame.h"
#include "lib/CalypModuleIf.h"
#include "lib/CalypStream.h"
#include <QEvent>
#include <QPointer>
#include <QVector>
#include <cstdio>
#include <iostream>
#include "config.h"
#ifdef CALYP_THREADED_MODULES
#include <QMutex>
#include <QThread>
#endif
#include "CommonDefs.h"
#include "ModuleHandleDock.h"
// #include "lib/CalypFrame.h"
#include "lib/CalypModuleIf.h"
// #include "lib/CalypStream.h"
class QAction;
class QDockWidget;
#define CLP_MODULE_MAX_NUM_FRAMES 5
class CalypStream;
class CalypFrame;
class VideoSubWindow;
class ModuleSubWindow;
class CalypAppModuleIf
class CalypAppModuleIf : std::enable_shared_from_this<CalypAppModuleIf>,
#ifdef CALYP_THREADED_MODULES
: public QThread
public QThread
#else
: public QObject
public QObject
#endif
{
friend class ModulesHandle;
friend class ModuleHandleDock;
friend class ModulesHandleOptDialog;
private:
bool m_bIsRunning;
bool m_bSuccess;
QAction* m_pcModuleAction;
CalypModuleIf* m_pcModule;
VideoSubWindow* m_pcSubWindow[CLP_MODULE_MAX_NUM_FRAMES];
VideoSubWindow* m_pcDisplaySubWindow;
QDockWidget* m_pcDockWidget;
ModuleHandleDock* m_pcModuleDock;
CalypStream* m_pcModuleStream;
CalypFrame* m_pcProcessedFrame;
double m_dMeasurementResult;
public:
class EventData : public QEvent
{
public:
EventData( bool success, CalypAppModuleIf* module )
: QEvent( QEvent::User )
: QEvent( QEvent::User ), m_bSuccess{ success }, m_pcModule{ module }
{
m_bSuccess = success;
m_pcModule = module;
}
bool m_bSuccess;
CalypAppModuleIf* m_pcModule;
QPointer<CalypAppModuleIf> m_pcModule;
};
CalypAppModuleIf( QObject* parent, QAction* action, CalypModuleIf* module );
virtual ~CalypAppModuleIf() {}
QList<VideoSubWindow*> getSubWindowList()
{
QList<VideoSubWindow*> arraySubWindows;
for( int i = 0; i < CLP_MODULE_MAX_NUM_FRAMES; i++ )
if( m_pcSubWindow[i] )
arraySubWindows.append( m_pcSubWindow[i] );
return arraySubWindows;
}
CalypAppModuleIf( QObject* parent, QAction* action, CalypModulePtr&& module );
~CalypAppModuleIf();
CalypModuleIf* getModule() { return m_pcModule; }
unsigned int getModuleRequirements() { return m_pcModule->m_uiModuleRequirements; }
ClpString moduleInfo() { return m_pcModule->moduleInfo(); }
void update();
auto getSubWindowList() const -> const std::vector<VideoSubWindow*>& { return m_pcSubWindow; }
CalypModuleIf* getModule() { return m_pcModule.get(); }
auto hasFeature( ClpModuleFeature feature ) const -> bool { return m_pcModule->has( feature ); }
std::string moduleInfo() const { return m_pcModule->moduleInfo(); }
void update( bool isPlaying );
bool apply( bool isPlaying = false, bool disableThreads = false );
bool isRunning();
bool process();
bool isRunning() const;
void show();
void destroy();
void disable();
protected:
virtual void run();
private:
bool m_bSuccess{ false };
QAction* m_pcModuleAction{ nullptr };
CalypModulePtr m_pcModule{ nullptr };
std::vector<VideoSubWindow*> m_pcSubWindow;
// The module owns the related widgets
ModuleSubWindow* m_pcDisplaySubWindow{ nullptr };
QDockWidget* m_pcDockWidget{ nullptr };
ModuleHandleDock* m_pcModuleDock{ nullptr };
std::unique_ptr<CalypStream> m_pcModuleStream{ nullptr };
std::vector<std::shared_ptr<CalypFrame>> m_frameList;
std::vector<CalypFrame*> m_frameListPtr;
std::shared_ptr<CalypFrame> m_pcProcessedFrame{ nullptr };
double m_dMeasurementResult{ 0 };
#ifdef CALYP_THREADED_MODULES
QMutex m_Mutex;
std::atomic<bool> m_canceling{ false };
#endif
};
#endif // __CALYPAPPMODULESIF_H__
+1 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
+4 -6
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@ void GridManager::setGridSize( int newsize )
////////////////////////////////////////////////////////////////////////////////
// Grid Drawer
////////////////////////////////////////////////////////////////////////////////
void GridManager::drawGrid( QPixmap& image, const QRect& area, QPainter* painter )
void GridManager::drawGrid( const QImage& image, const QRect& area, QPainter* painter )
{
int offsetx = 0; // Grid offset doesn't applies to SCODE
int offsety = 0; // project for now...
@@ -71,8 +71,7 @@ void GridManager::drawGrid( QPixmap& image, const QRect& area, QPainter* painter
switch( style )
{
case intersectionDot:
case intersectionCross:
{
case intersectionCross: {
painter->setPen( mainPen );
// Draw crosses or dots on intersections
for( int x = offsetx; x <= area.right(); x += hSpacing )
@@ -99,8 +98,7 @@ void GridManager::drawGrid( QPixmap& image, const QRect& area, QPainter* painter
}
break;
}
case Dashed:
{
case Dashed: {
// Change pen to the dashed line
mainPen.setStyle( Qt::DashLine );
}
+3 -2
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,7 @@
#include <QColor>
#include <QPen>
#include <QRect>
#include "CommonDefs.h"
#include "config.h"
@@ -54,7 +55,7 @@ public:
void setGridSize( int newsize );
void drawGrid( QPixmap& image, const QRect& area, QPainter* painter );
void drawGrid( const QImage& image, const QRect& area, QPainter* painter );
/**
* @returns a QRect defined by the grid that contains the point (x, y).
+208 -162
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
* Joao Santos (joaompssantos@gmail.com)
*
@@ -25,16 +25,6 @@
#include "MainWindow.h"
#include "AboutDialog.h"
#include "ModulesHandle.h"
#include "QualityHandle.h"
#include "SubWindowAbstract.h"
#include "SubWindowHandle.h"
#include "SubWindowSelectorDialog.h"
#include "VideoHandle.h"
#include "VideoSubWindow.h"
#include "lib/CalypOptions.h"
#include <QAction>
#include <QActionGroup>
#include <QCloseEvent>
@@ -43,12 +33,24 @@
#include <QDropEvent>
#include <QSignalMapper>
#include <QtDebug>
#include <memory>
#include "AboutDialog.h"
#include "ConfigureFormatDialog.h"
#include "ModulesHandle.h"
#include "QualityHandle.h"
#include "SubWindowAbstract.h"
#include "SubWindowHandle.h"
#include "SubWindowSelectorDialog.h"
#include "VideoHandle.h"
#include "VideoSubWindow.h"
#include "lib/CalypOptions.h"
#include "models/VideostreamResource.h"
#ifdef USE_FERVOR
#include "fvupdater.h"
#endif
MainWindow::MainWindow()
: m_pcCurrentSubWindow( NULL ), m_pcCurrentVideoSubWindow( NULL ), m_pcAboutDialog( NULL )
{
setWindowModality( Qt::ApplicationModal );
setWindowModality( Qt::NonModal );
@@ -58,6 +60,8 @@ MainWindow::MainWindow()
m_pDBusAdaptor = new DBusAppAdaptor( this );
#endif
m_appResourceHandle = std::make_unique<ResourceHandle>();
m_pcWindowHandle = new SubWindowHandle( this );
m_appModuleVideo = new VideoHandle( this, m_pcWindowHandle );
@@ -76,15 +80,15 @@ MainWindow::MainWindow()
setWindowTitle( QApplication::applicationName() );
setWindowIcon( QIcon( ":logos/calyp-icon.png" ) );
setUnifiedTitleAndToolBarOnMac( true );
setCentralWidget( m_pcWindowHandle );
setCentralWidget( m_pcWindowHandle->getWidget() );
setAcceptDrops( true );
setBackgroundRole( QPalette::Background );
setBackgroundRole( QPalette::Window );
connect( m_pcWindowHandle, SIGNAL( windowActivated() ), this, SLOT( update() ) );
connect( m_pcWindowHandle, SIGNAL( changed() ), this, SLOT( update() ) );
connect( m_appModuleVideo, SIGNAL( changed() ), this, SLOT( update() ) );
connect( m_appModuleQuality, SIGNAL( changed() ), this, SLOT( update() ) );
connect( m_appModuleExtensions, SIGNAL( changed() ), this, SLOT( update() ) );
connect( m_pcWindowHandle, &SubWindowHandle::windowActivated, this, &MainWindow::updateMainWindow );
connect( m_pcWindowHandle, &SubWindowHandle::changed, this, &MainWindow::updateMainWindow, Qt::QueuedConnection );
connect( m_appModuleVideo, &VideoHandle::changed, this, &MainWindow::updateMainWindow, Qt::QueuedConnection );
connect( m_appModuleQuality, &QualityHandle::changed, this, &MainWindow::updateMainWindow, Qt::QueuedConnection );
connect( m_appModuleExtensions, &ModulesHandle::changed, this, &MainWindow::updateMainWindow, Qt::QueuedConnection );
}
bool MainWindow::parseArgs( int argc, char* argv[] )
@@ -92,16 +96,16 @@ bool MainWindow::parseArgs( int argc, char* argv[] )
bool bRet = false;
CalypOptions pcCmdParser;
std::vector<ClpString> m_apcInputs;
ClpString strResolution( "" );
ClpString strPelFmt( "" );
std::vector<std::string> m_apcInputs;
std::string strResolution( "" );
std::string strPelFmt( "" );
pcCmdParser.addOptions() /**/
( "input,i", m_apcInputs, "input file" ) /**/
( "size,s", strResolution, "size (WxH)" ) /**/
( "pel_fmt", strPelFmt, "pixel format" );
if( !pcCmdParser.parse( argc, argv ) )
if( pcCmdParser.parse( argc, argv ) < 0 )
{
bRet |= true;
}
@@ -131,8 +135,7 @@ bool MainWindow::parseArgs( int argc, char* argv[] )
void MainWindow::about()
{
if( !m_pcAboutDialog )
m_pcAboutDialog = new AboutDialog( this );
if( !m_pcAboutDialog ) m_pcAboutDialog = new AboutDialog( this );
m_pcAboutDialog->exec();
}
@@ -182,37 +185,82 @@ void MainWindow::closeAll()
m_pcWindowHandle->removeAllSubWindow();
}
void MainWindow::loadFile( QString fileName, CalypFileInfo* pStreamInfo )
void MainWindow::loadFile( const CalypFileInfo& pStreamInfo )
{
loadFile( pStreamInfo.m_cFilename, pStreamInfo );
}
void MainWindow::loadFile( const QString& fileName, std::optional<CalypFileInfo> streamInfoOpt, bool forceDialog )
{
qDebug() << fileName;
if( !QFileInfo( fileName ).exists() )
{
printMessage( "File " + fileName + " do not exist!", CLP_LOG_ERROR );
return;
}
VideoSubWindow* videoSubWindow = MainWindow::findVideoStreamSubWindow( m_pcWindowHandle, fileName );
if( videoSubWindow )
if( auto* videoSubWindow = MainWindow::findVideoStreamSubWindow( m_pcWindowHandle, fileName ) )
{
m_pcWindowHandle->setActiveSubWindow( videoSubWindow );
return;
}
videoSubWindow = new VideoSubWindow( VideoSubWindow::VIDEO_STREAM_SUBWINDOW ); // createSubWindow();
if( !pStreamInfo )
if( !streamInfoOpt.has_value() )
{
int idx = findCalypStreamInfo( m_aRecentFileStreamInfo, fileName );
pStreamInfo = (CalypFileInfo*)( idx >= 0 ? &m_aRecentFileStreamInfo.at( idx ) : NULL );
auto idx = findCalypStreamInfo( m_aRecentFileStreamInfo, fileName );
if( idx >= 0 ) streamInfoOpt = m_aRecentFileStreamInfo.at( idx );
}
auto streamInfo = streamInfoOpt.has_value() ? *streamInfoOpt : CalypFileInfo{ .m_cFilename = fileName };
auto videoResource = std::make_unique<VideostreamResource>();
bool opened = false;
try
{
bool opened = false;
[[maybe_unused]] auto guessed = video_resource_guess_format(
streamInfo.m_cFilename, streamInfo.m_uiWidth, streamInfo.m_uiHeight, streamInfo.m_iPelFormat,
streamInfo.m_uiBitsPelPixel, streamInfo.m_iEndianness, streamInfo.m_uiFrameRate );
if( !pStreamInfo )
opened = videoSubWindow->loadFile( fileName );
else
opened = videoSubWindow->loadFile( pStreamInfo );
if( !forceDialog )
{
opened = videoResource->loadFile( streamInfo, false );
}
if( !opened )
{
ConfigureFormatDialog formatDialog( this );
if( streamInfo.m_uiWidth == 0 )
{
streamInfo.m_uiWidth = m_lastOpenWidth;
}
if( streamInfo.m_uiHeight == 0 )
{
streamInfo.m_uiHeight = m_lastOpenHeight;
}
if( streamInfo.m_uiBitsPelPixel == 0 )
{
streamInfo.m_uiBitsPelPixel = m_lastOpenBitPerPixel;
}
if( formatDialog.runConfigureFormatDialog( QFileInfo( streamInfo.m_cFilename ).fileName(), streamInfo.m_uiWidth,
streamInfo.m_uiHeight, streamInfo.m_iPelFormat,
streamInfo.m_uiBitsPelPixel, streamInfo.m_iEndianness,
streamInfo.m_uiFrameRate ) != QDialog::Accepted )
{
return;
}
opened = videoResource->loadFile( streamInfo, false );
}
if( opened )
{
const auto openedStreamInfo = videoResource->getStreamInfo();
auto resource_id = m_appResourceHandle->appendResource( std::move( videoResource ) );
auto* videoSubWindow = new VideoStreamSubWindow( m_appResourceHandle.get() ); // createSubWindow();
videoSubWindow->setResource( resource_id );
printMessage( "Loading file...", CLP_LOG_INFO );
m_pcWindowHandle->addSubWindow( videoSubWindow );
videoSubWindow->show();
@@ -221,19 +269,17 @@ void MainWindow::loadFile( QString fileName, CalypFileInfo* pStreamInfo )
updateZoomFactorSBox();
addStreamInfoToRecentList( videoSubWindow->getStreamInfo() );
m_lastOpenPath = QFileInfo( openedStreamInfo.m_cFilename ).path();
m_lastOpenWidth = openedStreamInfo.m_uiWidth;
m_lastOpenHeight = openedStreamInfo.m_uiHeight;
m_lastOpenBitPerPixel = openedStreamInfo.m_uiBitsPelPixel;
addStreamInfoToRecentList( std::move( openedStreamInfo ) );
printMessage( "File loaded", CLP_LOG_INFO );
m_cLastOpenPath = QFileInfo( fileName ).path();
}
else
{
videoSubWindow->close();
}
}
catch( CalypFailure& e )
{
videoSubWindow->close();
QString warningMsg =
"Cannot open file " + QFileInfo( fileName ).fileName() + " with the following error: \n" + e.what();
QMessageBox::warning( this, QApplication::applicationName(), warningMsg );
@@ -256,12 +302,12 @@ QStringList MainWindow::showFileDialog( bool bRead )
for( unsigned int i = 0; i < supportedFmts.size(); i++ )
{
std::vector<ClpString> arrayExt = supportedFmts[i].getExts();
std::vector<std::string> arrayExt = supportedFmts[i].getExts();
if( arrayExt.size() > 0 )
{
QString currFmt( QString::fromStdString( supportedFmts[i].formatName ) );
currFmt.append( " (" );
for( std::vector<ClpString>::iterator e = arrayExt.begin(); e != arrayExt.end(); ++e )
for( std::vector<std::string>::iterator e = arrayExt.begin(); e != arrayExt.end(); ++e )
{
supported.append( " *." );
currFmt.append( "*." );
@@ -281,13 +327,12 @@ QStringList MainWindow::showFileDialog( bool bRead )
fileNameList.clear();
if( bRead )
{
fileNameList = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_cLastOpenPath, filter.join( ";;" ) );
fileNameList = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_lastOpenPath, filter.join( ";;" ) );
}
else
{
QString fileName = QFileDialog::getSaveFileName( this, tr( "Save File" ), m_cLastOpenPath, filter.join( ";;" ) );
if( !fileName.isEmpty() )
fileNameList.append( fileName );
QString fileName = QFileDialog::getSaveFileName( this, tr( "Save File" ), m_lastOpenPath, filter.join( ";;" ) );
if( !fileName.isEmpty() ) fileNameList.append( fileName );
}
return fileNameList;
}
@@ -299,7 +344,7 @@ void MainWindow::open()
{
if( !fileNameList.at( i ).isEmpty() )
{
loadFile( fileNameList.at( i ) );
loadFile( std::move( fileNameList.at( i ) ) );
}
}
}
@@ -312,25 +357,25 @@ void MainWindow::open()
void MainWindow::openRecent()
{
QAction* action = qobject_cast<QAction*>( sender() );
CalypFileInfo recentFile = action->data().value<CalypFileInfo>();
if( action )
loadFile( recentFile.m_cFilename, &recentFile );
{
loadFile( action->data().value<CalypFileInfo>() );
}
}
void MainWindow::saveFrame()
{
if( m_pcCurrentVideoSubWindow )
auto* pcVideoSubWindow = m_pcWindowHandle->activeSubWindow<VideoStreamSubWindow>();
if( pcVideoSubWindow != nullptr )
{
VideoSubWindow* saveWindow = m_pcCurrentVideoSubWindow;
QStringList fileNameList = showFileDialog( false );
if( fileNameList.size() == 1 )
{
QString fileName = fileNameList[0];
m_cLastOpenPath = QFileInfo( fileName ).path();
m_lastOpenPath = QFileInfo( fileName ).path();
try
{
saveWindow->save( fileName );
pcVideoSubWindow->save( fileName );
}
catch( CalypFailure& e )
{
@@ -347,18 +392,17 @@ void MainWindow::saveFrame()
void MainWindow::saveStream()
{
if( m_pcCurrentVideoSubWindow )
auto* pcVideoSubWindow = m_pcWindowHandle->activeSubWindow<VideoStreamSubWindow>();
if( pcVideoSubWindow != nullptr )
{
VideoSubWindow* saveWindow = m_pcCurrentVideoSubWindow;
QStringList fileNameList = showFileDialog( false );
if( fileNameList.size() == 1 )
{
QString fileName = fileNameList[0];
m_cLastOpenPath = QFileInfo( fileName ).path();
m_lastOpenPath = QFileInfo( fileName ).path();
try
{
saveWindow->save( fileName );
pcVideoSubWindow->save( fileName );
}
catch( CalypFailure& e )
{
@@ -375,15 +419,19 @@ void MainWindow::saveStream()
void MainWindow::format()
{
if( m_pcCurrentVideoSubWindow )
auto* pcVideoSubWindow = m_pcWindowHandle->activeSubWindow<VideoStreamSubWindow>();
if( pcVideoSubWindow )
{
VideoSubWindow* pcVideoSubWindow = m_pcCurrentVideoSubWindow;
try
{
if( pcVideoSubWindow->loadFile( pcVideoSubWindow->getCurrentFileName(), true ) )
{
addStreamInfoToRecentList( pcVideoSubWindow->getStreamInfo() );
}
auto resourceId = pcVideoSubWindow->getResourceId();
CalypFileInfo streamInfo;
m_appResourceHandle->executeResourceAction<VideostreamResource>( resourceId, [&streamInfo]( auto* resource ) {
streamInfo = resource->getStreamInfo();
return true;
} );
m_pcWindowHandle->removeSubWindow( pcVideoSubWindow );
loadFile( streamInfo.m_cFilename, streamInfo, true );
}
catch( CalypFailure& e )
{
@@ -392,20 +440,18 @@ void MainWindow::format()
QMessageBox::warning( this, QApplication::applicationName(), warningMsg );
printMessage( warningMsg, CLP_LOG_ERROR );
qDebug() << warningMsg;
m_pcCurrentSubWindow->close();
}
m_pcCurrentSubWindow = NULL;
update();
updateMainWindow();
}
}
void MainWindow::reload()
{
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow<SubWindowAbstract>();
if( activeSubWindow != nullptr )
{
m_pcCurrentSubWindow->refreshSubWindow();
m_pcCurrentSubWindow = NULL;
update();
activeSubWindow->refreshSubWindow();
updateMainWindow();
}
}
@@ -425,16 +471,16 @@ void MainWindow::reloadAll()
subWindowList.at( i )->refreshSubWindow();
}
}
m_pcCurrentSubWindow = NULL;
update();
updateMainWindow();
}
void MainWindow::loadAll()
{
if( m_pcCurrentVideoSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow<VideoStreamSubWindow>();
if( activeSubWindow != nullptr )
{
printMessage( "Loading file into memory...", CLP_LOG_INFO );
m_pcCurrentVideoSubWindow->loadAll();
activeSubWindow->loadAll();
printMessage( "File loaded", CLP_LOG_INFO );
}
}
@@ -443,40 +489,45 @@ void MainWindow::loadAll()
void MainWindow::normalSize()
{
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
if( activeSubWindow != nullptr )
{
m_pcCurrentSubWindow->normalSize();
activeSubWindow->normalSize();
updateZoomFactorSBox();
}
}
void MainWindow::zoomToFit()
{
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
if( activeSubWindow != nullptr )
{
m_pcCurrentSubWindow->zoomToFit();
activeSubWindow->zoomToFit();
updateZoomFactorSBox();
}
}
void MainWindow::zoomToFitAll()
{
VideoSubWindow* videoSubWindow;
QList<SubWindowAbstract*> subWindowList = m_pcWindowHandle->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW );
for( int i = 0; i < subWindowList.size(); i++ )
{
videoSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
auto* videoSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
videoSubWindow->zoomToFit();
}
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
if( activeSubWindow != nullptr )
{
updateZoomFactorSBox();
}
}
void MainWindow::scaleFrame( int ratio )
{
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
if( activeSubWindow != nullptr )
{
m_pcCurrentSubWindow->scaleView( (double)( ratio ) / 100.0 );
activeSubWindow->scaleView( (double)( ratio ) / 100.0 );
updateZoomFactorSBox();
}
}
@@ -493,10 +544,10 @@ void MainWindow::zoomFromSBox( double zoom )
void MainWindow::updateZoomFactorSBox()
{
double factor;
if( m_pcCurrentSubWindow )
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
if( activeSubWindow != nullptr )
{
factor = m_pcCurrentSubWindow->getScaleFactor();
auto factor = activeSubWindow->getScaleFactor();
m_pcZoomFactorSBox->setValue( factor * 100 );
}
}
@@ -517,60 +568,48 @@ void MainWindow::dropEvent( QDropEvent* event )
if( urlList.size() == 1 )
{
QString fileName = urlList.at( 0 ).toLocalFile();
m_cLastOpenPath = QFileInfo( fileName ).path();
m_lastOpenPath = QFileInfo( fileName ).path();
loadFile( fileName );
}
}
// ----------------------- Sub Window Functions -----------------------
VideoSubWindow* MainWindow::findVideoStreamSubWindow( const SubWindowHandle* windowManager,
const QString& fileName )
VideoStreamSubWindow* MainWindow::findVideoStreamSubWindow( const SubWindowHandle* windowManager,
const QString& fileName )
{
QString canonicalFilePath = QFileInfo( fileName ).canonicalFilePath();
VideoSubWindow* pcSubWindow;
QList<SubWindowAbstract*> subWindowList = windowManager->findSubWindow( SubWindowAbstract::VIDEO_STREAM_SUBWINDOW );
for( int i = 0; i < subWindowList.size(); i++ )
{
pcSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
if( pcSubWindow->getCurrentFileName() == canonicalFilePath )
return qobject_cast<VideoSubWindow*>( pcSubWindow );
auto* pcSubWindow = qobject_cast<VideoStreamSubWindow*>( subWindowList.at( i ) );
if( pcSubWindow->getCurrentFileName() == canonicalFilePath ) return pcSubWindow;
}
return 0;
return nullptr;
}
// ----------------------- Update Functions -----------------------
void MainWindow::update()
void MainWindow::updateMainWindow()
{
SubWindowAbstract* activeSubWindow = m_pcWindowHandle->activeSubWindow();
auto* activeSubWindow = m_pcWindowHandle->activeSubWindow();
auto* activeVideoSubWindow = qobject_cast<VideoSubWindow*>( activeSubWindow );
QCoreApplication::processEvents();
// if( activeSubWindow() != m_pcCurrentSubWindow )
{
m_pcCurrentSubWindow = NULL;
m_pcCurrentVideoSubWindow = NULL;
if( activeSubWindow )
{
m_pcCurrentSubWindow = activeSubWindow;
if( m_pcCurrentSubWindow->getCategory() & SubWindowAbstract::VIDEO_SUBWINDOW )
if( activeVideoSubWindow != nullptr &&
!m_pcWindowHandle->findSubWindow( activeVideoSubWindow->getRefSubWindow() ) )
{
m_pcCurrentVideoSubWindow = qobject_cast<VideoSubWindow*>( m_pcCurrentSubWindow );
}
if( m_pcCurrentVideoSubWindow )
{
if( !m_pcWindowHandle->findSubWindow( m_pcCurrentVideoSubWindow->getRefSubWindow() ) )
{
m_pcCurrentVideoSubWindow->setRefSubWindow( NULL );
}
activeVideoSubWindow->setRefSubWindow( nullptr );
}
updateZoomFactorSBox();
}
}
//! Check this - these two function should swap order
m_appModuleQuality->update( m_pcCurrentVideoSubWindow );
m_appModuleVideo->update( m_pcCurrentVideoSubWindow );
m_appModuleQuality->update( activeVideoSubWindow );
m_appModuleVideo->update( activeVideoSubWindow );
updateMenus();
}
@@ -595,10 +634,14 @@ void MainWindow::updateMenus()
{
bool hasSubWindow = ( m_pcWindowHandle->activeSubWindow() != 0 );
bool hasVideoStreamSubWindow = false;
if( m_pcCurrentSubWindow )
if( m_pcCurrentSubWindow->getCategory() & SubWindowAbstract::VIDEO_STREAM_SUBWINDOW )
hasVideoStreamSubWindow = true;
bool hasVideoStreamSubWindow{ false };
bool supportsFormat{ false };
auto* pcVideoSubWindow = m_pcWindowHandle->activeSubWindow<VideoStreamSubWindow>();
if( pcVideoSubWindow != nullptr && pcVideoSubWindow->getCategory() & SubWindowAbstract::VIDEO_STREAM_SUBWINDOW )
{
hasVideoStreamSubWindow = true;
supportsFormat = pcVideoSubWindow->supportsFormatConfiguration();
}
m_arrayMenu[RECENT_MENU]->setEnabled( m_aRecentFileStreamInfo.size() > 0 ? true : false );
@@ -608,7 +651,7 @@ void MainWindow::updateMenus()
m_arrayActions[RELOAD_ACT]->setEnabled( hasSubWindow );
m_arrayActions[RELOAD_ALL_ACT]->setEnabled( hasSubWindow );
m_arrayActions[FORMAT_ACT]->setEnabled( hasVideoStreamSubWindow );
m_arrayActions[FORMAT_ACT]->setEnabled( supportsFormat );
m_arrayActions[LOAD_ALL_ACT]->setEnabled( hasVideoStreamSubWindow );
m_arrayActions[ZOOM_IN_ACT]->setEnabled( hasSubWindow );
@@ -663,19 +706,19 @@ void MainWindow::createActions()
m_arrayActions[FORMAT_ACT] = new QAction( tr( "&Format" ), this );
m_arrayActions[FORMAT_ACT]->setIcon( QIcon::fromTheme( "transform-scale" ) );
m_arrayActions[FORMAT_ACT]->setShortcut( Qt::CTRL + Qt::Key_F );
m_arrayActions[FORMAT_ACT]->setShortcut( Qt::CTRL | Qt::Key_F );
m_arrayActions[FORMAT_ACT]->setStatusTip( tr( "Open format dialog" ) );
connect( m_arrayActions[FORMAT_ACT], SIGNAL( triggered() ), this, SLOT( format() ) );
m_arrayActions[RELOAD_ACT] = new QAction( tr( "&Reload" ), this );
m_arrayActions[RELOAD_ACT]->setIcon( style()->standardIcon( QStyle::SP_BrowserReload ) );
m_arrayActions[RELOAD_ACT]->setShortcut( Qt::CTRL + Qt::Key_R );
m_arrayActions[RELOAD_ACT]->setShortcut( Qt::CTRL | Qt::Key_R );
m_arrayActions[RELOAD_ACT]->setShortcut( Qt::Key_F5 );
m_arrayActions[RELOAD_ACT]->setStatusTip( tr( "Reload current sequence" ) );
connect( m_arrayActions[RELOAD_ACT], SIGNAL( triggered() ), this, SLOT( reload() ) );
m_arrayActions[RELOAD_ALL_ACT] = new QAction( tr( "Reload All" ), this );
m_arrayActions[RELOAD_ALL_ACT]->setShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_R );
m_arrayActions[RELOAD_ALL_ACT]->setShortcut( Qt::CTRL | Qt::SHIFT | Qt::Key_R );
m_arrayActions[RELOAD_ALL_ACT]->setStatusTip( tr( "Reload all sequences" ) );
connect( m_arrayActions[RELOAD_ALL_ACT], SIGNAL( triggered() ), this, SLOT( reloadAll() ) );
@@ -698,22 +741,17 @@ void MainWindow::createActions()
connect( m_arrayActions[EXIT_ACT], SIGNAL( triggered() ), qApp, SLOT( closeAllWindows() ) );
// ------------ View ------------
mapperZoom = new QSignalMapper( this );
connect( mapperZoom, SIGNAL( mapped( int ) ), this, SLOT( scaleFrame( int ) ) );
m_arrayActions[ZOOM_IN_ACT] = new QAction( tr( "Zoom &In (+25%)" ), this );
m_arrayActions[ZOOM_IN_ACT]->setIcon( QIcon::fromTheme( "zoom-in" ) );
m_arrayActions[ZOOM_IN_ACT]->setShortcut( tr( "Ctrl++" ) );
m_arrayActions[ZOOM_IN_ACT]->setStatusTip( tr( "Scale the image up by 25%" ) );
connect( m_arrayActions[ZOOM_IN_ACT], SIGNAL( triggered() ), mapperZoom, SLOT( map() ) );
mapperZoom->setMapping( m_arrayActions[ZOOM_IN_ACT], 125 );
connect( m_arrayActions[ZOOM_IN_ACT], &QAction::triggered, [this] { scaleFrame( 125 ); } );
m_arrayActions[ZOOM_OUT_ACT] = new QAction( tr( "Zoom &Out (-25%)" ), this );
m_arrayActions[ZOOM_OUT_ACT]->setIcon( QIcon::fromTheme( "zoom-out" ) );
m_arrayActions[ZOOM_OUT_ACT]->setShortcut( tr( "Ctrl+-" ) );
m_arrayActions[ZOOM_OUT_ACT]->setStatusTip( tr( "Scale the image down by 25%" ) );
connect( m_arrayActions[ZOOM_OUT_ACT], SIGNAL( triggered() ), mapperZoom, SLOT( map() ) );
mapperZoom->setMapping( m_arrayActions[ZOOM_OUT_ACT], 80 );
connect( m_arrayActions[ZOOM_OUT_ACT], &QAction::triggered, [this] { scaleFrame( 80 ); } );
m_arrayActions[ZOOM_NORMAL_ACT] = new QAction( tr( "&Normal Size" ), this );
m_arrayActions[ZOOM_NORMAL_ACT]->setIcon( QIcon::fromTheme( "zoom-original" ) );
@@ -802,12 +840,9 @@ void MainWindow::createMenus()
menuBar()->addMenu( m_appModuleVideo->createVideoMenu() );
menuBar()->addMenu( m_appModuleVideo->createImageMenu() );
QMenu* QualityMenu = m_appModuleQuality->createMenu();
menuBar()->addMenu( QualityMenu );
QMenu* ModuleMenu = m_appModuleExtensions->createMenu();
menuBar()->addMenu( ModuleMenu );
QMenu* windowMenu = m_pcWindowHandle->createMenu();
menuBar()->addMenu( windowMenu );
menuBar()->addMenu( m_appModuleQuality->createMenu() );
menuBar()->addMenu( m_appModuleExtensions->createMenu() );
menuBar()->addMenu( m_pcWindowHandle->createMenu() );
menuBar()->addSeparator();
@@ -822,19 +857,17 @@ void MainWindow::createMenus()
void MainWindow::createToolBars()
{
m_arrayToolBars.resize( TOTAL_TOOLBAR );
auto* fileToolbar = addToolBar( tr( "File" ) );
fileToolbar->addAction( m_arrayActions[OPEN_ACT] );
fileToolbar->addAction( m_arrayActions[SAVE_ACT] );
fileToolbar->addAction( m_arrayActions[FORMAT_ACT] );
fileToolbar->addAction( m_arrayActions[RELOAD_ACT] );
fileToolbar->addAction( m_arrayActions[CLOSE_ACT] );
fileToolbar->setMovable( false );
addToolBar( Qt::TopToolBarArea, fileToolbar );
m_arrayToolBars[FILE_TOOLBAR] = new QToolBar( tr( "File" ) );
m_arrayToolBars[FILE_TOOLBAR]->addAction( m_arrayActions[OPEN_ACT] );
m_arrayToolBars[FILE_TOOLBAR]->addAction( m_arrayActions[SAVE_ACT] );
m_arrayToolBars[FILE_TOOLBAR]->addAction( m_arrayActions[FORMAT_ACT] );
m_arrayToolBars[FILE_TOOLBAR]->addAction( m_arrayActions[RELOAD_ACT] );
m_arrayToolBars[FILE_TOOLBAR]->addAction( m_arrayActions[CLOSE_ACT] );
auto* viewToolBar = addToolBar( tr( "View" ) );
m_arrayToolBars[FILE_TOOLBAR]->setMovable( false );
addToolBar( Qt::TopToolBarArea, m_arrayToolBars[FILE_TOOLBAR] );
m_arrayToolBars[VIEW_TOOLBAR] = new QToolBar( tr( "View" ) );
m_pcZoomFactorSBox = new QDoubleSpinBox;
m_pcZoomFactorSBox->setRange( 1.0, 10000.0 );
m_pcZoomFactorSBox->setDecimals( 0 );
@@ -842,14 +875,15 @@ void MainWindow::createToolBars()
m_pcZoomFactorSBox->setValue( 100.0 );
m_pcZoomFactorSBox->setSuffix( "%" );
connect( m_pcZoomFactorSBox, SIGNAL( valueChanged( double ) ), this, SLOT( zoomFromSBox( double ) ) );
m_arrayToolBars[VIEW_TOOLBAR]->addWidget( m_pcZoomFactorSBox );
m_arrayToolBars[VIEW_TOOLBAR]->addAction( m_arrayActions[ZOOM_IN_ACT] );
m_arrayToolBars[VIEW_TOOLBAR]->addAction( m_arrayActions[ZOOM_OUT_ACT] );
m_arrayToolBars[VIEW_TOOLBAR]->addAction( m_arrayActions[ZOOM_NORMAL_ACT] );
m_arrayToolBars[VIEW_TOOLBAR]->addAction( m_arrayActions[ZOOM_FIT_ACT] );
m_arrayToolBars[FILE_TOOLBAR]->setMovable( false );
addToolBar( Qt::TopToolBarArea, m_arrayToolBars[VIEW_TOOLBAR] );
viewToolBar->addWidget( m_pcZoomFactorSBox );
viewToolBar->addAction( m_arrayActions[ZOOM_IN_ACT] );
viewToolBar->addAction( m_arrayActions[ZOOM_OUT_ACT] );
viewToolBar->addAction( m_arrayActions[ZOOM_NORMAL_ACT] );
viewToolBar->addAction( m_arrayActions[ZOOM_FIT_ACT] );
viewToolBar->setMovable( false );
addToolBar( Qt::TopToolBarArea, viewToolBar );
addToolBar( Qt::TopToolBarArea, m_appModuleVideo->createToolBar() );
}
@@ -872,12 +906,17 @@ void MainWindow::createStatusBar()
void MainWindow::addStreamInfoToRecentList( CalypFileInfo streamInfo )
{
int idx = findCalypStreamInfo( m_aRecentFileStreamInfo, streamInfo.m_cFilename );
if( idx >= 0 )
m_aRecentFileStreamInfo.remove( idx );
if( idx >= 0 ) m_aRecentFileStreamInfo.remove( idx );
m_aRecentFileStreamInfo.prepend( streamInfo );
while( m_aRecentFileStreamInfo.size() > MAX_RECENT_FILES )
{
m_aRecentFileStreamInfo.remove( m_aRecentFileStreamInfo.size() - 1 );
}
updateRecentFileActions();
QSettings appSettings;
QVariant var;
var.setValue( m_aRecentFileStreamInfo );
appSettings.setValue( "MainWindow/RecentFileList", var );
}
void MainWindow::updateRecentFileActions()
@@ -917,6 +956,7 @@ void MainWindow::checkRecentFileActions()
else
{
unsigned long long int fileSize = QFileInfo( m_aRecentFileStreamInfo.at( i ).m_cFilename ).size();
std::cout << m_aRecentFileStreamInfo.at( i ).m_uiFileSize << std::endl;
if( m_aRecentFileStreamInfo.at( i ).m_uiFileSize != fileSize )
{
m_aRecentFileStreamInfo.remove( i );
@@ -936,7 +976,10 @@ void MainWindow::readSettings()
move( pos );
resize( size );
m_cLastOpenPath = appSettings.value( "MainWindow/LastOpenPath", QDir::homePath() ).toString();
m_lastOpenPath = appSettings.value( "MainWindow/LastOpenPath", QDir::homePath() ).toString();
m_lastOpenWidth = appSettings.value( "MainWindow/LastWidth" ).value<unsigned int>();
m_lastOpenHeight = appSettings.value( "MainWindow/LastHeight" ).value<unsigned int>();
m_lastOpenBitPerPixel = appSettings.value( "MainWindow/LastBitsPerPixel" ).value<unsigned int>();
QVariant value = appSettings.value( "MainWindow/RecentFileList" );
m_aRecentFileStreamInfo = value.value<CalypFileInfoVector>();
@@ -955,10 +998,13 @@ void MainWindow::writeSettings()
appSettings.setValue( "MainWindow/Position", pos() );
appSettings.setValue( "MainWindow/Size", size() );
appSettings.setValue( "MainWindow/LastOpenPath", m_cLastOpenPath );
appSettings.setValue( "MainWindow/LastOpenPath", m_lastOpenPath );
appSettings.setValue( "MainWindow/LastWidth", m_lastOpenWidth );
appSettings.setValue( "MainWindow/LastHeight", m_lastOpenHeight );
appSettings.setValue( "MainWindow/LastBitsPerPixel", m_lastOpenBitPerPixel );
QVariant var;
var.setValue<CalypFileInfoVector>( m_aRecentFileStreamInfo );
var.setValue( m_aRecentFileStreamInfo );
appSettings.setValue( "MainWindow/RecentFileList", var );
m_appModuleVideo->writeSettings();
+23 -26
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -36,16 +36,20 @@
#ifndef __MAINWINDOW_H__
#define __MAINWINDOW_H__
#include <QMainWindow>
#include <QString>
#include <QVector>
#include <optional>
#include "CommonDefs.h"
#include "VideoStreamSubWindow.h"
#include "VideoSubWindow.h"
#include "config.h"
#ifdef USE_QTDBUS
#include "DBusAppAdaptor.h"
#endif
#include <QMainWindow>
#include <QString>
#include <QVector>
#include "ResourceHandle.h"
#include "VideostreamResource.h"
class QCloseEvent;
class QDragEnterEvent;
@@ -58,6 +62,7 @@ class QSignalMapper;
class CalypOptions;
class CalypStream;
class SubWindowHandle;
class VideoStreamSubWindow;
class VideoHandle;
class QualityHandle;
class ModulesHandle;
@@ -73,7 +78,8 @@ class MainWindow : public QMainWindow
public:
MainWindow();
bool parseArgs( int argc, char* argv[] );
void loadFile( QString fileName, CalypFileInfo* pStreamInfo = NULL );
void loadFile( const CalypFileInfo& pStreamInfo );
void loadFile( const QString& fileName, std::optional<CalypFileInfo> streamInfoOpt = {}, bool forceDialog = false );
public Q_SLOTS:
void printMessage( const QString& msg );
@@ -114,7 +120,7 @@ private Q_SLOTS:
void dragEnterEvent( QDragEnterEvent* event );
void dropEvent( QDropEvent* event );
void update();
void updateMainWindow();
void updateZoomFactorSBox();
private:
@@ -123,14 +129,17 @@ private:
/**
* Save the current subwindow for every category
*/
SubWindowAbstract* m_pcCurrentSubWindow; //!< General always set
VideoSubWindow* m_pcCurrentVideoSubWindow;
// SubWindowAbstract* m_pcCurrentSubWindow; //!< General always set
// VideoSubWindow* m_pcCurrentVideoSubWindow;
QString m_cLastOpenPath;
QString m_lastOpenPath;
unsigned int m_lastOpenWidth;
unsigned int m_lastOpenHeight;
unsigned int m_lastOpenBitPerPixel;
QStringList showFileDialog( bool bRead );
static VideoSubWindow* findVideoStreamSubWindow( const SubWindowHandle* windowManager,
const QString& fileName );
static VideoStreamSubWindow* findVideoStreamSubWindow( const SubWindowHandle* windowManager,
const QString& fileName );
void updateMenus();
@@ -149,7 +158,6 @@ private:
QDoubleSpinBox* m_pcZoomFactorSBox;
QSignalMapper* mapperZoom;
QSignalMapper* mapperWindow;
/**
@@ -158,6 +166,7 @@ private:
* Quality
* Modules
*/
std::unique_ptr<ResourceHandle> m_appResourceHandle;
VideoHandle* m_appModuleVideo;
QualityHandle* m_appModuleQuality;
ModulesHandle* m_appModuleExtensions;
@@ -193,18 +202,6 @@ private:
};
QVector<QDockWidget*> m_arraySideBars;
/**
* Array of tool bars for the main app
*/
enum TOOLBAR_LIST
{
FILE_TOOLBAR = 0,
VIEW_TOOLBAR,
VIDEO_TOOLBAR,
TOTAL_TOOLBAR,
};
QVector<QToolBar*> m_arrayToolBars;
/**
* Array of actions for the main app
*/
@@ -237,7 +234,7 @@ private:
QVector<QAction*> m_arrayRecentFilesActions;
CalypFileInfoVector m_aRecentFileStreamInfo;
AboutDialog* m_pcAboutDialog;
AboutDialog* m_pcAboutDialog{ nullptr };
};
#endif // __MAINWINDOW_H__
+4 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,15 +24,15 @@
#include "MdiSubWindow.h"
#include "SubWindowAbstract.h"
#include <QCloseEvent>
#include "SubWindowAbstract.h"
MdiSubWindow::MdiSubWindow( QWidget* parent )
: QMdiSubWindow( parent )
{
setAttribute( Qt::WA_DeleteOnClose );
setBackgroundRole( QPalette::Background );
setBackgroundRole( QPalette::Window );
}
QSize MdiSubWindow::sizeHint() const
+2 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
#define __MDISUBWINDOW_H_
#include <QMdiSubWindow>
#include "CommonDefs.h"
#include "config.h"
+114
View File
@@ -0,0 +1,114 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file ModuleSubWindow.cpp
* \brief Video Sub windows handling
*/
#include "ModuleSubWindow.h"
#include <QSettings>
#include <QStaticText>
#include <cassert>
#include "ModulesHandle.h"
ModuleSubWindow::ModuleSubWindow( CalypAppModuleIf* module, QWidget* parent )
: VideoSubWindow( VideoSubWindow::MODULE_SUBWINDOW, parent )
{
m_pcDisplayModule = module;
}
ModuleSubWindow::~ModuleSubWindow()
{
}
void ModuleSubWindow::resetWindowName()
{
QString windowName{ "Module" };
if( auto module_ptr = m_pcDisplayModule )
{
windowName.append( " " ).append( module_ptr->getModule()->m_pchModuleLongName );
}
setWindowName( windowName );
}
void ModuleSubWindow::updateVideoWindowInfo()
{
m_cStreamInformation = "";
m_cStreamInformation = "Module";
if( auto module_ptr = m_pcDisplayModule )
{
const auto& arraySubWindows = module_ptr->getSubWindowList();
QStringList windowInfoList;
if( arraySubWindows.size() > 0 )
{
for( std::size_t i = 0; i < arraySubWindows.size(); i++ )
{
if( arraySubWindows[i]->getWindowName() != getWindowName() )
{
windowInfoList.append( QString( "Input %1 - " + arraySubWindows[i]->getWindowName() ).arg( i + 1 ) );
}
}
}
if( module_ptr->hasFeature( ClpModuleFeature::HasInfo ) )
{
QStringList list = QString::fromStdString( module_ptr->moduleInfo() ).split( '\n' );
windowInfoList.append( list );
}
if( windowInfoList.size() > 0 )
{
m_pcVideoInfo->setInformationTopLeft( windowInfoList );
}
}
if( m_pcCurrFrameAsset )
{
QString m_cPelFmtName = QString::fromStdString( m_pcCurrFrameAsset->getPelFmtName() );
m_cStreamInformation += " | " + m_cPelFmtName;
}
if( m_cStreamInformation.isEmpty() )
{
m_cStreamInformation = " ";
}
}
bool ModuleSubWindow::isPlaying()
{
if( auto module_ptr = m_pcDisplayModule )
{
for( auto window : module_ptr->getSubWindowList() )
{
if( window->isPlaying() )
return true;
}
}
return false;
}
void ModuleSubWindow::refreshSubWindow()
{
if( auto module_ptr = m_pcDisplayModule )
{
setFillWindow( true );
updateVideoWindowInfo();
module_ptr->apply( isPlaying(), false );
}
}
+64
View File
@@ -0,0 +1,64 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file ModuleSubWindow.h
* \brief Video Sub windows handling
*/
#ifndef __MODULESUBWINDOW_H__
#define __MODULESUBWINDOW_H__
#include <QDataStream>
#include <QFuture>
#include <QRect>
#include <QString>
#include <QVector>
#include "CalypAppModuleIf.h"
#include "CommonDefs.h"
#include "VideoSubWindow.h"
#include "config.h"
#include "lib/CalypStream.h"
class VideoInformation;
class ModuleSubWindow : public VideoSubWindow
{
Q_OBJECT
public:
ModuleSubWindow( CalypAppModuleIf* module, QWidget* parent = 0 );
~ModuleSubWindow();
void resetWindowName();
void updateVideoWindowInfo();
bool isPlaying();
void stop(){};
void advanceOneFrame(){};
auto getFrameNum() -> std::uint64_t { return 1; };
void refreshSubWindow();
void setCurrFrame( std::shared_ptr<CalypFrame> pcCurrFrame );
};
#endif // __MODULESUBWINDOW_H__
+109 -130
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@
#include <cstdio>
#include "MainWindow.h"
#include "ModuleSubWindow.h"
#include "ModulesHandleOptDialog.h"
#include "SubWindowHandle.h"
#include "SubWindowSelectorDialog.h"
@@ -35,7 +36,7 @@
#include "modules/CalypModulesFactory.h"
ModulesHandle::ModulesHandle( QWidget* parent, SubWindowHandle* windowManager, VideoHandle* moduleVideo )
: QWidget( parent ), m_pcParent( parent ), m_pcMainWindowManager( windowManager ), m_appModuleVideo( moduleVideo )
: m_pcParent( parent ), m_pcMainWindowManager( windowManager ), m_appModuleVideo( moduleVideo )
{
setParent( m_pcParent );
}
@@ -50,32 +51,32 @@ void ModulesHandle::createActions()
connect( m_pcActionMapper, SIGNAL( mapped( int ) ), this, SLOT( processOpt( int ) ) );
// m_arrayActions[FORCE_PLAYING_REFRESH_ACT] = new QAction( "Refresh while
// playing", parent() );
// playing", m_pcParent );
// m_arrayActions[FORCE_PLAYING_REFRESH_ACT]->setStatusTip( "Force module
// refreshing while playing" );
// m_arrayActions[FORCE_PLAYING_REFRESH_ACT]->setCheckable( true );
m_arrayActions[LOAD_EXTERNAL_ACT] = new QAction( "Load external module", parent() );
m_arrayActions[LOAD_EXTERNAL_ACT] = new QAction( "Load external module", m_pcParent );
m_arrayActions[LOAD_EXTERNAL_ACT]->setStatusTip( "Load an externally build module" );
connect( m_arrayActions[LOAD_EXTERNAL_ACT], SIGNAL( triggered() ), this, SLOT( loadExternalModule() ) );
connect( m_arrayActions[LOAD_EXTERNAL_ACT], &QAction::triggered, this, &ModulesHandle::loadExternalModule );
m_arrayActions[APPLY_ALL_ACT] = new QAction( "Apply to All", parent() );
m_arrayActions[APPLY_ALL_ACT] = new QAction( "Apply to All", m_pcParent );
m_arrayActions[APPLY_ALL_ACT]->setStatusTip( "Apply module to all frames and save the result" );
connect( m_arrayActions[APPLY_ALL_ACT], SIGNAL( triggered() ), m_pcActionMapper, SLOT( map() ) );
m_pcActionMapper->setMapping( m_arrayActions[APPLY_ALL_ACT], APPLY_ALL_ACT );
m_arrayActions[SWAP_FRAMES_ACT] = new QAction( "Swap frames", parent() );
m_arrayActions[SWAP_FRAMES_ACT] = new QAction( "Swap frames", m_pcParent );
m_arrayActions[SWAP_FRAMES_ACT]->setStatusTip( "Swap Sub Window order" );
connect( m_arrayActions[SWAP_FRAMES_ACT], SIGNAL( triggered() ), m_pcActionMapper, SLOT( map() ) );
m_pcActionMapper->setMapping( m_arrayActions[SWAP_FRAMES_ACT], SWAP_FRAMES_ACT );
m_arrayActions[DISABLE_ACT] = new QAction( "Disable Modules", parent() );
connect( m_arrayActions[DISABLE_ACT], SIGNAL( triggered() ), this, SLOT( destroyWindowModules() ) );
m_arrayActions[DISABLE_ACT] = new QAction( "Disable Modules", m_pcParent );
connect( m_arrayActions[DISABLE_ACT], &QAction::triggered, this, &ModulesHandle::destroyWindowModules );
m_arrayActions[DISABLE_ALL_ACT] = new QAction( "Disable All Modules", parent() );
connect( m_arrayActions[DISABLE_ALL_ACT], SIGNAL( triggered() ), this, SLOT( destroyAllModulesIf() ) );
m_arrayActions[DISABLE_ALL_ACT] = new QAction( "Disable All Modules", m_pcParent );
connect( m_arrayActions[DISABLE_ALL_ACT], &QAction::triggered, this, &ModulesHandle::destroyAllModulesIf );
m_arrayActions[FORCE_NEW_WINDOW_ACT] = new QAction( "Use New Window", parent() );
m_arrayActions[FORCE_NEW_WINDOW_ACT] = new QAction( "Use New Window", m_pcParent );
m_arrayActions[FORCE_NEW_WINDOW_ACT]->setStatusTip(
"Show module result in a new window. Some modules already force this "
"feature" );
@@ -84,34 +85,28 @@ void ModulesHandle::createActions()
QMenu* ModulesHandle::createMenu()
{
m_pcModulesMenu = new QMenu( "&Modules", this );
m_pcModulesMenu = new QMenu( "&Modules", m_pcParent );
buildMenu();
return m_pcModulesMenu;
}
void ModulesHandle::buildMenu()
{
CalypModuleIf* pcCurrModuleIf;
QString ModuleIfinternalName;
QAction* currAction;
QMenu* currSubMenu;
for( int i = 0; i < m_arrayModulesActions.size(); i++ )
for( auto& action : m_arrayModulesActions )
{
delete m_arrayModulesActions.at( i );
delete action;
}
m_arrayModulesActions.clear();
m_pcModulesMenu->clear();
m_pcModulesSubMenuList.clear();
CalypModulesFactoryMap& moduleFactoryMap = CalypModulesFactory::Get()->getMap();
CalypModulesFactoryMap::iterator it = moduleFactoryMap.begin();
for( ; it != moduleFactoryMap.end(); ++it )
const auto& moduleFactoryMap = CalypModulesFactory::Get()->getMap();
for( auto& [name, create_fct] : moduleFactoryMap )
{
pcCurrModuleIf = it->second();
ModuleIfinternalName = QString::fromLocal8Bit( it->first );
auto pcCurrModuleIf = create_fct();
QString moduleIfInternalName = QString::fromStdString( name );
currSubMenu = NULL;
QMenu* currSubMenu{ nullptr };
if( pcCurrModuleIf->m_iModuleAPI <= CLP_MODULE_API_2 )
{
if( pcCurrModuleIf->m_pchModuleCategory )
@@ -132,23 +127,21 @@ void ModulesHandle::buildMenu()
}
}
currAction = new QAction( pcCurrModuleIf->getModuleLongName(), parent() );
QAction* currAction = new QAction( pcCurrModuleIf->getModuleLongName(), m_pcParent );
QString moduleTooltip = pcCurrModuleIf->m_pchModuleTooltip;
if( pcCurrModuleIf->m_uiNumberOfFrames > 1 )
moduleTooltip += QString( " | Requires %1 frames" ).arg( pcCurrModuleIf->m_uiNumberOfFrames );
currAction->setStatusTip( moduleTooltip );
currAction->setData( ModuleIfinternalName );
currAction->setData( moduleIfInternalName );
currAction->setCheckable( false );
connect( currAction, SIGNAL( triggered() ), this, SLOT( activateModule() ) );
connect( currAction, &QAction::triggered, this, &ModulesHandle::activateModule );
m_arrayModulesActions.append( currAction );
if( currSubMenu )
currSubMenu->addAction( currAction );
else
m_pcModulesMenu->addAction( currAction );
pcCurrModuleIf->Delete();
}
m_pcModulesMenu->addAction( m_arrayActions[LOAD_EXTERNAL_ACT] );
@@ -162,20 +155,20 @@ void ModulesHandle::buildMenu()
void ModulesHandle::updateMenus()
{
VideoSubWindow* pcSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
bool hasSubWindow = pcSubWindow ? true : false;
QAction* currModuleAction;
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
bool hasSubWindow = pcSubWindow != nullptr ? true : false;
for( int i = 0; i < m_arrayModulesActions.size(); i++ )
{
currModuleAction = m_arrayModulesActions.at( i );
//currModuleAction->setEnabled( hasSubWindow );
auto* currModuleAction = m_arrayModulesActions.at( i );
// currModuleAction->setEnabled( hasSubWindow );
currModuleAction->setChecked( false );
}
//for( int i = 0; i < m_pcModulesSubMenuList.size(); i++ )
// for( int i = 0; i < m_pcModulesSubMenuList.size(); i++ )
//{
// m_pcModulesSubMenuList.at( i )->setEnabled( hasSubWindow );
//}
// }
for( int i = 0; i < m_arrayActions.size(); i++ )
{
@@ -183,22 +176,21 @@ void ModulesHandle::updateMenus()
}
m_arrayActions[LOAD_EXTERNAL_ACT]->setEnabled( true );
m_arrayActions[FORCE_NEW_WINDOW_ACT]->setEnabled( hasSubWindow );
m_arrayActions[DISABLE_ALL_ACT]->setEnabled( m_pcCalypAppModuleIfList.size() > 0 );
m_arrayActions[DISABLE_ALL_ACT]->setEnabled( true );
if( pcSubWindow )
{
QList<CalypAppModuleIf*> apcCurrentModule = pcSubWindow->getModuleArray();
m_arrayActions[DISABLE_ACT]->setEnabled( apcCurrentModule.size() > 0 );
m_arrayActions[DISABLE_ACT]->setEnabled( pcSubWindow->hasModules() );
if( pcSubWindow->getDisplayModule() )
{
m_arrayActions[APPLY_ALL_ACT]->setEnabled( true );
m_arrayActions[SWAP_FRAMES_ACT]->setEnabled( true );
}
for( int i = 0; i < apcCurrentModule.size(); i++ )
{
currModuleAction = apcCurrentModule.at( i )->m_pcModuleAction;
currModuleAction->setChecked( true );
}
// for( int i = 0; i < apcCurrentModule.size(); i++ )
// {
// currModuleAction = apcCurrentModule.at( i )->m_pcModuleAction;
// currModuleAction->setChecked( true );
// }
}
}
@@ -216,22 +208,21 @@ void ModulesHandle::writeSettings()
void ModulesHandle::processOpt( int index )
{
VideoSubWindow* pcSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcSubWindow )
{
CalypAppModuleIf* pcCurrentModule = pcSubWindow->getDisplayModule();
if( pcCurrentModule )
{
CalypAppModuleIf* pcCurrModule = pcCurrentModule;
switch( index )
{
case INVALID_OPT:
break;
case SWAP_FRAMES_ACT:
swapModulesWindowsIf( pcCurrModule );
swapModulesWindowsIf( pcCurrentModule );
break;
case APPLY_ALL_ACT:
applyAllModuleIf( pcCurrModule );
applyAllModuleIf( pcCurrentModule );
break;
default:
Q_ASSERT( 0 );
@@ -266,7 +257,7 @@ void ModulesHandle::activateModule()
Qt::KeyboardModifiers keyModifiers = QApplication::keyboardModifiers();
bool bTmpForceNewWindow = false;
VideoSubWindow* pcVideoSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcVideoSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( !pcVideoSubWindow )
{
return;
@@ -278,9 +269,12 @@ void ModulesHandle::activateModule()
}
QString ModuleIfName = pcAction->data().toString();
CalypModuleIf* pcCurrModuleIf =
CalypModulesFactory::Get()->CreateModule( ModuleIfName.toLocal8Bit().constData() );
CalypAppModuleIf* pcCurrAppModuleIf = new CalypAppModuleIf( this, pcAction, pcCurrModuleIf );
auto pcCurrModuleIf = CalypModulesFactory::Get()->CreateModule( ModuleIfName.toLocal8Bit().constData() );
if( pcCurrModuleIf == nullptr )
{
return;
}
auto pcCurrAppModuleIf = std::make_shared<CalypAppModuleIf>( this, pcAction, std::move( pcCurrModuleIf ) );
QList<VideoSubWindow*> videoSubWindowList;
int numberOfFrames = pcCurrAppModuleIf->m_pcModule->m_uiNumberOfFrames;
@@ -288,7 +282,7 @@ void ModulesHandle::activateModule()
{
int minNumFrames = numberOfFrames;
int maxNumFrames = numberOfFrames;
if( pcCurrAppModuleIf->m_pcModule->m_uiModuleRequirements & CLP_MODULES_VARIABLE_NUM_FRAMES )
if( pcCurrAppModuleIf->m_pcModule->has( ClpModuleFeature::VariableNumOfFrames ) )
{
minNumFrames = numberOfFrames;
maxNumFrames = 255;
@@ -337,7 +331,7 @@ void ModulesHandle::activateModule()
{
videoSubWindowList.clear();
qobject_cast<MainWindow*>( m_pcParent )->printMessage( "Error! Incompatible frames", CLP_LOG_ERROR );
destroyModuleIf( pcCurrAppModuleIf );
// destroyModuleIf( pcCurrAppModuleIf );
return;
}
}
@@ -352,7 +346,7 @@ void ModulesHandle::activateModule()
{
qobject_cast<MainWindow*>( m_pcParent )
->printMessage( "Error! There is no windows to apply the module", CLP_LOG_ERROR );
destroyModuleIf( pcCurrAppModuleIf );
// destroyModuleIf( pcCurrAppModuleIf );
return;
}
@@ -361,13 +355,13 @@ void ModulesHandle::activateModule()
pcCurrAppModuleIf->m_pcSubWindow[i] = videoSubWindowList.at( i );
}
if( pcCurrAppModuleIf->m_pcModule->m_uiModuleRequirements & CLP_MODULE_REQUIRES_OPTIONS )
if( pcCurrAppModuleIf->m_pcModule->has( ClpModuleFeature::Options ) )
{
ModulesHandleOptDialog moduleOptDialog( m_pcParent, pcCurrAppModuleIf );
ModulesHandleOptDialog moduleOptDialog( m_pcParent, pcCurrAppModuleIf.get() );
if( moduleOptDialog.runConfiguration() == QDialog::Rejected )
{
qobject_cast<MainWindow*>( m_pcParent )->printMessage( "Module canceled by user!", CLP_LOG_WARNINGS );
destroyModuleIf( pcCurrAppModuleIf );
// destroyModuleIf( pcCurrAppModuleIf );
return;
}
}
@@ -376,14 +370,12 @@ void ModulesHandle::activateModule()
QString windowName;
VideoSubWindow* pcModuleSubWindow = NULL;
if( pcCurrAppModuleIf->m_pcModule->m_iModuleType == CLP_FRAME_PROCESSING_MODULE )
if( pcCurrAppModuleIf->m_pcModule->m_iModuleType == ClpModuleType::FrameProcessing )
{
if( ( pcCurrAppModuleIf->m_pcModule->m_uiModuleRequirements & CLP_MODULE_REQUIRES_NEW_WINDOW ) || bShowModulesNewWindow )
if( bShowModulesNewWindow || pcCurrAppModuleIf->m_pcModule->has( ClpModuleFeature::NewWindow ) )
{
pcModuleSubWindow = new VideoSubWindow( VideoSubWindow::MODULE_SUBWINDOW );
windowName.append( QStringLiteral( "Module " ) );
windowName.append( pcCurrAppModuleIf->m_pcModule->m_pchModuleLongName );
auto pcModuleSubWindow = new ModuleSubWindow( pcCurrAppModuleIf.get() );
pcModuleSubWindow->resetWindowName();
pcCurrAppModuleIf->m_pcDisplaySubWindow = pcModuleSubWindow;
// connect( pcModuleSubWindow->getViewArea(), SIGNAL( selectionChanged( QRect ) ), m_appModuleVideo,
// SLOT( updateSelectionArea( QRect ) ) );
@@ -392,11 +384,15 @@ void ModulesHandle::activateModule()
// connect( pcModuleSubWindow, SIGNAL( scrollBarMoved_SWindow( const QPoint ) ), m_appModuleVideo,
// SLOT( moveAllScrollBars( const QPoint ) ) );
}
else
{
pcCurrAppModuleIf->m_pcSubWindow[0]->setDisplayModule( pcCurrAppModuleIf.get() );
}
}
else if( pcCurrAppModuleIf->m_pcModule->m_iModuleType == CLP_FRAME_MEASUREMENT_MODULE )
else if( pcCurrAppModuleIf->m_pcModule->m_iModuleType == ClpModuleType::FrameMeasurement )
{
pcCurrAppModuleIf->m_pcDisplaySubWindow = NULL;
pcCurrAppModuleIf->m_pcModuleDock = new ModuleHandleDock( m_pcParent, pcCurrAppModuleIf );
pcCurrAppModuleIf->m_pcModuleDock = new ModuleHandleDock( m_pcParent, pcCurrAppModuleIf.get() );
QString titleDockWidget;
titleDockWidget.append( pcCurrAppModuleIf->m_pcModule->m_pchModuleName );
titleDockWidget.append( " Information" );
@@ -408,19 +404,9 @@ void ModulesHandle::activateModule()
->addDockWidget( Qt::RightDockWidgetArea, pcCurrAppModuleIf->m_pcDockWidget );
}
// Associate module with subwindows
if( !pcCurrAppModuleIf->m_pcDisplaySubWindow && !pcCurrAppModuleIf->m_pcModuleDock )
for( int i = 0; i < videoSubWindowList.size(); i++ )
{
pcCurrAppModuleIf->m_pcSubWindow[0]->enableModule( pcCurrAppModuleIf );
}
else
{
if( pcCurrAppModuleIf->m_pcDisplaySubWindow )
pcCurrAppModuleIf->m_pcDisplaySubWindow->enableModule( pcCurrAppModuleIf );
for( int i = 0; i < videoSubWindowList.size(); i++ )
{
pcCurrAppModuleIf->m_pcSubWindow[i]->associateModule( pcCurrAppModuleIf );
}
pcCurrAppModuleIf->m_pcSubWindow[i]->associateModule( pcCurrAppModuleIf );
}
// Create Module
@@ -443,19 +429,19 @@ void ModulesHandle::activateModule()
if( !moduleCreated )
{
qobject_cast<MainWindow*>( m_pcParent )->printMessage( "Error! Module cannot be created", CLP_LOG_ERROR );
destroyModuleIf( pcCurrAppModuleIf );
// destroyModuleIf( pcCurrAppModuleIf );
return;
}
pcCurrAppModuleIf->apply( false, true );
QCoreApplication::processEvents();
if( pcModuleSubWindow )
if( pcCurrAppModuleIf->m_pcDisplaySubWindow )
{
pcModuleSubWindow->setWindowName( windowName );
m_pcMainWindowManager->addSubWindow( pcModuleSubWindow );
pcModuleSubWindow->show();
m_appModuleVideo->addSubWindow( pcModuleSubWindow );
m_pcMainWindowManager->addSubWindow( pcCurrAppModuleIf->m_pcDisplaySubWindow );
pcCurrAppModuleIf->m_pcDisplaySubWindow->show();
m_appModuleVideo->addSubWindow( pcCurrAppModuleIf->m_pcDisplaySubWindow );
}
else
{
@@ -465,44 +451,39 @@ void ModulesHandle::activateModule()
videoSubWindowList.at( 0 )->setWindowName( windowName );
}
m_pcCalypAppModuleIfList.append( pcCurrAppModuleIf );
// Change ownership of the module
// if( !pcCurrAppModuleIf->m_pcDisplaySubWindow && !pcCurrAppModuleIf->m_pcModuleDock )
// {
// pcCurrAppModuleIf->m_pcSubWindow[0]->enableModule( pcCurrAppModuleIf );
// }
// else if( pcCurrAppModuleIf->m_pcDisplaySubWindow )
// {
// pcCurrAppModuleIf->m_pcDisplaySubWindow->enableModule( pcCurrAppModuleIf );
// }
emit changed();
}
void ModulesHandle::destroyModuleIf( CalypAppModuleIf* pcCurrModuleIf )
{
if( pcCurrModuleIf )
{
pcCurrModuleIf->destroy();
}
}
void ModulesHandle::destroyWindowModules()
{
VideoSubWindow* pcVideoSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcVideoSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcVideoSubWindow )
{
pcVideoSubWindow->disableModule();
pcVideoSubWindow->disableAllModules();
emit changed();
}
}
void ModulesHandle::destroyAllModulesIf()
{
for( int i = 0; i < m_pcCalypAppModuleIfList.size(); i++ )
bool emit_changed = false;
QList<SubWindowAbstract*> windowsList = m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW );
for( auto window : windowsList )
{
destroyModuleIf( m_pcCalypAppModuleIfList.at( i ) );
}
emit changed();
}
void ModulesHandle::applyModuleIf( QList<CalypAppModuleIf*> pcCurrModuleIfList, bool isPlaying, bool disableThreads )
{
for( int i = 0; i < pcCurrModuleIfList.size() && !isPlaying; i++ )
{
pcCurrModuleIfList.at( i )->apply( isPlaying, disableThreads );
emit_changed |= qobject_cast<VideoSubWindow*>( window )->disableAllModules();
}
if( emit_changed )
emit changed();
}
void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf )
@@ -511,21 +492,18 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf )
{
if( !pcCurrModuleIf->m_pcModuleStream )
{
unsigned int Width = 0, Height = 0, FrameRate = 30;
int BitsPixel, InputFormat = -1;
QString supported = tr( "Supported Files (" );
QStringList formatsList;
std::vector<CalypStreamFormat> supportedFmts = CalypStream::supportedWriteFormats();
for( unsigned int i = 0; i < supportedFmts.size(); i++ )
{
std::vector<ClpString> arrayExt = supportedFmts[i].getExts();
std::vector<std::string> arrayExt = supportedFmts[i].getExts();
if( arrayExt.size() > 0 )
{
QString currFmt( QString::fromStdString( supportedFmts[i].formatName ) );
currFmt.append( " (" );
for( std::vector<ClpString>::iterator e = arrayExt.begin(); e != arrayExt.end(); ++e )
for( std::vector<std::string>::iterator e = arrayExt.begin(); e != arrayExt.end(); ++e )
{
supported.append( " *." );
currFmt.append( "*." );
@@ -546,18 +524,17 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf )
{
return;
}
Width = pcCurrModuleIf->m_pcProcessedFrame->getWidth();
Height = pcCurrModuleIf->m_pcProcessedFrame->getHeight();
InputFormat = pcCurrModuleIf->m_pcProcessedFrame->getPelFormat();
BitsPixel = pcCurrModuleIf->m_pcProcessedFrame->getBitsPel();
FrameRate = pcCurrModuleIf->m_pcSubWindow[0]->getInputStream()->getFrameRate();
auto Width = pcCurrModuleIf->m_pcProcessedFrame->getWidth();
auto Height = pcCurrModuleIf->m_pcProcessedFrame->getHeight();
auto InputFormat = pcCurrModuleIf->m_pcProcessedFrame->getPelFormat();
auto BitsPixel = pcCurrModuleIf->m_pcProcessedFrame->getBitsPel();
auto FrameRate = 30;
pcCurrModuleIf->m_pcModuleStream = new CalypStream;
pcCurrModuleIf->m_pcModuleStream = std::unique_ptr<CalypStream>();
if( !pcCurrModuleIf->m_pcModuleStream->open( fileName.toStdString(), Width, Height, InputFormat, BitsPixel,
CLP_LITTLE_ENDIAN, FrameRate, false ) )
CLP_LITTLE_ENDIAN, FrameRate, CalypStream::Type::Output ) )
{
delete pcCurrModuleIf->m_pcModuleStream;
pcCurrModuleIf->m_pcModuleStream = NULL;
pcCurrModuleIf->m_pcModuleStream = nullptr;
return;
}
}
@@ -565,11 +542,11 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf )
if( pcCurrModuleIf->m_pcModuleStream )
{
unsigned int numberOfWindows = pcCurrModuleIf->m_pcModule->m_uiNumberOfFrames;
ClpULong currFrames = 0;
ClpULong numberOfFrames = -1;
std::uint64_t currFrames = 0;
std::uint64_t numberOfFrames = -1;
for( unsigned int i = 0; i < numberOfWindows; i++ )
{
currFrames = pcCurrModuleIf->m_pcSubWindow[i]->getInputStream()->getFrameNum();
currFrames = pcCurrModuleIf->m_pcSubWindow[i]->getFrameNum();
if( currFrames < numberOfFrames )
numberOfFrames = currFrames;
pcCurrModuleIf->m_pcSubWindow[i]->stop();
@@ -579,11 +556,10 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf )
{
pcCurrModuleIf->apply( false, true );
QCoreApplication::processEvents();
pcCurrModuleIf->m_pcModuleStream->writeFrame( pcCurrModuleIf->m_pcProcessedFrame );
pcCurrModuleIf->m_pcModuleStream->writeFrame( *pcCurrModuleIf->m_pcProcessedFrame );
for( unsigned int i = 0; i < numberOfWindows; i++ )
{
pcCurrModuleIf->m_pcSubWindow[i]->play();
pcCurrModuleIf->m_pcSubWindow[i]->playEvent();
pcCurrModuleIf->m_pcSubWindow[i]->advanceOneFrame();
}
}
for( unsigned int i = 0; i < numberOfWindows; i++ )
@@ -609,12 +585,15 @@ void ModulesHandle::swapModulesWindowsIf( CalypAppModuleIf* pcCurrModuleIf )
void ModulesHandle::customEvent( QEvent* event )
{
if( !event )
{
return;
}
CalypAppModuleIf::EventData* eventData = (CalypAppModuleIf::EventData*)event;
if( eventData->m_bSuccess )
{
event->accept();
// The module could be freed by the time the event is processed
if( eventData->m_pcModule.isNull() )
return;
eventData->m_pcModule->show();
}
}
+5 -10
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,15 +24,14 @@
#ifndef __MODULESHANDLE_H__
#define __MODULESHANDLE_H__
#include "config.h"
#include <QtCore>
#include <QtWidgets>
#include <cstdio>
#include <iostream>
#include <QtCore>
#include <QtWidgets>
#include "CalypAppModuleIf.h"
#include "CommonDefs.h"
#include "config.h"
#include "lib/CalypFrame.h"
class VideoHandle;
@@ -40,7 +39,7 @@ class SubWindowHandle;
class CalypAppModuleIf;
class SubWindowHandle;
class ModulesHandle : public QWidget
class ModulesHandle : public QObject
{
Q_OBJECT
public:
@@ -56,10 +55,6 @@ public:
void readSettings();
void writeSettings();
static void destroyModuleIf( CalypAppModuleIf* pcCurrModuleIf );
static void applyModuleIf( QList<CalypAppModuleIf*> pcCurrModuleIfList, bool isPlaying = false,
bool disableThreads = false );
private:
QWidget* m_pcParent;
SubWindowHandle* m_pcMainWindowManager;
+6 -3
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,8 +24,11 @@
#include "PlotSubWindow.h"
#include <QGuiApplication>
#include <QScreen>
#include <QSize>
#include "qcustomplot.h"
//#include "external/qcustomplot/qcustomplot.h"
void PlotSubWindow::definePlotColors()
{
@@ -174,7 +177,7 @@ QSize PlotSubWindow::sizeHint() const
}
else
{
maxSize = QApplication::desktop()->availableGeometry().size();
maxSize = QGuiApplication::screens()[0]->availableGeometry().size();
}
return sizeHint( maxSize );
}
+3 -3
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,12 +25,12 @@
#ifndef __PLOTWINDOWHANDLE_H__
#define __PLOTWINDOWHANDLE_H__
#include <QtWidgets>
#include "CommonDefs.h"
#include "SubWindowAbstract.h"
#include "config.h"
#include <QtWidgets>
class QCustomPlot;
class PlotSubWindow : public SubWindowAbstract
+20 -22
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,18 +24,17 @@
#include "QualityHandle.h"
#include <QtGui>
#include "PlotSubWindow.h"
#include "ProgressBar.h"
#include "QtConcurrent/qtconcurrentrun.h"
#include "SubWindowHandle.h"
#include "SubWindowSelectorDialog.h"
#include "VideoSubWindow.h"
#include "lib/LibMemory.h"
#include <QtGui>
#include "QtConcurrent/qtconcurrentrun.h"
QualityHandle::QualityHandle( QWidget* parent, SubWindowHandle* windowManager )
: m_pcParet( parent ), m_pcMainWindowManager( windowManager )
: m_pcParent( parent ), m_pcMainWindowManager( windowManager )
{
}
@@ -71,7 +70,7 @@ void QualityHandle::createActions()
QMenu* QualityHandle::createMenu()
{
m_pcMenuQuality = new QMenu( "Quality", this );
m_pcMenuQuality = new QMenu( "Quality", m_pcParent );
m_pcSubMenuQualityMetrics = m_pcMenuQuality->addMenu( "Quality Metrics" );
m_pcSubMenuQualityMetrics->addActions( m_actionGroupQualityMetric->actions() );
m_pcMenuQuality->addAction( m_arrayActions[SELECT_CURR_REF_ACT] );
@@ -83,8 +82,8 @@ QMenu* QualityHandle::createMenu()
QDockWidget* QualityHandle::createDock()
{
m_pcQualityHandleSideBar = new QualityMeasurementSidebar( m_pcParet, m_pcMainWindowManager );
m_pcQualityHandleDock = new QDockWidget( tr( "Quality Measurement" ), this );
m_pcQualityHandleSideBar = new QualityMeasurementSidebar( m_pcParent, m_pcMainWindowManager );
m_pcQualityHandleDock = new QDockWidget( tr( "Quality Measurement" ), m_pcParent );
m_pcQualityHandleDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
m_pcQualityHandleDock->setWidget( m_pcQualityHandleSideBar );
@@ -99,7 +98,7 @@ QDockWidget* QualityHandle::createDock()
void QualityHandle::updateMenus()
{
VideoSubWindow* pcCurrentVideoSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcCurrentVideoSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
bool hasSubWindow = pcCurrentVideoSubWindow ? true : false;
bool hasReference = false;
bool isReference = false;
@@ -157,8 +156,8 @@ void QualityHandle::update( VideoSubWindow* currSubWindow )
void QualityHandle::measureQuality( QVector<VideoSubWindow*> apcWindowList )
{
unsigned numberOfWindows = apcWindowList.size();
ClpULong currFrames = 0;
ClpULong numberOfFrames = -1;
std::uint64_t currFrames = 0;
std::uint64_t numberOfFrames = -1;
//! Check reference window
for( unsigned i = 0; i < numberOfWindows; i++ )
@@ -170,21 +169,20 @@ void QualityHandle::measureQuality( QVector<VideoSubWindow*> apcWindowList )
}
VideoSubWindow* pcReferenceWindow = apcWindowList.at( 0 )->getRefSubWindow();
numberOfFrames = pcReferenceWindow->getInputStream()->getFrameNum();
numberOfFrames = pcReferenceWindow->getFrameNum();
for( unsigned i = 0; i < numberOfWindows; i++ )
{
currFrames = apcWindowList.at( i )->getInputStream()->getFrameNum();
currFrames = apcWindowList.at( i )->getFrameNum();
if( currFrames < numberOfFrames )
numberOfFrames = currFrames;
apcWindowList.at( i )->stop();
}
pcReferenceWindow->stop();
ProgressBar* pcProgressBar = new ProgressBar( m_pcParet, numberOfFrames );
ProgressBar* pcProgressBar = new ProgressBar( m_pcParent, numberOfFrames );
QVector<double>* padQualityValues = new QVector<double>[numberOfWindows + 1];
double* padAverageQuality = new double[numberOfWindows + 1];
double dCurrentQuality;
for( unsigned i = 0; i < numberOfWindows + 1; i++ )
{
@@ -200,12 +198,12 @@ void QualityHandle::measureQuality( QVector<VideoSubWindow*> apcWindowList )
for( unsigned int i = 0; i < numberOfWindows; i++ )
{
pcCurrFrame = apcWindowList.at( i )->getCurrFrame();
dCurrentQuality = pcCurrFrame->getQuality( m_iQualityMetricIdx, pcReferenceFrame, CLP_LUMA );
double dCurrentQuality = pcCurrFrame->getQuality( m_iQualityMetricIdx, pcReferenceFrame, CLP_LUMA );
padAverageQuality[i + 1] = ( padAverageQuality[i + 1] * double( f ) + dCurrentQuality ) / double( f + 1 );
padQualityValues[i + 1].append( dCurrentQuality );
apcWindowList.at( i )->seekRelativeEvent( true );
apcWindowList.at( i )->advanceOneFrame();
}
pcReferenceWindow->seekRelativeEvent( true );
pcReferenceWindow->advanceOneFrame();
pcProgressBar->incrementProgress( 1 );
}
for( unsigned int i = 0; i < numberOfWindows; i++ )
@@ -249,7 +247,7 @@ void QualityHandle::slotQualityMetricChanged( int idx )
void QualityHandle::slotSelectCurrentAsReference()
{
VideoSubWindow* pcRefSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcRefSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcRefSubWindow )
{
VideoSubWindow* pcVideoSubWindow;
@@ -269,7 +267,7 @@ void QualityHandle::slotSelectCurrentAsReference()
void QualityHandle::slotPlotQualitySingle()
{
VideoSubWindow* pcSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcSubWindow )
{
if( pcSubWindow->getRefSubWindow() )
@@ -293,7 +291,7 @@ void QualityHandle::slotPlotQualitySingle()
void QualityHandle::slotPlotQualitySeveral()
{
VideoSubWindow* pcSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcSubWindow )
{
QVector<VideoSubWindow*> apcWindowList;
+5 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,17 +25,18 @@
#ifndef __QUALITYMEASUREMENT_H__
#define __QUALITYMEASUREMENT_H__
#include <QFuture>
#include <QtCore>
#include <QtWidgets>
#include "CommonDefs.h"
#include "QFuture"
#include "QualityMeasurementSidebar.h"
#include "config.h"
class SubWindowHandle;
class VideoSubWindow;
class QualityHandle : public QWidget
class QualityHandle : public QObject
{
Q_OBJECT
public:
@@ -53,7 +54,7 @@ public:
void update( VideoSubWindow* currSubWindow );
private:
QWidget* m_pcParet;
QWidget* m_pcParent;
SubWindowHandle* m_pcMainWindowManager;
enum
+229
View File
@@ -0,0 +1,229 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
* Joao Santos (joaompssantos@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file ResourceHandle.cpp
* \brief Handle resources
*/
#include "ResourceHandle.h"
#include <QCoreApplication>
#include <QEvent>
#include <QFileInfo>
#include <QMutex>
#include <QThread>
#include <memory>
auto get_new_resource_id() -> std::size_t
{
static std::size_t unique_id{ 0 };
return unique_id++;
}
ResourceWorker::~ResourceWorker()
{
stop();
}
void ResourceWorker::stop()
{
while( m_bStarting )
{
}
m_bStop = true;
if( m_bStarted )
{
wake();
wait();
}
m_bStarted = false;
}
void ResourceWorker::wake()
{
m_Mutex.lock();
m_ResourceIdle.wakeAll();
m_Mutex.unlock();
}
void ResourceWorker::start()
{
m_bStarting = true;
QThread::start();
}
void ResourceWorker::run()
{
m_bStop = false;
m_bStarted = true;
m_bStarting = false;
// Loop forever
for( ;; )
{
while( !m_bStop && !m_resource->isReady() )
{
// Wait here
m_Mutex.lock();
m_ResourceIdle.wait( &m_Mutex );
m_Mutex.unlock();
}
// auto start = std::chrono::steady_clock::now();
if( m_bStop || !m_resource->iteration() )
{
break;
}
// auto end = std::chrono::steady_clock::now();
// std::cout << "Elapsed time reading and processing a frame: "
// << std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count()
// << " ms" << std::endl;
}
m_bStarted = false;
m_bStop = false;
}
class OldStreamResource : public CalypResource
{
public:
OldStreamResource() = default;
CalypStream m_stream;
auto getResourceName() -> std::string override { return m_stream.getFileName(); };
auto getResource() -> CalypStream* override { return &m_stream; };
auto iteration() -> bool override
{
if( m_stream.getFrameNum() < 2 )
{
return false;
}
m_stream.readNextFrameFillRGBBuffer();
return true;
}
auto isReady() -> bool override { return m_stream.hasWritingSlot(); }
};
ResourceHandle::ResourceHandle() : m_thread{ std::make_unique<QThread>() }
{
moveToThread( m_thread.get() );
m_thread->start();
};
ResourceHandle::~ResourceHandle()
{
QMetaObject::invokeMethod( this, "cleanup" );
m_thread->wait();
};
void ResourceHandle::cleanup()
{
m_thread->quit();
};
auto ResourceHandle::addResource() -> std::size_t
{
auto resource_id = get_new_resource_id();
;
auto newStreamResource = std::make_shared<OldStreamResource>();
auto newStreamResourceWorker = std::make_unique<ResourceWorker>( newStreamResource );
m_apcStreamResourcesList[resource_id] = newStreamResource;
m_apcStreamResourcesWorkersList[resource_id] = std::move( newStreamResourceWorker );
return resource_id;
}
auto ResourceHandle::getResource( CalypStream* ptr ) -> std::size_t
{
if( ptr != nullptr )
{
for( std::size_t i = 0; i < m_apcStreamResourcesList.size(); i++ )
{
if( auto* resource = dynamic_cast<OldStreamResource*>( m_apcStreamResourcesList[i].get() ) )
{
if( &resource->m_stream == ptr ) return i;
}
}
}
return addResource();
}
auto ResourceHandle::getResourceAsset( std::size_t id ) -> CalypStream*
{
if( !m_apcStreamResourcesWorkersList.contains( id ) ) return nullptr;
return m_apcStreamResourcesList[id]->getResource();
}
auto ResourceHandle::appendResource( std::unique_ptr<CalypResource>&& resource ) -> std::size_t
{
auto resource_id = get_new_resource_id();
m_apcStreamResourcesList[resource_id] = std::move( resource );
m_apcStreamResourcesWorkersList[resource_id] =
std::make_unique<ResourceWorker>( m_apcStreamResourcesList[resource_id] );
return resource_id;
}
void ResourceHandle::removeResource( std::size_t id )
{
if( !m_apcStreamResourcesList.contains( id ) )
{
assert( false );
return;
}
// Remove worker first
m_apcStreamResourcesWorkersList[id]->stop();
m_apcStreamResourcesWorkersList[id] = nullptr;
// Then the underlying stream
m_apcStreamResourcesList[id] = nullptr;
}
void ResourceHandle::stopResourceWorker( std::size_t id )
{
if( !m_apcStreamResourcesWorkersList.contains( id ) )
{
assert( false );
return;
}
m_apcStreamResourcesWorkersList[id]->stop();
}
void ResourceHandle::startResourceWorker( std::size_t id )
{
if( !m_apcStreamResourcesWorkersList.contains( id ) )
{
assert( false );
return;
}
m_apcStreamResourcesWorkersList[id]->setObjectName(
"RW-" +
QFileInfo( QString::fromStdString( m_apcStreamResourcesList[id]->getResourceName() ) ).completeBaseName() );
m_apcStreamResourcesWorkersList[id]->start();
}
void ResourceHandle::wakeResourceWorker( std::size_t id )
{
if( !m_apcStreamResourcesWorkersList.contains( id ) )
{
assert( false );
return;
}
m_apcStreamResourcesWorkersList[id]->wake();
}
+114
View File
@@ -0,0 +1,114 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file ResourceHandle.h
* \brief Handle multiple sub-windows
*/
#ifndef __RESOURCEHANDLE_H__
#define __RESOURCEHANDLE_H__
#include <QMutex>
#include <QMutexLocker>
#include <QThread>
#include <QVector>
#include <QWaitCondition>
#include <atomic>
#include "CalypResource.h"
#include "lib/CalypStream.h"
class ResourceWorker : public QThread
{
private:
QMutex m_Mutex;
QWaitCondition m_ResourceIdle;
std::shared_ptr<CalypResource> m_resource;
std::atomic<bool> m_bStop{ false };
std::atomic<bool> m_bStarted{ false };
std::atomic<bool> m_bStarting{ false };
public:
explicit ResourceWorker( std::shared_ptr<CalypResource> resource ) : m_resource{ std::move( resource ) } {}
ResourceWorker( ResourceWorker&& other ) noexcept = delete;
ResourceWorker( const ResourceWorker& other ) = delete;
auto operator=( ResourceWorker&& other ) noexcept -> ResourceWorker& = delete;
auto operator=( const ResourceWorker& other ) -> ResourceWorker& = delete;
~ResourceWorker() override;
void stop();
void wake();
void start();
void run() override;
auto mutex() -> QMutex* { return &m_Mutex; }
};
class ResourceWorker;
class ResourceHandle : public QObject
{
Q_OBJECT
public:
ResourceHandle();
ResourceHandle( ResourceHandle&& other ) noexcept = delete;
ResourceHandle( const ResourceHandle& other ) = delete;
auto operator=( ResourceHandle&& other ) noexcept -> ResourceHandle& = delete;
auto operator=( const ResourceHandle& other ) -> ResourceHandle& = delete;
~ResourceHandle() override;
auto getResource( CalypStream* ptr ) -> std::size_t;
auto getResourceAsset( std::size_t id ) -> CalypStream*;
auto appendResource( std::unique_ptr<CalypResource>&& resource ) -> std::size_t;
void removeResource( std::size_t id );
void stopResourceWorker( std::size_t id );
void startResourceWorker( std::size_t id );
void wakeResourceWorker( std::size_t id );
template <typename T>
auto executeResourceAction( std::size_t id, const std::function<bool( T* )>& action ) -> bool
{
static_assert( std::is_base_of<CalypResource, T>::value, "T must inherit from CalypResource" );
if( !m_apcStreamResourcesList.contains( id ) )
{
assert( false );
return false;
}
bool result{ false };
if( auto* resource = dynamic_cast<T*>( m_apcStreamResourcesList[id].get() ) )
{
QMutexLocker locker( m_apcStreamResourcesWorkersList[id]->mutex() );
result = action( resource );
}
m_apcStreamResourcesWorkersList[id]->wake();
return result;
}
void cleanup();
private:
auto addResource() -> std::size_t;
private: // NOLINT
std::unique_ptr<QThread> m_thread;
std::map<std::size_t, std::shared_ptr<CalypResource>> m_apcStreamResourcesList;
std::map<std::size_t, std::unique_ptr<ResourceWorker>> m_apcStreamResourcesWorkersList;
};
#endif // __RESOURCEHANDLE_H__
+19 -12
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,31 +24,28 @@
#include "SubWindowAbstract.h"
#include "MdiSubWindow.h"
#include <QCloseEvent>
#include <QFocusEvent>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QIcon>
#include <QScreen>
#include <QScrollBar>
#include "MdiSubWindow.h"
SubWindowAbstract::SubWindowAbstract( QWidget* parent, unsigned int category )
: QWidget( parent ), m_cSubWindow( NULL )
: QWidget{ parent }, m_uiCategory{ category }, m_cWindowName{ " " }
{
setParent( parent );
setVisible( false );
// setFocusPolicy( Qt::WheelFocus );
setFocusPolicy( Qt::StrongFocus );
setAttribute( Qt::WA_DeleteOnClose );
setBackgroundRole( QPalette::Background );
setBackgroundRole( QPalette::Window );
setWindowIcon( QIcon( ":/logos/calyp-icon.png" ) );
// setWidgetResizable( true );
m_pcLayout = NULL;
m_uiCategory = category;
m_cWindowName = QString( " " );
connect( this, SIGNAL( destroyed() ), this, SLOT( onDestroyed() ) );
}
@@ -87,10 +84,20 @@ bool SubWindowAbstract::mayClose()
QSize SubWindowAbstract::sizeHint() const
{
return QSize();
QSize maxSize;
QWidget* p = parentWidget();
if( p )
{
maxSize = p->size();
}
else
{
maxSize = QGuiApplication::screens()[0]->availableGeometry().size();
}
return sizeHint( maxSize );
}
QSize SubWindowAbstract::sizeHint( const QSize& ) const
QSize SubWindowAbstract::sizeHint( const QSize& maxSize ) const
{
return QSize();
}
+6 -5
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -41,6 +41,7 @@
#include <QSize>
#include <QString>
#include <QWidget>
#include "CommonDefs.h"
#include "config.h"
@@ -55,11 +56,11 @@ class SubWindowAbstract : public QWidget
Q_OBJECT
private:
QHBoxLayout* m_pcLayout;
QHBoxLayout* m_pcLayout{ nullptr };
unsigned int m_uiCategory;
QString m_cWindowName;
MdiSubWindow* m_cSubWindow;
MdiSubWindow* m_cSubWindow{ nullptr };
public:
enum SubWindowCategory
@@ -89,7 +90,7 @@ public:
*/
virtual void zoomToFit() = 0;
/**
* Scale the image (zoomed in or out) to speficied absolute zoom value (1.0 =
* Scale the image (zoomed in or out) to specified absolute zoom value (1.0 =
* original size).
*/
virtual void zoomToFactor( double factor, QPoint center = QPoint() ) = 0;
@@ -106,7 +107,7 @@ public:
* Size related functions
*/
virtual QSize sizeHint() const;
virtual QSize sizeHint( const QSize& ) const;
virtual QSize sizeHint( const QSize& maxSize ) const;
/**
* Window name
+46 -30
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
* Joao Santos (joaompssantos@gmail.com)
*
@@ -25,29 +25,30 @@
#include "SubWindowHandle.h"
#include "MainWindow.h"
#include "MdiSubWindow.h"
#include "SubWindowAbstract.h"
#include <QAction>
#include <QActionGroup>
#include <QApplication>
#include <QDesktopWidget>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QMdiArea>
#include <QMenu>
#include <QPainter>
#include <QScreen>
#include <QSettings>
#include <QSignalMapper>
#include <QStyle>
#include "MainWindow.h"
#include "MdiSubWindow.h"
#include "SubWindowAbstract.h"
class MdiArea : public QMdiArea
{
public:
MdiArea( QWidget* parent = 0 )
: QMdiArea( parent ), m_pixmapLogo( ":/logos/calyp-logo.png" )
{
setBackgroundRole( QPalette::Background );
setBackgroundRole( QPalette::Window );
}
void appendLogMessage( const QString& msg )
@@ -83,7 +84,7 @@ private:
};
SubWindowHandle::SubWindowHandle( QWidget* parent )
: QWidget( parent )
: m_pcApp( qobject_cast<MainWindow*>( parent ) )
{
m_iWindowMode = -1;
m_pcWindowManagerLayout = NULL;
@@ -92,7 +93,7 @@ SubWindowHandle::SubWindowHandle( QWidget* parent )
m_apcSubWindowList.clear();
m_apcMdiSubWindowList.clear();
m_pcApp = qobject_cast<MainWindow*>( parentWidget() );
m_pcCentralWidget = new QWidget;
// setWindowMode( DETACHEDSUBWINDOWMODE );
setWindowMode( MDISUBWINDOWMODE );
}
@@ -150,11 +151,11 @@ void SubWindowHandle::setWindowMode( int iWindowMode )
m_apcSubWindowList.at( i )->resize( m_apcSubWindowList.at( i )->sizeHint() );
m_apcSubWindowList.at( i )->show();
}
setVisible( false );
parentWidget()->update();
m_pcCentralWidget->setVisible( false );
m_pcApp->update();
m_pcApp->showNormal();
qApp->processEvents();
QSize screenSize = QApplication::desktop()->availableGeometry().size();
QSize screenSize = QGuiApplication::screens()[0]->availableGeometry().size();
m_pcApp->move( 0, 0 );
m_pcApp->resize( screenSize.width(), 5 );
m_pcApp->setWindowTitle( QApplication::applicationName() );
@@ -162,13 +163,13 @@ void SubWindowHandle::setWindowMode( int iWindowMode )
if( iWindowMode == MDISUBWINDOWMODE )
{
setVisible( true );
m_pcCentralWidget->setVisible( true );
m_pcMdiArea = new MdiArea;
m_pcMdiArea->setActivationOrder( QMdiArea::ActivationHistoryOrder );
connect( m_pcMdiArea, SIGNAL( subWindowActivated( QMdiSubWindow* ) ), this, SLOT( updateActiveSubWindow() ) );
m_pcWindowManagerLayout = new QHBoxLayout( this );
m_pcWindowManagerLayout = new QHBoxLayout( m_pcCentralWidget );
m_pcWindowManagerLayout->addWidget( m_pcMdiArea );
setLayout( m_pcWindowManagerLayout );
m_pcCentralWidget->setLayout( m_pcWindowManagerLayout );
for( int i = 0; i < m_apcSubWindowList.size(); i++ )
{
addMdiSubWindow( m_apcSubWindowList.at( i ) );
@@ -180,6 +181,10 @@ void SubWindowHandle::setWindowMode( int iWindowMode )
{
m_pcApp->setWindowTitle( QApplication::applicationName() + " :: " + m_pcActiveWindow->getWindowName() );
}
else
{
m_pcApp->setWindowTitle( QApplication::applicationName() );
}
}
m_iWindowMode = iWindowMode;
// tileSubWindows();
@@ -216,6 +221,10 @@ void SubWindowHandle::updateActiveSubWindow( SubWindowAbstract* window )
{
m_pcApp->setWindowTitle( QApplication::applicationName() + " :: " + m_pcActiveWindow->getWindowName() );
}
else
{
m_pcApp->setWindowTitle( QApplication::applicationName() );
}
}
}
@@ -230,12 +239,14 @@ void SubWindowHandle::addMdiSubWindow( SubWindowAbstract* window )
SLOT( removeMdiSubWindow( MdiSubWindow* ) ) );
}
void SubWindowHandle::addSubWindow( SubWindowAbstract* window, Qt::WindowFlags flags )
void SubWindowHandle::addSubWindow( SubWindowAbstract* window )
{
if( window )
{
connect( window, SIGNAL( updateStatusBar( const QString& ) ), m_pcApp, SLOT( printMessage( const QString& ) ) );
connect( window, SIGNAL( zoomFactorChanged( const double, const QPoint ) ), m_pcApp, SLOT( updateZoomFactorSBox() ) );
connect( window, SIGNAL( updateStatusBar( const QString& ) ), m_pcApp,
SLOT( printMessage( const QString& ) ) );
connect( window, SIGNAL( zoomFactorChanged( const double, const QPoint ) ), m_pcApp,
SLOT( updateZoomFactorSBox() ) );
if( m_iWindowMode == DETACHEDSUBWINDOWMODE )
{
connect( window, SIGNAL( aboutToActivate( SubWindowAbstract* ) ), this,
@@ -274,7 +285,12 @@ void SubWindowHandle::removeSubWindow( int windowIdx )
if( !m_apcSubWindowList.isEmpty() )
m_apcSubWindowList.front()->setFocus();
else
m_pcActiveWindow = NULL;
m_pcActiveWindow = nullptr;
if( m_pcActiveWindow == nullptr )
{
m_pcApp->setWindowTitle( QApplication::applicationName() );
}
emit changed();
}
@@ -303,11 +319,6 @@ void SubWindowHandle::removeActiveSubWindow()
removeSubWindow( m_pcActiveWindow );
}
SubWindowAbstract* SubWindowHandle::activeSubWindow() const
{
return m_pcActiveWindow;
}
QList<SubWindowAbstract*> SubWindowHandle::findSubWindow( const unsigned int uiCategory ) const
{
QList<SubWindowAbstract*> apcSubWindowList;
@@ -378,7 +389,7 @@ void SubWindowHandle::tileSubWindows()
if( m_iWindowMode == DETACHEDSUBWINDOWMODE )
{
QSize screenSize = QApplication::desktop()->availableGeometry().size();
QSize screenSize = QGuiApplication::screens()[0]->availableGeometry().size();
unsigned int minWindowsInRow = 1;
while( ( screenSize.width() / minWindowsInRow ) > 500 )
{
@@ -474,12 +485,12 @@ void SubWindowHandle::createActions()
m_actionGroupWindowMode->actions().at( m_iWindowMode )->setChecked( true );
m_arrayActions[CLOSE_ACT] = new QAction( tr( "&Close" ), this );
m_arrayActions[CLOSE_ACT]->setIcon( style()->standardIcon( QStyle::SP_DialogCloseButton ) );
m_arrayActions[CLOSE_ACT]->setIcon( m_pcApp->style()->standardIcon( QStyle::SP_DialogCloseButton ) );
m_arrayActions[CLOSE_ACT]->setStatusTip( tr( "Close the active window" ) );
connect( m_arrayActions[CLOSE_ACT], SIGNAL( triggered() ), this, SLOT( removeActiveSubWindow() ) );
m_arrayActions[CLOSE_ACT] = new QAction( tr( "&Close" ), this );
m_arrayActions[CLOSE_ACT]->setIcon( style()->standardIcon( QStyle::SP_DialogCloseButton ) );
m_arrayActions[CLOSE_ACT]->setIcon( m_pcApp->style()->standardIcon( QStyle::SP_DialogCloseButton ) );
m_arrayActions[CLOSE_ACT]->setStatusTip( tr( "Close the active window" ) );
connect( m_arrayActions[CLOSE_ACT], SIGNAL( triggered() ), this, SLOT( removeActiveSubWindow() ) );
@@ -502,14 +513,14 @@ void SubWindowHandle::createActions()
m_arrayActions[NEXT_WINDOWS_ACT] = new QAction( tr( "Ne&xt" ), this );
m_arrayActions[NEXT_WINDOWS_ACT]->setShortcuts( QKeySequence::NextChild );
m_arrayActions[NEXT_WINDOWS_ACT]->setIcon( QIcon( style()->standardIcon( QStyle::SP_ArrowRight ) ) );
m_arrayActions[NEXT_WINDOWS_ACT]->setIcon( QIcon( m_pcApp->style()->standardIcon( QStyle::SP_ArrowRight ) ) );
m_arrayActions[NEXT_WINDOWS_ACT]->setStatusTip( tr( "Move the focus to the next window" ) );
// connect( m_arrayActions[NEXT_WINDOWS_ACT], SIGNAL( triggered() ), this,
// SLOT( activateNextSubWindow() ) );
m_arrayActions[PREVIOUS_WINDOWS_ACT] = new QAction( tr( "Pre&vious" ), this );
m_arrayActions[PREVIOUS_WINDOWS_ACT]->setShortcuts( QKeySequence::PreviousChild );
m_arrayActions[PREVIOUS_WINDOWS_ACT]->setIcon( QIcon( style()->standardIcon( QStyle::SP_ArrowLeft ) ) );
m_arrayActions[PREVIOUS_WINDOWS_ACT]->setIcon( QIcon( m_pcApp->style()->standardIcon( QStyle::SP_ArrowLeft ) ) );
m_arrayActions[PREVIOUS_WINDOWS_ACT]->setStatusTip( tr( "Move the focus to the previous window" ) );
// connect( m_arrayActions[PREVIOUS_WINDOWS_ACT], SIGNAL( triggered() ),
// this, SLOT( activatePreviousSubWindow() ) );
@@ -520,12 +531,17 @@ void SubWindowHandle::createActions()
QMenu* SubWindowHandle::createMenu()
{
m_pcMenuWindow = new QMenu( "&Window", this );
m_pcMenuWindow = new QMenu( "&Window", m_pcApp );
updateMenu();
connect( m_pcMenuWindow, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
return m_pcMenuWindow;
}
auto SubWindowHandle::getWidget() -> QWidget*
{
return m_pcCentralWidget;
}
void SubWindowHandle::updateMenu()
{
m_pcMenuWindow->clear();
+14 -6
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,12 +25,12 @@
#ifndef __SUBWINDOWHANDLE_H__
#define __SUBWINDOWHANDLE_H__
#include "CommonDefs.h"
#include <QString>
#include <QVector>
#include <QWidget>
#include "CommonDefs.h"
class QAction;
class QActionGroup;
class QHBoxLayout;
@@ -42,7 +42,7 @@ class SubWindowAbstract;
class MdiArea;
class MdiSubWindow;
class SubWindowHandle : public QWidget
class SubWindowHandle : public QObject
{
Q_OBJECT
@@ -51,9 +51,14 @@ public:
void processLogMsg( const QString& msg );
void addSubWindow( SubWindowAbstract* widget, Qt::WindowFlags flags = 0 );
void addSubWindow( SubWindowAbstract* widget );
SubWindowAbstract* activeSubWindow() const;
template <class T = SubWindowAbstract>
T* activeSubWindow() const
{
static_assert( std::is_base_of<SubWindowAbstract, T>::value, "T must inherit from SubWindowAbstract" );
return qobject_cast<T*>( m_pcActiveWindow );
}
QList<SubWindowAbstract*> findSubWindow( const unsigned int uiCategory = 0 ) const;
QList<SubWindowAbstract*> findSubWindow( const QString& aName, const unsigned int uiCategory = 0 ) const;
@@ -62,6 +67,8 @@ public:
void createActions();
QMenu* createMenu();
auto getWidget() -> QWidget*;
void readSettings();
void writeSettings();
@@ -76,6 +83,7 @@ private:
int m_iWindowMode;
QList<SubWindowAbstract*> m_apcSubWindowList;
QWidget* m_pcCentralWidget;
QHBoxLayout* m_pcWindowManagerLayout;
MdiArea* m_pcMdiArea;
QList<MdiSubWindow*> m_apcMdiSubWindowList;
+300 -157
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,50 +24,56 @@
#include "VideoHandle.h"
#include <QDockWidget>
#include <QElapsedTimer>
#include <QLabel>
#include <QSignalMapper>
#include <QSlider>
#include <QTimer>
#include <QToolBar>
#include <QtGui>
#include <limits>
#include <memory>
#include "FrameNumberWidget.h"
#include "FramePropertiesDock.h"
#include "MainWindow.h"
#include "SeekStreamDialog.h"
#include "SubWindowHandle.h"
#include "SubWindowSelectorDialog.h"
#include "VideoStreamSubWindow.h"
#include "VideoSubWindow.h"
#include <QDockWidget>
#include <QElapsedTimer>
#include <QLabel>
#include <QSignalMapper>
#include <QSlider>
#include <QToolBar>
#include <QtGui>
#if( _CONTROL_PLAYING_TIME_ == 1 )
#include <QElapsedTimer>
#endif
#include "lib/CalypFrame.h"
VideoHandle::VideoHandle( QWidget* parent, SubWindowHandle* windowManager )
: m_pcParet( parent ), m_pcMainWindowManager( windowManager )
: m_pcParent{ parent }
, m_pcMainWindowManager{ windowManager }
, m_pcPlayingTimer{ new QTimer{ this } }
, m_pcFrameRateFeedbackTimer{ std::make_unique<QElapsedTimer>() }
{
m_pcCurrentVideoSubWindow = NULL;
m_bIsPlaying = false;
m_pcPlayingTimer = new QTimer;
m_pcPlayingTimer->setTimerType( Qt::PreciseTimer );
connect( m_pcPlayingTimer, SIGNAL( timeout() ), this, SLOT( playEvent() ) );
connect( m_pcPlayingTimer, &QTimer::timeout, this, &VideoHandle::playEvent );
m_acPlayingSubWindows.clear();
}
VideoHandle::~VideoHandle() {}
VideoHandle::~VideoHandle() = default;
void VideoHandle::createActions()
{
if( m_pcParent == nullptr )
{
return;
}
m_arrayActions.resize( TOTAL_ACT );
m_arrayActions[PLAY_ACT] = new QAction( "Play", this );
m_arrayActions[PLAY_ACT]->setStatusTip( "Play/Pause" );
m_arrayActions[PLAY_ACT]->setIcon( QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaPlay ) ) );
m_arrayActions[PLAY_ACT]->setIcon( QIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaPlay ) ) );
m_arrayActions[PLAY_ACT]->setShortcut( Qt::Key_Space );
connect( m_arrayActions[PLAY_ACT], SIGNAL( triggered() ), this, SLOT( play() ) );
m_arrayActions[STOP_ACT] = new QAction( "Stop", this );
m_arrayActions[STOP_ACT]->setStatusTip( "Stop" );
m_arrayActions[STOP_ACT]->setIcon( QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaStop ) ) );
m_arrayActions[STOP_ACT]->setIcon( QIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaStop ) ) );
connect( m_arrayActions[STOP_ACT], SIGNAL( triggered() ), this, SLOT( stop() ) );
m_mapperVideoSeek = new QSignalMapper( this );
@@ -76,7 +82,7 @@ void VideoHandle::createActions()
m_arrayActions[VIDEO_BACKWARD_ACT] = new QAction( "Video Backward", this );
m_arrayActions[VIDEO_BACKWARD_ACT]->setStatusTip( "Seek backward" );
m_arrayActions[VIDEO_BACKWARD_ACT]->setIcon(
QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaSeekBackward ) ) );
QIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaSeekBackward ) ) );
m_arrayActions[VIDEO_BACKWARD_ACT]->setShortcut( Qt::Key_Left );
connect( m_arrayActions[VIDEO_BACKWARD_ACT], SIGNAL( triggered() ), m_mapperVideoSeek, SLOT( map() ) );
m_mapperVideoSeek->setMapping( m_arrayActions[VIDEO_BACKWARD_ACT], 0 );
@@ -84,7 +90,7 @@ void VideoHandle::createActions()
m_arrayActions[VIDEO_FORWARD_ACT] = new QAction( "Video Forward", this );
m_arrayActions[VIDEO_FORWARD_ACT]->setStatusTip( "Seek forward" );
m_arrayActions[VIDEO_FORWARD_ACT]->setIcon(
QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaSeekForward ) ) );
QIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaSeekForward ) ) );
m_arrayActions[VIDEO_FORWARD_ACT]->setShortcut( Qt::Key_Right );
connect( m_arrayActions[VIDEO_FORWARD_ACT], SIGNAL( triggered() ), m_mapperVideoSeek, SLOT( map() ) );
m_mapperVideoSeek->setMapping( m_arrayActions[VIDEO_FORWARD_ACT], 1 );
@@ -121,6 +127,24 @@ void VideoHandle::createActions()
connect( m_pcFrameSlider, SIGNAL( valueChanged( int ) ), this, SLOT( seekSliderEvent( int ) ) );
// ------------ Image ------------
m_mapperComponent = new QSignalMapper( this );
m_actionGroupComponent = new QActionGroup( this );
m_actionGroupComponent->setExclusive( true );
m_mapperComponent->setMapping( m_actionGroupComponent->addAction( "All" ), -1 );
m_mapperComponent->setMapping( m_actionGroupComponent->addAction( "Red" ), 0 );
m_mapperComponent->setMapping( m_actionGroupComponent->addAction( "Green" ), 1 );
m_mapperComponent->setMapping( m_actionGroupComponent->addAction( "Blue" ), 2 );
m_mapperComponent->setMapping( m_actionGroupComponent->addAction( "Alpha" ), 3 );
for( int i = 0; i < m_actionGroupComponent->actions().size(); i++ )
{
m_actionGroupComponent->actions().at( i )->setCheckable( true );
m_actionGroupComponent->actions().at( i )->setVisible( false );
connect( m_actionGroupComponent->actions().at( i ), SIGNAL( triggered() ), m_mapperComponent, SLOT( map() ) );
}
m_actionGroupComponent->actions().at( 0 )->setChecked( true );
m_actionGroupComponent->actions().at( 0 )->setVisible( true );
connect( m_mapperComponent, SIGNAL( mapped( int ) ), this, SLOT( setComponent( int ) ) );
m_actionGroupTools = new QActionGroup( this );
m_actionGroupTools->setExclusive( true );
@@ -132,7 +156,7 @@ void VideoHandle::createActions()
m_arrayActions[NAVIGATION_TOOL_ACT] = new QAction( tr( "Navigation Tool" ), this );
m_arrayActions[NAVIGATION_TOOL_ACT]->setCheckable( true );
m_arrayActions[NAVIGATION_TOOL_ACT]->setChecked( true );
m_arrayActions[NAVIGATION_TOOL_ACT]->setShortcut( Qt::CTRL + Qt::Key_1 );
m_arrayActions[NAVIGATION_TOOL_ACT]->setShortcut( Qt::CTRL | Qt::Key_1 );
m_actionGroupTools->addAction( m_arrayActions[NAVIGATION_TOOL_ACT] );
connect( m_arrayActions[NAVIGATION_TOOL_ACT], SIGNAL( triggered() ), m_mapperTools, SLOT( map() ) );
m_mapperTools->setMapping( m_arrayActions[NAVIGATION_TOOL_ACT], ViewArea::NavigationView );
@@ -140,7 +164,7 @@ void VideoHandle::createActions()
m_arrayActions[SELECTION_TOOL_ACT] = new QAction( "Selection Tool", this );
m_arrayActions[SELECTION_TOOL_ACT]->setCheckable( true );
m_arrayActions[SELECTION_TOOL_ACT]->setChecked( false );
m_arrayActions[SELECTION_TOOL_ACT]->setShortcut( Qt::CTRL + Qt::Key_2 );
m_arrayActions[SELECTION_TOOL_ACT]->setShortcut( Qt::CTRL | Qt::Key_2 );
m_actionGroupTools->addAction( m_arrayActions[SELECTION_TOOL_ACT] );
connect( m_arrayActions[SELECTION_TOOL_ACT], SIGNAL( triggered() ), m_mapperTools, SLOT( map() ) );
m_mapperTools->setMapping( m_arrayActions[SELECTION_TOOL_ACT], ViewArea::NormalSelectionView );
@@ -148,7 +172,7 @@ void VideoHandle::createActions()
m_arrayActions[BLOCK_SELECTION_TOOL_ACT] = new QAction( "Block Selection Tool", this );
m_arrayActions[BLOCK_SELECTION_TOOL_ACT]->setCheckable( true );
m_arrayActions[BLOCK_SELECTION_TOOL_ACT]->setChecked( false );
m_arrayActions[BLOCK_SELECTION_TOOL_ACT]->setShortcut( Qt::CTRL + Qt::Key_3 );
m_arrayActions[BLOCK_SELECTION_TOOL_ACT]->setShortcut( Qt::CTRL | Qt::Key_3 );
m_actionGroupTools->addAction( m_arrayActions[BLOCK_SELECTION_TOOL_ACT] );
connect( m_arrayActions[BLOCK_SELECTION_TOOL_ACT], SIGNAL( triggered() ), m_mapperTools, SLOT( map() ) );
m_mapperTools->setMapping( m_arrayActions[BLOCK_SELECTION_TOOL_ACT], ViewArea::BlockSelectionView );
@@ -156,9 +180,11 @@ void VideoHandle::createActions()
m_mapperGrid = new QSignalMapper( this );
m_actionGroupGrid = new QActionGroup( this );
m_actionGroupGrid->setExclusive( true );
m_mapperGrid->setMapping( m_actionGroupGrid->addAction( "4x4" ), 4 );
m_mapperGrid->setMapping( m_actionGroupGrid->addAction( "8x8" ), 8 );
m_mapperGrid->setMapping( m_actionGroupGrid->addAction( "16x16" ), 16 );
m_mapperGrid->setMapping( m_actionGroupGrid->addAction( "64x64" ), 64 );
m_mapperGrid->setMapping( m_actionGroupGrid->addAction( "128x128" ), 128 );
for( int i = 0; i < m_actionGroupGrid->actions().size(); i++ )
{
@@ -176,7 +202,11 @@ void VideoHandle::createActions()
QMenu* VideoHandle::createVideoMenu()
{
m_pcMenuVideo = new QMenu( "Video", m_pcParet );
if( m_pcParent == nullptr )
{
return nullptr;
}
m_pcMenuVideo = new QMenu( "Video", m_pcParent );
m_pcMenuVideo->addAction( m_arrayActions[PLAY_ACT] );
m_pcMenuVideo->addAction( m_arrayActions[STOP_ACT] );
m_pcMenuVideo->addAction( m_arrayActions[VIDEO_BACKWARD_ACT] );
@@ -191,7 +221,13 @@ QMenu* VideoHandle::createVideoMenu()
QMenu* VideoHandle::createImageMenu()
{
m_pcMenuImage = new QMenu( "Image", m_pcParet );
if( m_pcParent == nullptr )
{
return nullptr;
}
m_pcMenuImage = new QMenu( "Image", m_pcParent );
m_menuComponent = m_pcMenuImage->addMenu( "Component" );
m_menuComponent->addActions( m_actionGroupComponent->actions() );
m_pcMenuImage->addAction( m_arrayActions[NAVIGATION_TOOL_ACT] );
m_pcMenuImage->addAction( m_arrayActions[SELECTION_TOOL_ACT] );
m_pcMenuImage->addAction( m_arrayActions[BLOCK_SELECTION_TOOL_ACT] );
@@ -202,14 +238,16 @@ QMenu* VideoHandle::createImageMenu()
return m_pcMenuImage;
}
QToolBar* VideoHandle::createToolBar()
auto VideoHandle::createToolBar() -> QPointer<QToolBar>
{
m_toolbarVideo = new QToolBar( tr( "Video" ) );
if( m_pcParent == nullptr ) return nullptr;
QPointer m_toolbarVideo = new QToolBar( tr( "Video" ) );
m_toolbarVideo->setAllowedAreas( Qt::TopToolBarArea | Qt::BottomToolBarArea );
m_toolbarVideo->addAction( m_arrayActions[PLAY_ACT] );
m_toolbarVideo->addAction( m_arrayActions[STOP_ACT] );
QLabel* pcLockLabel = new QLabel( "PlayingLock" );
QPointer pcLockLabel = new QLabel( "PlayingLock" );
pcLockLabel->setAlignment( Qt::AlignCenter );
m_arrayActions[VIDEO_LOCK_ACT] = m_toolbarVideo->addWidget( pcLockLabel );
m_arrayActions[VIDEO_LOCK_ACT]->setVisible( false );
@@ -218,6 +256,7 @@ QToolBar* VideoHandle::createToolBar()
m_toolbarVideo->addWidget( m_pcFrameSlider );
m_toolbarVideo->addAction( m_arrayActions[VIDEO_FORWARD_ACT] );
m_toolbarVideo->addWidget( new QLabel );
m_pcFrameNumInfo = new FrameNumberWidget;
m_toolbarVideo->addWidget( m_pcFrameNumInfo );
@@ -226,8 +265,12 @@ QToolBar* VideoHandle::createToolBar()
QDockWidget* VideoHandle::createDock()
{
m_pcFramePropertiesSideBar = new FramePropertiesDock( m_pcParet, &m_bIsPlaying );
m_pcFramePropertiesDock = new QDockWidget( tr( "Frame Information" ), m_pcParet );
if( m_pcParent == nullptr )
{
return nullptr;
}
m_pcFramePropertiesSideBar = new FramePropertiesDock( m_pcParent, &m_bIsPlaying );
m_pcFramePropertiesDock = new QDockWidget( tr( "Frame Information" ), m_pcParent );
m_pcFramePropertiesDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
m_pcFramePropertiesDock->setWidget( m_pcFramePropertiesSideBar );
connect( m_pcFramePropertiesDock, SIGNAL( visibilityChanged( bool ) ), this, SLOT( update() ) );
@@ -237,9 +280,19 @@ QDockWidget* VideoHandle::createDock()
QWidget* VideoHandle::createStatusBarMessage()
{
if( m_pcParent == nullptr )
{
return nullptr;
}
QWidget* pcStatusBarWidget = new QWidget;
QHBoxLayout* mainlayout = new QHBoxLayout;
m_pcPlayingFPSLabel = new QLabel;
m_pcPlayingFPSLabel->setText( " " );
m_pcPlayingFPSLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
m_pcPlayingFPSLabel->setMinimumWidth( 150 );
m_pcPlayingFPSLabel->setAlignment( Qt::AlignCenter );
m_pcVideoFormatLabel = new QLabel;
m_pcVideoFormatLabel->setText( " " );
m_pcVideoFormatLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
@@ -252,6 +305,7 @@ QWidget* VideoHandle::createStatusBarMessage()
m_pcResolutionLabel->setMinimumWidth( 90 );
m_pcResolutionLabel->setAlignment( Qt::AlignCenter );
mainlayout->addWidget( m_pcPlayingFPSLabel );
mainlayout->addWidget( m_pcVideoFormatLabel );
mainlayout->addWidget( m_pcResolutionLabel );
pcStatusBarWidget->setLayout( mainlayout );
@@ -259,9 +313,65 @@ QWidget* VideoHandle::createStatusBarMessage()
return pcStatusBarWidget;
}
void VideoHandle::updateComponentMenu()
{
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
if( pcSubWindow == nullptr )
{
m_menuComponent->setEnabled( false );
return;
}
const auto* frame = pcSubWindow->getCurrFrame();
if( frame == nullptr )
{
m_menuComponent->setEnabled( false );
return;
}
m_menuComponent->setEnabled( true );
for( int i = 1; i < m_actionGroupComponent->actions().size(); i++ )
{
m_actionGroupComponent->actions()[i]->setChecked( false );
m_actionGroupComponent->actions()[i]->setVisible( false );
}
switch( frame->getColorSpace() )
{
case CLP_COLOR_GRAY:
m_actionGroupComponent->actions().at( 1 )->setText( QStringLiteral( "Gray" ) );
m_actionGroupComponent->actions().at( 1 )->setVisible( true );
break;
case CLP_COLOR_YUV:
m_actionGroupComponent->actions().at( 1 )->setText( QStringLiteral( "Luminance" ) );
m_actionGroupComponent->actions().at( 1 )->setVisible( true );
m_actionGroupComponent->actions().at( 2 )->setText( QStringLiteral( "Chrominance U (Cb)" ) );
m_actionGroupComponent->actions().at( 2 )->setVisible( true );
m_actionGroupComponent->actions().at( 3 )->setText( QStringLiteral( "Chrominance V (Cr)" ) );
m_actionGroupComponent->actions().at( 3 )->setVisible( true );
break;
case CLP_COLOR_RGBA:
m_actionGroupComponent->actions().at( 4 )->setText( QStringLiteral( "Alpha" ) );
m_actionGroupComponent->actions().at( 4 )->setVisible( true );
[[fallthrough]];
case CLP_COLOR_RGB:
m_actionGroupComponent->actions().at( 1 )->setText( QStringLiteral( "Red" ) );
m_actionGroupComponent->actions().at( 1 )->setVisible( true );
m_actionGroupComponent->actions().at( 2 )->setText( QStringLiteral( "Green" ) );
m_actionGroupComponent->actions().at( 2 )->setVisible( true );
m_actionGroupComponent->actions().at( 3 )->setText( QStringLiteral( "Blue" ) );
m_actionGroupComponent->actions().at( 3 )->setVisible( true );
break;
default:
Q_ASSERT( false );
}
auto component = pcSubWindow->getViewArea()->getFilteredChannel();
int idx = component.has_value() ? *component : 0;
m_actionGroupComponent->actions().at( idx )->setChecked( true );
}
void VideoHandle::updateMenus()
{
VideoSubWindow* pcSubWindow = qobject_cast<VideoSubWindow*>( m_pcMainWindowManager->activeSubWindow() );
VideoSubWindow* pcSubWindow = m_pcMainWindowManager->activeSubWindow<VideoSubWindow>();
bool hasSubWindow = pcSubWindow ? true : false;
m_arrayActions[PLAY_ACT]->setEnabled( hasSubWindow );
@@ -287,6 +397,8 @@ void VideoHandle::updateMenus()
m_arrayActions[SELECTION_TOOL_ACT]->setEnabled( hasSubWindow );
m_arrayActions[BLOCK_SELECTION_TOOL_ACT]->setEnabled( hasSubWindow );
m_arrayActions[SHOW_GRID_ACT]->setEnabled( hasSubWindow );
updateComponentMenu();
}
void VideoHandle::readSettings()
@@ -294,8 +406,7 @@ void VideoHandle::readSettings()
QSettings appSettings;
m_arrayActions[VIDEO_REPEAT_ACT]->setChecked( appSettings.value( "VideoHandle/Repeat", false ).toBool() );
m_arrayActions[VIDEO_ZOOM_LOCK_ACT]->setChecked( appSettings.value( "VideoHandle/VideoZoomLock", false ).toBool() );
if( !appSettings.value( "VideoHandle/FrameProperties", true ).toBool() )
m_pcFramePropertiesDock->close();
if( !appSettings.value( "VideoHandle/FrameProperties", true ).toBool() ) m_pcFramePropertiesDock->close();
m_uiViewTool = appSettings.value( "VideoHandle/SelectedTool", ViewArea::NavigationView ).toUInt();
setTool( m_uiViewTool );
@@ -317,13 +428,16 @@ void VideoHandle::update()
{
if( m_pcCurrentVideoSubWindow )
{
CalypStream* pcStream = m_pcCurrentVideoSubWindow->getInputStream();
CalypFrame* pcFrame = m_pcCurrentVideoSubWindow->getCurrFrame();
bool isPlaying{ false };
const CalypStream* pcStream{ nullptr };
if( auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) )
{
pcStream = videoStreamSubWindow->getInputStream();
isPlaying = videoStreamSubWindow->isPlaying();
}
auto pcFrame = m_pcCurrentVideoSubWindow->getCurrFrameAsset();
unsigned long frame_num = 0;
unsigned long total_frame_num = 1;
m_pcVideoFormatLabel->setText( m_pcCurrentVideoSubWindow->getStreamInformation() );
m_pcVideoFormatLabel->setText( m_pcCurrentVideoSubWindow->getVideoInformation() );
QString resolution;
if( pcFrame )
@@ -331,6 +445,8 @@ void VideoHandle::update()
resolution.append( QString( "%1x%2" ).arg( pcFrame->getWidth() ).arg( pcFrame->getHeight() ) );
}
unsigned long frame_num = 0;
unsigned long total_frame_num = 1;
if( pcStream )
{
frame_num = pcStream->getCurrFrameNum();
@@ -355,8 +471,7 @@ void VideoHandle::update()
}
}
m_pcResolutionLabel->setText( resolution );
m_pcFramePropertiesSideBar->setFrame( pcFrame );
m_pcFramePropertiesSideBar->setFrame( pcFrame, isPlaying );
m_pcFrameNumInfo->setTotalFrameNum( total_frame_num );
m_pcFrameNumInfo->setCurrFrameNum( frame_num );
@@ -366,19 +481,25 @@ void VideoHandle::update()
m_pcFrameSlider->setValue( frame_num );
m_pcFrameSlider->blockSignals( false );
if( m_uiRealAverageFrameRate > 0 )
{
m_pcPlayingFPSLabel->setText( QString( "%1 fps" ).arg( m_uiRealAverageFrameRate ) );
}
if( m_pcCurrentVideoSubWindow->isPlaying() )
{
m_arrayActions[PLAY_ACT]->setText( "Pause" );
m_arrayActions[PLAY_ACT]->setIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaPause ) );
m_arrayActions[PLAY_ACT]->setIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaPause ) );
}
else
{
m_arrayActions[PLAY_ACT]->setText( "Play" );
m_arrayActions[PLAY_ACT]->setIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaPlay ) );
m_arrayActions[PLAY_ACT]->setIcon( m_pcParent->style()->standardIcon( QStyle::SP_MediaPlay ) );
}
}
else
{
m_pcPlayingFPSLabel->setText( "" );
m_pcVideoFormatLabel->setText( "" );
m_pcResolutionLabel->setText( "" );
m_pcFramePropertiesSideBar->reset();
@@ -407,48 +528,45 @@ void VideoHandle::addSubWindow( VideoSubWindow* window )
window->getViewArea()->setTool( m_uiViewTool );
window->getViewArea()->setGridVisible( m_arrayActions[SHOW_GRID_ACT]->isChecked() );
connect( window, &SubWindowAbstract::aboutToClose,
this, &VideoHandle::closeSubWindow );
connect( window, &SubWindowAbstract::aboutToClose, this, &VideoHandle::closeSubWindow );
connect( window, &SubWindowAbstract::zoomFactorChanged,
this, &VideoHandle::zoomToFactorAll );
connect( window, &SubWindowAbstract::zoomFactorChanged, this, &VideoHandle::zoomToFactorAll );
connect( window, &SubWindowAbstract::scrollBarMoved,
this, &VideoHandle::moveAllScrollBars );
connect( window, &SubWindowAbstract::scrollBarMoved, this, &VideoHandle::moveAllScrollBars );
connect( window->getViewArea(), SIGNAL( selectionChanged( QRect ) ), this, SLOT( updateSelectionArea( QRect ) ) );
}
void VideoHandle::closeSubWindow( SubWindowAbstract* subWindow )
{
VideoSubWindow* videoSubWindow = qobject_cast<VideoSubWindow*>( subWindow );
auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( subWindow );
if( m_acPlayingSubWindows.contains( videoSubWindow ) )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
int pos = m_acPlayingSubWindows.indexOf( videoSubWindow );
m_acPlayingSubWindows.at( pos )->stop();
int pos = m_acPlayingSubWindows.indexOf( videoStreamSubWindow );
m_acPlayingSubWindows.remove( pos );
if( m_acPlayingSubWindows.size() < 2 )
{
m_arrayActions[VIDEO_LOCK_ACT]->setVisible( false );
}
}
if( subWindow == m_pcCurrentVideoSubWindow )
{
m_pcFramePropertiesSideBar->reset();
}
}
void VideoHandle::zoomToFactorAll( const double scale, const QPoint center )
{
double factor;
if( m_arrayActions[VIDEO_ZOOM_LOCK_ACT]->isChecked() )
{
factor = m_pcCurrentVideoSubWindow->getScaleFactor();
double factor = m_pcCurrentVideoSubWindow->getScaleFactor();
SubWindowAbstract* subWindow;
QList<SubWindowAbstract*> subWindowList =
m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW );
for( int i = 0; i < subWindowList.size(); i++ )
{
subWindow = subWindowList.at( i );
SubWindowAbstract* subWindow = subWindowList.at( i );
if( m_pcCurrentVideoSubWindow == subWindow )
continue;
else
@@ -502,12 +620,12 @@ void VideoHandle::moveAllScrollBars( const double& horRatio, const double& verRa
{
if( m_arrayActions[VIDEO_ZOOM_LOCK_ACT]->isChecked() && m_pcCurrentVideoSubWindow )
{
VideoSubWindow* videoSubWindow;
QList<SubWindowAbstract*> subWindowList = m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW );
QList<SubWindowAbstract*> subWindowList =
m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_SUBWINDOW );
for( int i = 0; i < subWindowList.size(); i++ )
{
videoSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
VideoSubWindow* videoSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
if( m_pcCurrentVideoSubWindow == videoSubWindow )
continue;
else
@@ -521,22 +639,20 @@ void VideoHandle::moveAllScrollBars( const double& horRatio, const double& verRa
unsigned long VideoHandle::getMaxFrameNumber()
{
unsigned long currFrames;
unsigned long maxFrames = INT_MAX;
std::uint64_t maxFrames = std::numeric_limits<std::uint64_t>::max();
if( m_pcCurrentVideoSubWindow )
{
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
if( m_acPlayingSubWindows.contains( qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) ) )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
{
currFrames = m_acPlayingSubWindows.at( i )->getInputStream()->getFrameNum();
if( currFrames < maxFrames )
maxFrames = currFrames;
auto currFrames = m_acPlayingSubWindows.at( i )->getFrameNum();
if( currFrames < maxFrames ) maxFrames = currFrames;
}
}
else
{
maxFrames = m_pcCurrentVideoSubWindow->getInputStream()->getFrameNum();
maxFrames = m_pcCurrentVideoSubWindow->getFrameNum();
}
}
return maxFrames;
@@ -549,9 +665,9 @@ void VideoHandle::setTimerStatus()
{
status |= m_acPlayingSubWindows.at( i )->isPlaying();
}
if( m_pcCurrentVideoSubWindow )
if( auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) )
{
status |= m_pcCurrentVideoSubWindow->isPlaying();
status |= videoStreamSubWindow->isPlaying();
}
if( status )
{
@@ -559,42 +675,33 @@ void VideoHandle::setTimerStatus()
{
m_pcPlayingTimer->start();
m_bIsPlaying = true;
#if( _CONTROL_PLAYING_TIME_ == 1 )
m_uiNumberPlayedFrames = 0;
m_pcPlayControlTimer = new QElapsedTimer;
m_pcPlayControlTimer->start();
m_dAverageFps = 0;
#endif
m_pcFrameRateFeedbackTimer->start();
m_uiRealAverageFrameRate = 0;
}
}
else
{
#if( _CONTROL_PLAYING_TIME_ == 1 )
if( m_pcPlayControlTimer && m_pcPlayingTimer->interval() > 0 )
{
qDebug() << "Desired Fps: " << 1000 / m_pcPlayingTimer->interval() << "Real Fps: " << 1000 / m_dAverageFps;
delete m_pcPlayControlTimer;
m_pcPlayControlTimer = NULL;
}
#endif
m_pcPlayingTimer->stop();
m_bIsPlaying = false;
}
}
void VideoHandle::configureFrameRateTimer()
{
double frame_rate = m_acPlayingSubWindows.at( 0 )->getInputStream()->getFrameRate();
unsigned int time_ms = (unsigned int)( 1000.0 / frame_rate + 0.5 );
m_pcPlayingTimer->setInterval( time_ms );
}
void VideoHandle::play()
{
if( !m_pcCurrentVideoSubWindow )
return;
auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow );
if( !m_pcCurrentVideoSubWindow->getInputStream() )
return;
if( videoStreamSubWindow == nullptr ) return;
if( !m_pcCurrentVideoSubWindow->isPlaying() ) // Not playing
if( !videoStreamSubWindow->isPlaying() ) // Not playing
{
double frameRate;
unsigned int timeinterval;
if( m_acPlayingSubWindows.size() < 2 )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
@@ -602,22 +709,20 @@ void VideoHandle::play()
m_acPlayingSubWindows.at( i )->pause();
}
m_acPlayingSubWindows.clear();
m_acPlayingSubWindows.append( m_pcCurrentVideoSubWindow );
m_acPlayingSubWindows.append( videoStreamSubWindow );
}
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
{
m_acPlayingSubWindows.at( i )->play();
}
frameRate = m_acPlayingSubWindows.at( 0 )->getInputStream()->getFrameRate();
timeinterval = (unsigned int)( 1000.0 / frameRate + 0.5 );
m_pcPlayingTimer->setInterval( timeinterval );
configureFrameRateTimer();
}
}
else
{
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
{
@@ -626,21 +731,20 @@ void VideoHandle::play()
}
else
{
m_pcCurrentVideoSubWindow->pause();
videoStreamSubWindow->pause();
}
}
setTimerStatus();
emit changed();
// update();
}
void VideoHandle::stop()
{
if( m_acPlayingSubWindows.size() > 0 )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
for( auto playingSubWindow : m_acPlayingSubWindows )
{
m_acPlayingSubWindows.at( i )->stop();
playingSubWindow->stop();
}
m_acPlayingSubWindows.clear();
setTimerStatus();
@@ -656,109 +760,137 @@ void VideoHandle::stop()
m_arrayActions[VIDEO_LOCK_ACT]->setVisible( false );
}
void VideoHandle::calculateRealFrameRate()
{
double average_time_between_frames_ms = m_uiNumberPlayedFrames > 0 ? 1000.0 / m_uiRealAverageFrameRate : 0;
auto time_elapsed_since_last_frame_ms = static_cast<double>( m_pcFrameRateFeedbackTimer->elapsed() );
average_time_between_frames_ms =
double( average_time_between_frames_ms * m_uiNumberPlayedFrames + time_elapsed_since_last_frame_ms ) /
double( m_uiNumberPlayedFrames + 1 );
m_uiRealAverageFrameRate =
std::round<unsigned int>( static_cast<unsigned int>( 1000.0 / average_time_between_frames_ms ) );
m_uiNumberPlayedFrames++;
m_pcFrameRateFeedbackTimer->restart();
}
void VideoHandle::playEvent()
{
bool bEndOfSequence = false;
#if( _CONTROL_PLAYING_TIME_ == 1 )
m_dAverageFps = double( m_dAverageFps * m_uiNumberPlayedFrames + m_pcPlayControlTimer->elapsed() ) /
double( m_uiNumberPlayedFrames + 1 );
m_uiNumberPlayedFrames++;
m_pcPlayControlTimer->restart();
#endif
// auto start = std::chrono::steady_clock::now();
// This value should only be true if it is really needed to refresh the UI after this play event
// Lets assume the current window is not playing. Nothing changes in the UI expect the playing windows
// So no changed is emmited
bool bShouldRefreshUI = false;
calculateRealFrameRate();
try
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
bool bEndOfSequence = false;
for( auto playingSubWindow : m_acPlayingSubWindows )
{
bEndOfSequence |= m_acPlayingSubWindows.at( i )->playEvent();
bEndOfSequence |= playingSubWindow->playEvent();
// If the current selected windows is playing then we need to refresh the UI
if( playingSubWindow == m_pcCurrentVideoSubWindow )
{
bShouldRefreshUI = true;
}
}
if( bEndOfSequence )
{
if( !m_arrayActions[VIDEO_REPEAT_ACT]->isChecked() )
{
stop();
}
else
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
m_acPlayingSubWindows.at( i )->seekAbsoluteEvent( 0 );
{
for( auto playingSubWindow : m_acPlayingSubWindows )
{
playingSubWindow->seekAbsoluteEvent( 0 );
}
}
}
}
catch( const char* msg )
{
QString warningMsg = "Error while playing " +
QFileInfo( m_pcCurrentVideoSubWindow->getCurrentFileName() ).fileName() +
" with the following error: \n" + msg;
QMessageBox::warning( m_pcParet, QApplication::applicationName(), warningMsg );
QString warningMsg =
"Error while playing " + m_pcCurrentVideoSubWindow->getWindowName() + " with the following error: \n" + msg;
QMessageBox::warning( m_pcParent, QApplication::applicationName(), warningMsg );
qDebug() << warningMsg;
stop();
m_pcCurrentVideoSubWindow->close();
}
emit changed();
if( bShouldRefreshUI ) emit changed();
// auto end = std::chrono::steady_clock::now();
// std::cout << "Elapsed time going to next frame: "
// << std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count()
// << " ms" << std::endl;
}
void VideoHandle::seekEvent( int direction )
{
if( m_pcCurrentVideoSubWindow )
if( auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) )
{
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
if( !( (unsigned int)( m_pcCurrentVideoSubWindow->getInputStream()->getCurrFrameNum() + 1 ) >= getMaxFrameNumber() &&
if( !( (unsigned int)( videoStreamSubWindow->getInputStream()->getCurrFrameNum() + 1 ) >= getMaxFrameNumber() &&
direction > 0 ) )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
for( auto playingSubWindow : m_acPlayingSubWindows )
{
m_acPlayingSubWindows.at( i )->seekRelativeEvent( direction > 0 ? true : false );
playingSubWindow->seekRelativeEvent( direction > 0 ? true : false );
}
}
}
else
{
m_pcCurrentVideoSubWindow->seekRelativeEvent( direction > 0 ? true : false );
videoStreamSubWindow->seekRelativeEvent( direction > 0 ? true : false );
}
emit changed();
// update();
}
}
void VideoHandle::seekVideo()
{
if( m_pcCurrentVideoSubWindow )
if( auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) )
{
if( m_pcCurrentVideoSubWindow->getInputStream() )
SeekStreamDialog* dialogSeekVideo = new SeekStreamDialog( videoStreamSubWindow->getInputStream(), m_pcParent );
int newFrameNum = dialogSeekVideo->runDialog();
if( newFrameNum >= 0 )
{
SeekStreamDialog* dialogSeekVideo =
new SeekStreamDialog( m_pcCurrentVideoSubWindow->getInputStream(), m_pcParet );
int newFrameNum = dialogSeekVideo->runDialog();
if( newFrameNum >= 0 )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
for( auto playingSubWindow : m_acPlayingSubWindows )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
{
m_acPlayingSubWindows.at( i )->seekAbsoluteEvent( (unsigned int)newFrameNum );
}
playingSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum );
}
else
{
m_pcCurrentVideoSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum );
}
emit changed();
}
else
{
videoStreamSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum );
}
emit changed();
}
}
}
void VideoHandle::seekSliderEvent( int new_frame_num )
{
if( m_pcCurrentVideoSubWindow && !m_bIsPlaying ) // TODO: Fix this slot
// TODO: Fix this slot
if( m_bIsPlaying ) return;
if( auto* videoStreamSubWindow = qobject_cast<VideoStreamSubWindow*>( m_pcCurrentVideoSubWindow ) )
{
if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) )
if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) )
{
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
for( auto playingSubWindow : m_acPlayingSubWindows )
{
m_acPlayingSubWindows.at( i )->seekAbsoluteEvent( (unsigned int)new_frame_num );
playingSubWindow->seekAbsoluteEvent( (unsigned int)new_frame_num );
}
}
else
{
m_pcCurrentVideoSubWindow->seekAbsoluteEvent( (unsigned int)new_frame_num );
videoStreamSubWindow->seekAbsoluteEvent( (unsigned int)new_frame_num );
}
emit changed();
}
@@ -766,36 +898,34 @@ void VideoHandle::seekSliderEvent( int new_frame_num )
void VideoHandle::videoSelectionButtonEvent()
{
VideoSubWindow* videoSubWindow;
Qt::KeyboardModifiers keyModifiers = QApplication::keyboardModifiers();
if( keyModifiers & Qt::ControlModifier )
{
QList<SubWindowAbstract*> subWindowList =
m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_STREAM_SUBWINDOW );
for( int i = 0; i < subWindowList.size(); i++ )
for( auto subWindow : subWindowList )
{
videoSubWindow = qobject_cast<VideoSubWindow*>( subWindowList.at( i ) );
auto* videoSubWindow = qobject_cast<VideoStreamSubWindow*>( subWindow );
m_acPlayingSubWindows.append( videoSubWindow );
}
}
else
{
SubWindowSelectorDialog dialogWindowsSelection( m_pcParet, m_pcMainWindowManager,
SubWindowSelectorDialog dialogWindowsSelection( m_pcParent, m_pcMainWindowManager,
SubWindowAbstract::VIDEO_STREAM_SUBWINDOW );
QStringList cWindowListNames;
for( int i = 0; i < m_acPlayingSubWindows.size(); i++ )
for( auto playingSubWindow : m_acPlayingSubWindows )
{
dialogWindowsSelection.selectSubWindow( m_acPlayingSubWindows.at( i ) );
dialogWindowsSelection.selectSubWindow( playingSubWindow );
}
if( dialogWindowsSelection.exec() == QDialog::Accepted )
{
m_acPlayingSubWindows.clear();
QList<SubWindowAbstract*> selectedSubWindowList = dialogWindowsSelection.getSelectedWindows();
for( int i = 0; i < selectedSubWindowList.size(); i++ )
for( auto window : selectedSubWindowList )
{
videoSubWindow = qobject_cast<VideoSubWindow*>( selectedSubWindowList.at( i ) );
auto* videoSubWindow = qobject_cast<VideoStreamSubWindow*>( window );
m_acPlayingSubWindows.append( videoSubWindow );
}
}
@@ -807,7 +937,7 @@ void VideoHandle::videoSelectionButtonEvent()
if( m_acPlayingSubWindows.size() > 0 )
{
m_acPlayingSubWindows.at( 0 )->activateWindow();
m_acPlayingSubWindows.front()->activateWindow();
if( m_acPlayingSubWindows.size() > 1 )
{
m_arrayActions[VIDEO_LOCK_ACT]->setVisible( true );
@@ -826,6 +956,19 @@ void VideoHandle::videoSelectionButtonEvent()
}
}
void VideoHandle::setComponent( int component )
{
if( m_pcCurrentVideoSubWindow == nullptr ) return;
if( component < 0 )
{
m_pcCurrentVideoSubWindow->getViewArea()->clearFilteredChannel();
}
else
{
m_pcCurrentVideoSubWindow->getViewArea()->setFilteredChannel( static_cast<std::size_t>( component ) );
}
}
void VideoHandle::setTool( int tool )
{
m_uiViewTool = tool;
+28 -18
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,29 +25,29 @@
#ifndef __VIDEOHANDLE_H__
#define __VIDEOHANDLE_H__
#include "CommonDefs.h"
#include "config.h"
#include <QElapsedTimer>
#include <QMenu>
#include <QPoint>
#include <QThread>
#include <QVector>
#include <QWidget>
//#define _CONTROL_PLAYING_TIME_ 1
#include "CommonDefs.h"
#include "VideoSubWindow.h"
#include "config.h"
class QToolBar;
class QDockWidget;
class QSignalMapper;
class QLabel;
class QSlider;
class QElapsedTimer;
class SubWindowHandle;
class SubWindowAbstract;
class VideoSubWindow;
class VideoStreamSubWindow;
class FramePropertiesDock;
class FrameNumberWidget;
class QTimer;
class VideoHandle : public QObject
{
@@ -59,7 +59,7 @@ public:
void createActions();
QMenu* createVideoMenu();
QMenu* createImageMenu();
QToolBar* createToolBar();
QPointer<QToolBar> createToolBar();
QDockWidget* createDock();
QWidget* createStatusBarMessage();
void updateMenus();
@@ -72,7 +72,7 @@ public:
void addSubWindow( VideoSubWindow* subWindow );
private:
QWidget* m_pcParet;
QWidget* m_pcParent;
SubWindowHandle* m_pcMainWindowManager;
enum
{
@@ -97,6 +97,11 @@ private:
QSlider* m_pcFrameSlider;
FrameNumberWidget* m_pcFrameNumInfo;
// Filter component actions
QMenu* m_menuComponent;
QActionGroup* m_actionGroupComponent;
QSignalMapper* m_mapperComponent;
// Tools Actions
QActionGroup* m_actionGroupTools;
QSignalMapper* m_mapperTools;
@@ -108,28 +113,30 @@ private:
QMenu* m_pcMenuVideo;
QMenu* m_pcMenuImage;
QToolBar* m_toolbarVideo;
// QToolBar* m_toolbarVideo;
QDockWidget* m_pcFramePropertiesDock;
FramePropertiesDock* m_pcFramePropertiesSideBar;
QLabel* m_pcPlayingFPSLabel;
QLabel* m_pcVideoFormatLabel;
QLabel* m_pcResolutionLabel;
VideoSubWindow* m_pcCurrentVideoSubWindow;
QVector<VideoSubWindow*> m_acPlayingSubWindows;
QPointer<VideoSubWindow> m_pcCurrentVideoSubWindow{ nullptr };
QVector<VideoStreamSubWindow*> m_acPlayingSubWindows;
QTimer* m_pcPlayingTimer;
bool m_bIsPlaying;
bool m_bIsPlaying{ false };
#if( _CONTROL_PLAYING_TIME_ == 1 )
unsigned int m_uiNumberPlayedFrames;
double m_dAverageFps;
QElapsedTimer* m_pcPlayControlTimer;
#endif
unsigned int m_uiNumberPlayedFrames{ 0 };
unsigned int m_uiRealAverageFrameRate{ 0 };
std::unique_ptr<QElapsedTimer> m_pcFrameRateFeedbackTimer;
void configureFrameRateTimer();
void calculateRealFrameRate();
unsigned long getMaxFrameNumber();
void setTimerStatus();
void updateComponentMenu();
Q_SIGNALS:
void changed();
@@ -140,13 +147,16 @@ private Q_SLOTS:
void closeSubWindow( SubWindowAbstract* subWindow );
void zoomToFactorAll( const double factor, const QPoint center = QPoint() );
void moveAllScrollBars( const double&, const double& );
void play();
void stop();
void playEvent();
void seekSliderEvent( int new_frame_num );
void seekEvent( int direction );
void seekVideo();
void videoSelectionButtonEvent();
void setComponent( int component );
void setTool( int tool );
void toggleGrid( bool checked );
void setGridSize( int size );
+423
View File
@@ -0,0 +1,423 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file VideoStreamSubWindow.cpp
* \brief Video Sub windows handling
*/
#include "VideoStreamSubWindow.h"
#include <QScrollArea>
#include <QSettings>
#include <QStaticText>
#include <cassert>
#include "ConfigureFormatDialog.h"
#include "ModulesHandle.h"
#include "QtConcurrent/qtconcurrentrun.h"
#include "ResourceHandle.h"
#include "SubWindowAbstract.h"
#define QT_NO_CONCURRENT
VideoStreamSubWindow::VideoStreamSubWindow( ResourceHandle* resourceManager, QWidget* parent )
: VideoSubWindow( VideoSubWindow::VIDEO_STREAM_SUBWINDOW, parent )
, m_pcResourceManager{ resourceManager }
, m_pCurrStream{ NULL }
, m_bIsPlaying{ false }
{
}
VideoStreamSubWindow::~VideoStreamSubWindow()
{
if( m_pcResourceManager ) m_pcResourceManager->removeResource( m_uiResourceId );
}
void VideoStreamSubWindow::resetWindowName()
{
setWindowName( QFileInfo( m_cFilename ).fileName() );
}
void VideoStreamSubWindow::updateVideoWindowInfo()
{
m_cStreamInformation = "";
if( m_pcDisplayModule )
{
m_cStreamInformation = "Module";
const auto& arraySubWindows = m_pcDisplayModule->getSubWindowList();
QStringList windowInfoList;
if( arraySubWindows.size() > 0 )
{
for( std::size_t i = 0; i < arraySubWindows.size(); i++ )
{
if( arraySubWindows[i]->getWindowName() != getWindowName() )
{
windowInfoList.append( QString( "Input %1 - " + arraySubWindows[i]->getWindowName() ).arg( i + 1 ) );
}
}
}
if( m_pcDisplayModule->hasFeature( ClpModuleFeature::HasInfo ) )
{
QStringList list = QString::fromStdString( m_pcDisplayModule->moduleInfo() ).split( '\n' );
windowInfoList.append( list );
}
if( windowInfoList.size() > 0 )
{
m_pcVideoInfo->setInformationTopLeft( windowInfoList );
}
}
else if( m_pCurrStream )
{
QString m_cFormatName = QString::fromStdString( m_pCurrStream->getFormatName() );
QString m_cCodedName = QString::fromStdString( m_pCurrStream->getCodecName() );
m_cStreamInformation = m_cFormatName + " | " + m_cCodedName;
}
if( m_pcCurrFrameAsset )
{
QString m_cPelFmtName = QString::fromStdString( m_pcCurrFrameAsset->getPelFmtName() );
if( m_pCurrStream )
if( !m_pCurrStream->isNative() ) m_cPelFmtName += "*";
m_cStreamInformation += " | " + m_cPelFmtName;
}
if( m_cStreamInformation.isEmpty() )
{
m_cStreamInformation = " ";
}
}
void VideoStreamSubWindow::loadAll()
{
QApplication::setOverrideCursor( Qt::WaitCursor );
m_pCurrStream->loadAll();
refreshFrame();
QApplication::restoreOverrideCursor();
}
void VideoStreamSubWindow::setResource( std::size_t id )
{
m_uiResourceId = id;
m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId );
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->startResourceWorker( m_uiResourceId );
#endif
QApplication::restoreOverrideCursor();
refreshFrame();
m_cFilename = QString::fromStdString( m_pCurrStream->getFileName() );
updateVideoWindowInfo();
setWindowName( QFileInfo( m_cFilename ).fileName() );
}
// bool VideoStreamSubWindow::loadFile( QString cFilename, bool bForceDialog )
// {
// assert( m_pcResourceManager != nullptr );
// ConfigureFormatDialog formatDialog( this );
// unsigned int Width = 0, Height = 0, BitsPel = 8, FrameRate = 30;
// int Endianness = CLP_LITTLE_ENDIAN;
// auto InputFormat = ClpPixelFormats::YUV420p;
// QSettings appSettings;
// if( m_pCurrStream )
// m_pCurrStream->getFormat( Width, Height, InputFormat, BitsPel, Endianness, FrameRate );
// else
// m_uiResourceId = m_pcResourceManager->getResource( nullptr );
// m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId );
// bool bConfig = true;
// if( !bForceDialog )
// {
// bConfig = guessFormat( cFilename, Width, Height, InputFormat, BitsPel, Endianness, FrameRate );
// if( bConfig )
// {
// // Pre-load values with last opened file
// Width = appSettings.value( "VideoStreamSubWindow/LastWidth" ).value<unsigned int>();
// Height = appSettings.value( "VideoStreamSubWindow/LastHeight" ).value<unsigned int>();
// BitsPel = appSettings.value( "VideoStreamSubWindow/LastBitsPerPixel" ).value<unsigned int>();
// }
// }
// bool bRet{ false };
// bool forceRaw{ false };
// for( int iPass = 0; iPass < 2 && !bRet; iPass++ )
// {
// if( iPass || bConfig )
// {
// if( formatDialog.runConfigureFormatDialog( QFileInfo( cFilename ).fileName(), Width, Height, InputFormat,
// BitsPel,
// Endianness, FrameRate ) == QDialog::Rejected )
// {
// return false;
// }
// }
// try
// {
// bRet = m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness,
// FrameRate,
// iPass == 1, CalypStream::Type::Input );
// forceRaw = iPass > 0;
// }
// catch( CalypFailure& e )
// {
// if( iPass > 0 )
// throw( e );
// }
// }
// if( !bRet )
// {
// return false;
// }
// m_sStreamInfo.m_cFilename = cFilename;
// m_sStreamInfo.m_uiWidth = Width;
// m_sStreamInfo.m_uiHeight = Height;
// m_sStreamInfo.m_iPelFormat = InputFormat;
// m_sStreamInfo.m_uiBitsPelPixel = BitsPel;
// m_sStreamInfo.m_iEndianness = Endianness;
// m_sStreamInfo.m_uiFrameRate = FrameRate;
// m_sStreamInfo.m_uiFileSize = QFileInfo( cFilename ).size();
// m_sStreamInfo.m_bForceRaw = forceRaw;
// QVariant var;
// var.setValue<unsigned int>( Width );
// appSettings.setValue( "VideoStreamSubWindow/LastWidth", var );
// var.setValue<unsigned int>( Height );
// appSettings.setValue( "VideoStreamSubWindow/LastHeight", var );
// var.setValue<unsigned int>( BitsPel );
// appSettings.setValue( "VideoStreamSubWindow/LastBitsPerPixel", var );
// #ifdef CALYP_MANAGED_RESOURCES
// m_pcResourceManager->startResourceWorker( m_uiResourceId );
// #endif
// QApplication::restoreOverrideCursor();
// refreshFrame();
// m_cFilename = cFilename;
// updateVideoWindowInfo();
// setWindowName( QFileInfo( m_cFilename ).fileName() );
// return true;
// }
// bool VideoStreamSubWindow::loadFile( CalypFileInfo streamInfo )
// {
// assert( m_pcResourceManager != nullptr );
// m_uiResourceId = m_pcResourceManager->getResource( m_pCurrStream );
// m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId );
// if( !m_pCurrStream->open( streamInfo.m_cFilename.toStdString(), streamInfo.m_uiWidth, streamInfo.m_uiHeight,
// static_cast<ClpPixelFormats>( streamInfo.m_iPelFormat ), streamInfo.m_uiBitsPelPixel,
// streamInfo.m_iEndianness, streamInfo.m_uiFrameRate, streamInfo.m_bForceRaw,
// CalypStream::Type::Input ) )
// {
// return false;
// }
// m_cFilename = streamInfo.m_cFilename;
// m_sStreamInfo = std::move( streamInfo );
// #ifdef CALYP_MANAGED_RESOURCES
// m_pcResourceManager->startResourceWorker( m_uiResourceId );
// #endif
// QApplication::restoreOverrideCursor();
// refreshFrame();
// updateVideoWindowInfo();
// setWindowName( QFileInfo( m_cFilename ).fileName() );
// return true;
// }
void VideoStreamSubWindow::refreshSubWindow()
{
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->stopResourceWorker( m_uiResourceId );
#endif
if( !m_pCurrStream->reload() )
{
close();
return;
}
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->startResourceWorker( m_uiResourceId );
#endif
updateVideoWindowInfo();
refreshFrame();
}
void VideoStreamSubWindow::refreshFrame()
{
bool bSetFrame = true;
m_pcCurrFrameAsset = m_pCurrStream->getCurrFrameAsset();
if( m_pcDisplayModule )
{
// bool disableThreads = !m_bIsPlaying && hasAssociatedModule();
m_pcDisplayModule->apply( m_bIsPlaying, true );
bSetFrame = false;
}
if( bSetFrame ) VideoSubWindow::refreshFrame();
}
void VideoStreamSubWindow::refreshFrame( bool bThreaded )
{
#ifndef QT_NO_CONCURRENT
m_cRefreshResult.waitForFinished();
if( bThreaded )
{
m_cRefreshResult = QtConcurrent::run( this, &VideoSubWindow::refreshFrame );
}
else
#endif
{
refreshFrame();
}
}
bool VideoStreamSubWindow::goToNextFrame( bool bThreaded )
{
#ifndef QT_NO_CONCURRENT
m_cRefreshResult.waitForFinished();
m_cReadResult.waitForFinished();
#endif
#ifdef CALYP_MANAGED_RESOURCES
while( !m_pCurrStream->hasNextFrame() && !m_pCurrStream->isEof() )
{
}
#endif
bool bEndOfSeq = m_pCurrStream->setNextFrame();
#ifdef CALYP_MANAGED_RESOURCES
bThreaded = false;
m_pcResourceManager->wakeResourceWorker( m_uiResourceId );
#endif
if( !bEndOfSeq )
{
#ifndef QT_NO_CONCURRENT
m_cRefreshResult.waitForFinished();
if( bThreaded )
{
m_cReadResult = QtConcurrent::run( m_pCurrStream, &CalypStream::readNextFrameFillRGBBuffer );
refreshFrame( bThreaded );
}
else
#endif
{
refreshFrame( bThreaded );
#ifndef CALYP_MANAGED_RESOURCES
m_pCurrStream->readNextFrameFillRGBBuffer();
#endif
}
}
return bEndOfSeq;
}
bool VideoStreamSubWindow::saveStream( const QString& filename )
{
bool iRet = false;
QApplication::setOverrideCursor( Qt::WaitCursor );
// TODO: implement this
QApplication::restoreOverrideCursor();
return iRet;
}
bool VideoStreamSubWindow::isPlaying()
{
return m_bIsPlaying;
}
bool VideoStreamSubWindow::play()
{
bool isPlaying = false;
if( m_pCurrStream && m_pCurrStream->getFrameNum() > 1 )
{
isPlaying = true;
}
m_bIsPlaying = isPlaying;
return m_bIsPlaying;
}
bool VideoStreamSubWindow::playEvent()
{
bool bEndOfSeq = false;
if( m_pCurrStream && m_bIsPlaying )
{
bEndOfSeq = goToNextFrame( true );
}
return bEndOfSeq;
}
void VideoStreamSubWindow::pause()
{
m_bIsPlaying = false;
refreshFrame();
}
void VideoStreamSubWindow::seekAbsoluteEvent( unsigned int new_frame_num )
{
if( m_pCurrStream )
{
if( m_pCurrStream->seekInput( new_frame_num ) ) refreshFrame();
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->wakeResourceWorker( m_uiResourceId );
#endif
}
}
void VideoStreamSubWindow::seekRelativeEvent( bool bIsForward )
{
if( m_pCurrStream )
{
if( bIsForward )
{
goToNextFrame( true );
}
else
{
m_pCurrStream->seekInputRelative( bIsForward );
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->wakeResourceWorker( m_uiResourceId );
#endif
refreshFrame();
}
}
}
void VideoStreamSubWindow::stop()
{
#ifndef QT_NO_CONCURRENT
m_cRefreshResult.waitForFinished();
m_cReadResult.waitForFinished();
#endif
m_bIsPlaying = false;
seekAbsoluteEvent( 0 );
return;
}
+112
View File
@@ -0,0 +1,112 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file VideoStreamSubWindow.h
* \brief Video Sub windows handling
*/
#ifndef __VIDEOSTREAMSUBWINDOW_H__
#define __VIDEOSTREAMSUBWINDOW_H__
#include <QDataStream>
#include <QFuture>
#include <QRect>
#include <QString>
#include <QVector>
#include <cstdint>
#include "CommonDefs.h"
#include "VideoSubWindow.h"
#include "config.h"
#include "lib/CalypStream.h"
#include "models/VideostreamResource.h"
class QScrollArea;
class VideoInformation;
class VideoStreamSubWindow;
class ResourceHandle;
class CalypAppModuleIf;
class VideoStreamSubWindow : public VideoSubWindow
{
Q_OBJECT
public:
VideoStreamSubWindow( ResourceHandle* resourceManager, QWidget* parent = 0 );
~VideoStreamSubWindow();
void resetWindowName() override;
void updateVideoWindowInfo() override;
bool isPlaying() override;
void stop() override;
void advanceOneFrame() override { goToNextFrame( true ); }
auto getFrameNum() -> std::uint64_t override { return m_pCurrStream->getFrameNum(); }
bool supportsFormatConfiguration() const { return m_pCurrStream->supportsFormatConfiguration(); };
void setResource( std::size_t id );
auto getResourceId() const -> std::size_t { return m_uiResourceId; };
// bool loadFile( QString cFilename, bool bForceDialog = false );
// bool loadFile( CalypFileInfo streamInfo );
void loadAll();
bool saveStream( const QString& filename );
bool play();
void pause();
bool playEvent();
void seekAbsoluteEvent( unsigned int new_frame_num );
void seekRelativeEvent( bool bIsFoward );
CalypFileInfo getStreamInfo() { return m_sStreamInfo; }
const CalypStream* getInputStream() { return m_pCurrStream; }
const CalypStream* getCurrStream() { return m_pCurrStream; }
QString getCurrentFileName() { return m_cFilename; }
void refreshSubWindow() override;
void refreshFrame();
void refreshFrame( bool bThreaded );
private:
bool goToNextFrame( bool bThreaded );
private: // NO_LINT
ResourceHandle* m_pcResourceManager;
std::size_t m_uiResourceId;
QString m_cFilename;
CalypFileInfo m_sStreamInfo;
CalypStream* m_pCurrStream;
QString m_cCurrFileName;
bool m_bIsPlaying;
/**
* Threads variables
* QtConcurrent
*/
QFuture<void> m_cRefreshResult;
QFuture<void> m_cReadResult;
};
#endif // __VIDEOSTREAMSUBWINDOW_H__
+213 -703
View File
File diff suppressed because it is too large. Load diff
+78 -114
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -28,8 +28,11 @@
#include <QDataStream>
#include <QFuture>
#include <QRect>
#include <QStaticText>
#include <QString>
#include <QVector>
#include "CalypAppModuleIf.h"
#include "CommonDefs.h"
#include "SubWindowAbstract.h"
#include "ViewArea.h"
@@ -40,67 +43,35 @@ class QScrollArea;
class VideoInformation;
class VideoSubWindow;
class ResourceHandle;
class CalypAppModuleIf;
typedef struct
/**
* \class VideoInformation
* \brief Shows information about video sub window
*/
class VideoInformation : public QWidget
{
QString m_cFilename;
unsigned int m_uiWidth;
unsigned int m_uiHeight;
int m_iPelFormat;
unsigned int m_uiBitsPelPixel;
unsigned int m_iEndianness;
unsigned int m_uiFrameRate;
unsigned long long int m_uiFileSize;
} CalypFileInfo;
typedef QVector<CalypFileInfo> CalypFileInfoVector;
public:
VideoInformation( QWidget* parent );
void setInformationTopLeft( const QStringList& textLines );
void setBusyWindow( bool bFlag );
QDataStream& operator<<( QDataStream& out, const CalypFileInfoVector& d );
QDataStream& operator>>( QDataStream& in, CalypFileInfoVector& d );
int findCalypStreamInfo( CalypFileInfoVector array, QString filename );
protected:
void paintEvent( QPaintEvent* event ) override;
private:
QTimer* m_pcRefreshTimer;
QList<QStaticText> m_cTopLeftTextList;
QFont m_cTopLeftTextFont;
QFont m_cCenterTextFont;
bool m_bBusyWindow;
};
class VideoSubWindow : public SubWindowAbstract
{
Q_OBJECT
private:
bool m_bWindowBusy;
QScrollArea* m_pcScrollArea;
QPoint m_cCurrScroll;
double m_dHorScroll;
double m_dVerScroll;
ViewArea* m_cViewArea;
VideoInformation* m_pcVideoInfo;
QString m_cFilename;
QString m_cStreamInformation;
CalypFileInfo m_sStreamInfo;
CalypStream* m_pCurrStream;
CalypFrame* m_pcCurrFrame;
QRect m_cSelectedArea;
CalypAppModuleIf* m_pcCurrentDisplayModule;
QList<CalypAppModuleIf*> m_apcCurrentModule;
VideoSubWindow* m_pcReferenceSubWindow;
// QString m_cWindowShortName;
QString m_cCurrFileName;
bool m_bIsPlaying;
QTimer* m_pcUpdateTimer;
/**
* Threads variables
* QtConcurrent
*/
QFuture<void> m_cRefreshResult;
QFuture<void> m_cReadResult;
public:
enum VideoSubWindowCategories
{
@@ -110,90 +81,63 @@ public:
VideoSubWindow( enum VideoSubWindowCategories category, QWidget* parent = 0 );
~VideoSubWindow();
void updateVideoWindowInfo();
virtual void resetWindowName() = 0;
virtual void updateVideoWindowInfo() = 0;
bool loadFile( QString cFilename, bool bForceDialog = false );
bool loadFile( CalypFileInfo* streamInfo );
void loadAll();
bool save( QString filename );
bool saveStream( QString filename );
virtual bool isPlaying() = 0;
virtual void stop() = 0;
virtual void advanceOneFrame() = 0;
virtual auto getFrameNum() -> std::uint64_t { return 1; };
void refreshSubWindow();
void refreshFrame( bool bThreaded = false );
QString getVideoInformation() { return m_cStreamInformation; }
bool save( const QString& filename );
bool play();
void pause();
bool playEvent();
void stop();
void setCurrFrame( std::shared_ptr<CalypFrame> pcCurrFrame );
bool isPlaying() { return m_bIsPlaying; }
void seekAbsoluteEvent( unsigned int new_frame_num );
void seekRelativeEvent( bool bIsFoward );
auto getCurrFrame() -> CalypFrame* { return m_pcCurrFrameAsset.get(); }
auto getCurrFrameAsset() -> std::shared_ptr<CalypFrame> { return m_pcCurrFrameAsset; };
auto getViewArea() -> ViewArea* { return m_cViewArea; }
void setCurrFrame( CalypFrame* pcCurrFrame );
CalypFileInfo getStreamInfo() { return m_sStreamInfo; }
QString getStreamInformation() { return m_cStreamInformation; }
CalypStream* getInputStream() { return m_pCurrStream; }
CalypStream* getCurrStream() { return m_pCurrStream; }
CalypFrame* getCurrFrame() { return m_pcCurrFrame; }
ViewArea* getViewArea() { return m_cViewArea; }
VideoSubWindow* getRefSubWindow() { return m_pcReferenceSubWindow; }
void setRefSubWindow( VideoSubWindow* subWindow )
{
m_pcReferenceSubWindow = NULL;
if( subWindow )
if( m_pcCurrFrame->haveSameFmt( subWindow->getCurrFrame() ) )
if( m_pcCurrFrameAsset->haveSameFmt( subWindow->getCurrFrame() ) )
m_pcReferenceSubWindow = subWindow;
}
VideoSubWindow* getRefSubWindow() { return m_pcReferenceSubWindow; }
/**
* Functions to enable a module in the
* current SubWindow
*/
void enableModule( CalypAppModuleIf* pcModule );
void disableModule( CalypAppModuleIf* pcModule = NULL );
void associateModule( CalypAppModuleIf* pcModule );
CalypAppModuleIf* getDisplayModule() { return m_pcCurrentDisplayModule; }
QList<CalypAppModuleIf*> getModuleArray()
{
QList<CalypAppModuleIf*> apcModulesArray;
if( m_pcCurrentDisplayModule )
apcModulesArray.append( m_pcCurrentDisplayModule );
apcModulesArray.append( m_apcCurrentModule );
return apcModulesArray;
}
auto hasModules() -> bool { return m_associatedModules.size() > 0; }
bool hasAssociatedModule();
void setDisplayModule( CalypAppModuleIf* pcModule );
void associateModule( std::shared_ptr<CalypAppModuleIf> pcModule );
void disableModule( CalypAppModuleIf* pcModule );
bool disableAllModules();
CalypAppModuleIf* getDisplayModule() { return m_pcDisplayModule; }
/**
* Virtual functions from SubWindowAbstract
*/
void normalSize();
void zoomToFit();
void scaleView( double scale, QPoint center = QPoint() );
void zoomToFactor( double factor, QPoint center = QPoint() );
void normalSize() override;
void zoomToFit() override;
void scaleView( double scale, QPoint center = QPoint() ) override;
void zoomToFactor( double factor, QPoint center = QPoint() ) override;
double getScaleFactor() { return m_cViewArea->getZoomFactor(); }
double getScaleFactor() override { return m_cViewArea->getZoomFactor(); }
/**
* Size related functions
*/
QSize sizeHint() const;
QSize sizeHint( const QSize& ) const;
QSize sizeHint( const QSize& ) const override;
QString getCurrentFileName() { return m_cFilename; }
bool getIsModule() { return getCategory() | SubWindowAbstract::MODULE_SUBWINDOW; }
void clearWindowBusy() { m_bWindowBusy = false; }
void setFillWindow( bool bFlag );
void adjustScrollBarToRatio( const double& horRatio, const double& verRatio );
void adjustScrollBarToRatio( const double horRatio, const double verRatio );
private:
void refreshFrameOperation();
bool goToNextFrame( bool bThreaded = false );
static bool guessFormat( QString filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBitsPerPixel,
int& rEndianness, unsigned int& rFrameRate );
bool hasRunningModule();
/**
@@ -205,9 +149,11 @@ private:
QSize getScrollSize();
protected:
void keyPressEvent( QKeyEvent* event );
void resizeEvent( QResizeEvent* event );
void closeEvent( QCloseEvent* event );
void refreshFrame();
void keyPressEvent( QKeyEvent* event ) override;
void resizeEvent( QResizeEvent* event ) override;
void closeEvent( QCloseEvent* event ) override;
public Q_SLOTS:
void updateWindowOnTimeout();
@@ -216,9 +162,27 @@ public Q_SLOTS:
void updateScrollValues();
void updateSelectedArea( QRect area );
void updatePixelValueStatusBar( const QPoint& pos );
protected:
VideoInformation* m_pcVideoInfo;
QString m_cStreamInformation;
std::shared_ptr<CalypFrame> m_pcCurrFrameAsset;
// bool m_bWindowBusy;
// bool m_bIsPlaying;
std::vector<std::shared_ptr<CalypAppModuleIf>> m_associatedModules;
CalypAppModuleIf* m_pcDisplayModule{ nullptr };
// bool m_hasAssociatedModules;
private:
QScrollArea* m_pcScrollArea;
QPoint m_cCurrScroll;
double m_dHorScroll{ 0 };
double m_dVerScroll{ 0 };
ViewArea* m_cViewArea;
QRect m_cSelectedArea;
VideoSubWindow* m_pcReferenceSubWindow;
QTimer* m_pcUpdateTimer;
};
Q_DECLARE_METATYPE( CalypFileInfo )
Q_DECLARE_METATYPE( CalypFileInfoVector )
#endif // __VIDEOSUBWINDOW_H__
+169 -131
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,8 @@
#include "ViewArea.h"
#include "GridManager.h"
#include <qcolor.h>
#include <qnamespace.h>
#include <QColor>
#include <QCoreApplication>
@@ -38,68 +39,105 @@
#include <QRectF>
#include <QString>
#include <QWidget>
#include <cmath>
static const QColor selectionColor = Qt::cyan;
static const QColor imageMaskColor = Qt::green;
static const QColor eraserColor = Qt::red;
#include "GridManager.h"
#if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0 )
constexpr auto kSelectionColor = QColorConstants::Cyan;
constexpr auto kImageMaskColor = QColorConstants::Green;
constexpr auto kEraserColor = QColorConstants::Red;
#else
static const QColor kSelectionColor = Qt::cyan;
static const QColor kImageMaskColor = Qt::green;
static const QColor kEraserColor = Qt::red;
#endif
constexpr double kMaxZoom = 100.0;
constexpr double kMinZoom = 0.01;
ViewArea::ViewArea( QWidget* parent )
: QWidget( parent )
{
setMouseTracking( true );
m_pcCurrFrame = NULL;
m_pixmap = QPixmap();
m_grid = GridManager();
m_mask = QBitmap();
m_selectedArea = QRect();
m_dZoomFactor = 1;
m_xOffset = 0;
m_yOffset = 0;
m_mode = NormalMode;
m_eTool = NavigationTool;
m_bGridVisible = false;
m_snapToGrid = false;
m_blockTrackEnable = false;
m_visibleZoomRect = true;
m_zoomWinTimer.setSingleShot( true );
m_zoomWinTimer.setInterval( 2000 );
connect( &m_zoomWinTimer, SIGNAL( timeout() ), this, SLOT( update() ) );
}
void ViewArea::setImage( CalypFrame* pcFrame )
void ViewArea::setImage( std::shared_ptr<CalypFrame> frame )
{
m_pcCurrFrame = pcFrame;
m_uiPixelHalfScale = 1 << ( m_pcCurrFrame->getBitsPel() - 1 );
m_pcCurrFrame->fillRGBBuffer();
QImage qimg = QImage( m_pcCurrFrame->getRGBBuffer(), m_pcCurrFrame->getWidth(), m_pcCurrFrame->getHeight(),
QImage::Format_ARGB32 );
setImage( QPixmap::fromImage( qimg ) );
}
m_nextFrame = frame;
m_uiPixelHalfScale = 1 << ( m_nextFrame->getBitsPel() - 1 );
if( m_filterSingleChannel.has_value() )
{
m_nextFrame->fillRGBBuffer( m_filterSingleChannel );
}
else
{
m_nextFrame->fillRGBBuffer();
}
void ViewArea::setImage( const QPixmap& pixmap )
{
m_pixmap = pixmap;
m_mask = QBitmap( pixmap.width(), pixmap.height() );
m_mask.clear();
auto rgb_buffer = *m_nextFrame->getRGBBuffer();
m_image = QImage( rgb_buffer.data(),
m_nextFrame->getWidth(),
m_nextFrame->getHeight(),
QImage::Format_ARGB32 );
// m_mask = QBitmap( pixmap.width(), pixmap.height() );
// m_mask.clear();
updateSize();
update();
updateGeometry();
initZoomWinRect();
}
void ViewArea::clear()
// void ViewArea::clear()
// {
// m_image = QImage();
// m_mask = QBitmap();
// m_mode = NormalMode;
// updateSize();
// update();
// updateGeometry();
// }
auto ViewArea::getFilteredChannel() -> std::optional<std::size_t>
{
m_pixmap = QPixmap();
m_mask = QBitmap();
m_mode = NormalMode;
updateSize();
return m_filterSingleChannel;
}
void ViewArea::setFilteredChannel( std::size_t channel )
{
m_filterSingleChannel = channel;
if( m_nextFrame != nullptr )
{
m_nextFrame->fillRGBBuffer( m_filterSingleChannel );
auto rgb_buffer = *m_nextFrame->getRGBBuffer();
m_image = QImage( rgb_buffer.data(),
m_nextFrame->getWidth(),
m_nextFrame->getHeight(),
QImage::Format_ARGB32 );
}
update();
}
void ViewArea::clearFilteredChannel()
{
m_filterSingleChannel = {};
if( m_nextFrame != nullptr )
{
m_nextFrame->fillRGBBuffer( m_filterSingleChannel );
auto rgb_buffer = *m_nextFrame->getRGBBuffer();
m_image = QImage( rgb_buffer.data(),
m_nextFrame->getWidth(),
m_nextFrame->getHeight(),
QImage::Format_ARGB32 );
}
update();
updateGeometry();
}
void ViewArea::setTool( unsigned int view )
@@ -167,14 +205,14 @@ void ViewArea::setZoomFactor( double f )
double ViewArea::scaleZoomFactor( double scale, QPoint center, QSize minimumSize )
{
double maxZoom = 100.0;
double minZoom = 0.01; //( 1.0 / m_pixmap.width() );
Q_ASSERT( !m_image.isNull() );
double new_scale = 1.0;
if( ( m_dZoomFactor == minZoom ) && ( scale < 1 ) )
if( ( m_dZoomFactor == kMinZoom ) && ( scale < 1 ) )
return new_scale;
if( ( m_dZoomFactor == maxZoom ) && ( scale > 1 ) )
if( ( m_dZoomFactor == kMaxZoom ) && ( scale > 1 ) )
return new_scale;
double newZoomFactor = m_dZoomFactor * scale * 100.0;
@@ -184,10 +222,10 @@ double ViewArea::scaleZoomFactor( double scale, QPoint center, QSize minimumSize
if( !minimumSize.isNull() )
{
double cw = m_pixmap.width() * m_dZoomFactor;
double ch = m_pixmap.height() * m_dZoomFactor;
double fw = m_pixmap.width() * newZoomFactor;
double fh = m_pixmap.height() * newZoomFactor;
double cw = m_image.width() * m_dZoomFactor;
double ch = m_image.height() * m_dZoomFactor;
double fw = m_image.width() * newZoomFactor;
double fh = m_image.height() * newZoomFactor;
double mw = minimumSize.width();
double mh = minimumSize.height();
@@ -215,16 +253,16 @@ double ViewArea::scaleZoomFactor( double scale, QPoint center, QSize minimumSize
new_scale = scale;
if( newZoomFactor < minZoom )
if( newZoomFactor < kMinZoom )
{
newZoomFactor = minZoom;
newZoomFactor = kMinZoom;
new_scale = newZoomFactor / m_dZoomFactor;
}
else
{
if( newZoomFactor > maxZoom )
if( newZoomFactor > kMaxZoom )
{
newZoomFactor = maxZoom;
newZoomFactor = kMaxZoom;
new_scale = newZoomFactor / m_dZoomFactor;
}
}
@@ -320,45 +358,45 @@ void ViewArea::setSnapToGrid( bool enable )
void ViewArea::initZoomWinRect()
{
int iMinX = 80;
int iMinY = 80;
double iMinX = 80;
double iMinY = 80;
int iMaxX = iMinX * 5;
int iMaxY = iMinY * 5;
double iMaxX = iMinX * 5;
double iMaxY = iMinY * 5;
double dSizeRatio, dWinZoomRatio;
int iHorizontalImg = ( m_pixmap.width() > m_pixmap.height() ) ? 1 : 0;
bool iHorizontalImg = m_image.width() > m_image.height();
if( iHorizontalImg )
{
dSizeRatio = (double)m_pixmap.width() / (double)m_pixmap.height();
dSizeRatio = (double)m_image.width() / (double)m_image.height();
}
else
{
dSizeRatio = (double)m_pixmap.height() / (double)m_pixmap.width();
dSizeRatio = (double)m_image.height() / (double)m_image.width();
}
if( dSizeRatio > 5.0 )
{
if( iHorizontalImg )
{
dWinZoomRatio = (double)( m_pixmap.width() * 1024 / iMaxX ) / 1000.0;
dWinZoomRatio = static_cast<double>( m_image.width() ) * 1024.0 / iMaxX / 1000.0;
}
else
{
dWinZoomRatio = (double)( m_pixmap.height() * 1024 / iMaxY ) / 1000.0;
dWinZoomRatio = static_cast<double>( m_image.height() ) * 1024.0 / iMaxY / 1000.0;
}
}
else
{
if( iHorizontalImg )
{
dWinZoomRatio = (double)( m_pixmap.height() * 1024 / iMinY ) / 1000.0;
dWinZoomRatio = static_cast<double>( m_image.height() ) * 1024.0 / iMinY / 1000.0;
}
else
{
dWinZoomRatio = (double)( m_pixmap.width() * 1024 / iMinX ) / 1000.0;
dWinZoomRatio = static_cast<double>( m_image.width() ) * 1024.0 / iMinX / 1000.0;
}
}
@@ -370,8 +408,8 @@ void ViewArea::initZoomWinRect()
////////////////////////////////////////////////////////////////////////////////
void ViewArea::updateSize()
{
int w = m_pixmap.width() * m_dZoomFactor;
int h = m_pixmap.height() * m_dZoomFactor;
int w = m_image.width() * m_dZoomFactor;
int h = m_image.height() * m_dZoomFactor;
setMinimumSize( w, h );
QWidget* p = parentWidget();
@@ -389,17 +427,17 @@ void ViewArea::updateSize()
void ViewArea::updateOffset()
{
if( width() > m_pixmap.width() * m_dZoomFactor )
if( width() > m_image.width() * m_dZoomFactor )
{
m_xOffset = ( width() - m_pixmap.width() * m_dZoomFactor ) / 2;
m_xOffset = ( width() - m_image.width() * m_dZoomFactor ) / 2;
}
else
{
m_xOffset = 0;
}
if( height() > m_pixmap.height() * m_dZoomFactor )
if( height() > m_image.height() * m_dZoomFactor )
{
m_yOffset = ( height() - m_pixmap.height() * m_dZoomFactor ) / 2;
m_yOffset = ( height() - m_image.height() * m_dZoomFactor ) / 2;
}
else
{
@@ -412,7 +450,7 @@ void ViewArea::updateOffset()
////////////////////////////////////////////////////////////////////////////////
void ViewArea::resizeEvent( QResizeEvent* event )
{
if( size().isEmpty() || m_pixmap.isNull() )
if( size().isEmpty() || m_image.isNull() )
return;
updateOffset();
@@ -425,12 +463,11 @@ void ViewArea::resizeEvent( QResizeEvent* event )
void ViewArea::paintEvent( QPaintEvent* event )
{
m_currFrame = m_nextFrame;
QRect winRect = event->rect();
if( visibleRegion().isEmpty() )
return;
if( size().isEmpty() || m_pixmap.isNull() )
if( visibleRegion().isEmpty() || size().isEmpty() || m_image.isNull() || m_currFrame == nullptr )
return;
QSize windowSize = parentWidget()->size();
@@ -443,15 +480,14 @@ void ViewArea::paintEvent( QPaintEvent* event )
// This line is for fast paiting. Only visible area of the image is painted.
// We take the exposed rect from the event (that gives us scroll/expose
// optimizations for free – no need
// to draw the whole pixmap if your widget is only partially exposed), and
// reverse map it with the painter matrix.
// optimizations for free – no need to draw the whole pixmap if your widget
// is only partially exposed), and reverse map it with the painter matrix.
// That gives us the part of the pixmap that has actually been exposed.
// See:
// http://blog.qt.digia.com/blog/2006/05/13/fast-transformed-pixmapimage-drawing/
QRect exposedRect = painter.worldTransform().inverted().mapRect( event->rect() ).adjusted( -1, -1, 1, 1 );
// See: http://blog.qt.digia.com/blog/2006/05/13/fast-transformed-pixmapimage-drawing/
QRect exposedRect = painter.worldTransform().inverted().mapRect( winRect ).adjusted( -1, -1, 1, 1 );
// Draw the pixmap.
painter.drawPixmap( exposedRect, m_pixmap, exposedRect );
// painter.drawPixmap( exposedRect, m_pixmap, exposedRect );
painter.drawImage( exposedRect, m_image, exposedRect );
// Draw the Grid if it's visible.
if( m_bGridVisible )
@@ -469,33 +505,33 @@ void ViewArea::paintEvent( QPaintEvent* event )
// is, is referenced to the not scaled image.
// To know what image area we need to update, just intersects the
// rectangle area with the image area.
vr &= QRect( 0, 0, m_pixmap.width(), m_pixmap.height() );
vr &= QRect( 0, 0, m_image.width(), m_image.height() );
// Set up for the grid drawer.
painter.setRenderHint( QPainter::Antialiasing );
// Draw grid.
m_grid.drawGrid( m_pixmap, vr, &painter );
m_grid.drawGrid( m_image, vr, &painter );
}
painter.restore();
// Draw a border around the image.
/* if( m_xOffset || m_yOffset )
{
painter.setPen( Qt::black );
painter.drawRect( m_xOffset - 1, m_yOffset - 1, m_pixmap.width() *
m_dZoomFactor + 1, m_pixmap.height() *
m_dZoomFactor + 1 );
}*/
{
painter.setPen( Qt::black );
painter.drawRect( m_xOffset - 1, m_yOffset - 1, m_image.width() *
m_dZoomFactor + 1, m_image.height() *
m_dZoomFactor + 1 );
}*/
int frFormat = m_pcCurrFrame->getColorSpace();
int frFormat = m_currFrame->getColorSpace();
// Draw pixel values in grid
if( m_dZoomFactor >= 60.0 || ( frFormat != CLP_COLOR_RGBA && m_dZoomFactor >= 50.0 ) )
{
int imageWidth = m_pixmap.width();
int imageHeight = m_pixmap.height();
int imageWidth = m_image.width();
int imageHeight = m_image.height();
;
QFont font( "Helvetica" );
@@ -513,7 +549,7 @@ void ViewArea::paintEvent( QPaintEvent* event )
QRect pixelRect( viewToWindow( pixelTopLeft ), QSize( m_dZoomFactor, m_dZoomFactor ) );
QString pixelValue;
CalypPixel pixel = m_pcCurrFrame->getPixel( pixelTopLeft.x(), pixelTopLeft.y() );
CalypPixel pixel = m_currFrame->getPixel( pixelTopLeft.x(), pixelTopLeft.y() );
if( frFormat == CLP_COLOR_YUV || frFormat == CLP_COLOR_GRAY )
{
@@ -560,33 +596,33 @@ void ViewArea::paintEvent( QPaintEvent* event )
painter.drawLine( viewToWindow( QPoint( 0, y ) ), viewToWindow( QPoint( imageWidth, y ) ) );
}
}
bool showZoomRect = m_pixmap.width() * m_dZoomFactor > windowSize.width() ||
m_pixmap.height() * m_dZoomFactor > windowSize.height();
bool showZoomRect = m_image.width() * m_dZoomFactor > windowSize.width() ||
m_image.height() * m_dZoomFactor > windowSize.height();
// VISIBLE ZOOM RECT
if( m_visibleZoomRect && m_zoomWinTimer.isActive() && showZoomRect )
{
double dRatio = m_dZoomWinRatio;
QRect cImg = QRect( 0, 0, m_pixmap.width(), m_pixmap.height() );
QRect cImg = QRect( 0, 0, m_image.width(), m_image.height() );
QPoint cZWinRBpos = QPoint( winRect.bottomRight() ) - QPoint( 15, 15 );
QRect cImgWinRect( 0, 0, round( (double)cImg.width() / dRatio ), round( (double)cImg.height() / dRatio ) );
cImgWinRect.moveBottomRight( cZWinRBpos );
QRect vr = windowToView( winRect );
QRect cVisibleImg = vr & cImg;
//cVisibleImg.moveTopLeft(vr.topLeft());
// cVisibleImg.moveTopLeft(vr.topLeft());
QRect cVisibleWinRect;
cVisibleWinRect.setLeft( floor( (double)cVisibleImg.x() / dRatio ) );
cVisibleWinRect.setTop( floor( (double)cVisibleImg.y() / dRatio ) );
cVisibleWinRect.setRight( round( (double)cVisibleImg.right() / dRatio ) );
cVisibleWinRect.setBottom( round( (double)cVisibleImg.bottom() / dRatio ) );
//painter.fillRect( cImgWinRect, QBrush( QColor( 128, 128, 128, 128 ) ) );
// painter.fillRect( cImgWinRect, QBrush( QColor( 128, 128, 128, 128 ) ) );
painter.setPen( QColor( 50, 50, 50, 128 ) );
//painter.drawRect( cImgWinRect );
// painter.drawRect( cImgWinRect );
painter.setOpacity( 0.7 );
painter.drawPixmap( cImgWinRect, m_pixmap );
painter.drawImage( cImgWinRect, m_image );
painter.setOpacity( 1 );
cVisibleWinRect.moveTopLeft( cImgWinRect.topLeft() + cVisibleWinRect.topLeft() );
@@ -607,7 +643,7 @@ void ViewArea::paintEvent( QPaintEvent* event )
painter.setPen( QColor( 255, 255, 255, 128 ) );
painter.drawRect( cVisibleWinRect );
//qDebug() << "Debug VisibleZoomRect: " << winRect << vr << cImgWinRect << cVisibleWinRect << cVisibleImg << dRatio;
// qDebug() << "Debug VisibleZoomRect: " << winRect << vr << cImgWinRect << cVisibleWinRect << cVisibleImg << dRatio;
}
QRect sr = viewToWindow( m_selectedArea );
@@ -618,7 +654,7 @@ void ViewArea::paintEvent( QPaintEvent* event )
if( m_newShape || m_blockTrackEnable )
{
// Set the tool color
QColor selectColor = selectionColor;
QColor selectColor = kSelectionColor;
selectColor.setAlpha( 120 );
@@ -643,7 +679,7 @@ void ViewArea::paintEvent( QPaintEvent* event )
painter.setBrush( fill );
painter.setPen( Qt::NoPen );
QPainterPath myPath;
QRect imgr = viewToWindow( QRect( 0, 0, m_pixmap.width(), m_pixmap.height() ) );
QRect imgr = viewToWindow( QRect( 0, 0, m_image.width(), m_image.height() ) );
myPath.addRect( imgr );
myPath.addRect( sr ); // m_selectedArea
@@ -672,7 +708,7 @@ void ViewArea::paintEvent( QPaintEvent* event )
if( m_maskColor.isValid() )
color = m_maskColor;
else
color = imageMaskColor;
color = kImageMaskColor;
color.setAlpha( 120 );
painter.setPen( color );
@@ -688,22 +724,20 @@ void ViewArea::paintEvent( QPaintEvent* event )
{
switch( tool() )
{
case MaskTool:
{
case MaskTool: {
if( m_maskColor.isValid() )
color = m_maskColor;
else
color = imageMaskColor;
color = kImageMaskColor;
break;
}
case EraserTool:
{
color = eraserColor;
case EraserTool: {
color = kEraserColor;
break;
}
default:
color = selectionColor; // ?Problems!
color = kSelectionColor; // ?Problems!
}
color.setAlpha( 120 );
@@ -733,7 +767,7 @@ void ViewArea::wheelEvent( QWheelEvent* event )
if( event->modifiers() & Qt::ControlModifier )
{
scale = 0.001 * event->delta();
scale = 0.001 * event->angleDelta().y();
if( scale > 0 )
scale = 1.25;
else
@@ -741,10 +775,16 @@ void ViewArea::wheelEvent( QWheelEvent* event )
QWidget* p = parentWidget();
QSize minimumSize = QSize( p->size().width() - 5, p->size().height() - 5 );
usedScale = scaleZoomFactor( scale, event->pos(), minimumSize );
#if QT_VERSION < QT_VERSION_CHECK( 5, 14, 0 )
auto eventPosition = event->pos();
#else
auto eventPosition = event->position().toPoint();
#endif
usedScale = scaleZoomFactor( scale, eventPosition, minimumSize );
if( usedScale != 1.0 )
{
emit zoomFactorChanged_byWheel( usedScale, event->pos() );
emit zoomFactorChanged_byWheel( usedScale, eventPosition );
}
}
}
@@ -755,7 +795,7 @@ void ViewArea::mousePressEvent( QMouseEvent* event )
QPoint vpos = windowToView( event->pos() );
if( event->button() == Qt::MidButton )
if( event->button() == Qt::MiddleButton )
{
}
if( event->button() == Qt::LeftButton )
@@ -902,24 +942,24 @@ void ViewArea::mouseMoveEvent( QMouseEvent* event )
}
}
/* else // if tool() == BlockSelectionTool || MaskTool || EraserTool
{
m_blockTrackEnable = false;
// If cursor is inside the selected area, we most redraw
// the selection rect because it may be smaller.
if( m_selectedArea.contains( actualPos ) )
{
m_selectedArea = m_grid.rectContains( m_lastPos );
}
{
m_blockTrackEnable = false;
// If cursor is inside the selected area, we most redraw
// the selection rect because it may be smaller.
if( m_selectedArea.contains( actualPos ) )
{
m_selectedArea = m_grid.rectContains( m_lastPos );
}
m_selectedArea = m_selectedArea.united( m_grid.rectContains( actualPos ) );
}
*/
m_selectedArea = m_selectedArea.united( m_grid.rectContains( actualPos ) );
}
*/
if( tool() == SelectionTool )
{
// intercept the selected area with the image area to limit the
// selection only to the image area, preventing it to come outside
// the image.
m_selectedArea &= QRect( 0, 0, m_pixmap.width(), m_pixmap.height() );
m_selectedArea &= QRect( 0, 0, m_image.width(), m_image.height() );
// Update only the united area
// updateRect = updateRect.united( viewToWindow( m_selectedArea ) );
@@ -1003,7 +1043,7 @@ void ViewArea::mouseReleaseEvent( QMouseEvent* event )
bool ViewArea::isPosValid( const QPoint& pos ) const
{
if( pos.x() < 0 || pos.y() < 0 || pos.x() >= m_pixmap.width() || pos.y() >= m_pixmap.height() )
if( pos.x() < 0 || pos.y() < 0 || pos.x() >= m_image.width() || pos.y() >= m_image.height() )
return false;
else
return true;
@@ -1075,8 +1115,7 @@ void ViewArea::updateMask( const QRect& rect )
{
switch( tool() )
{
case MaskTool:
{
case MaskTool: {
// Add rect to the mask
QPainter painter( &m_mask );
painter.setBrush( Qt::color1 );
@@ -1085,8 +1124,7 @@ void ViewArea::updateMask( const QRect& rect )
painter.end();
break;
}
case EraserTool:
{
case EraserTool: {
// Clears rect area in the mask
QPainter painter( &m_mask );
painter.setBrush( Qt::color0 );
@@ -1096,6 +1134,6 @@ void ViewArea::updateMask( const QRect& rect )
break;
}
default: /* Do Nothing */
;
;
}
}
+31 -32
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,17 +26,17 @@
#ifndef __VIEWAREA_H__
#define __VIEWAREA_H__
#include "CommonDefs.h"
#include "GridManager.h"
#include "config.h"
#include "lib/CalypFrame.h"
#include <QBitmap>
#include <QColor>
#include <QPixmap>
#include <QTimer>
#include <QWidget>
#include "CommonDefs.h"
#include "GridManager.h"
#include "config.h"
#include "lib/CalypFrame.h"
class CalypStream;
/**
@@ -56,17 +56,15 @@ public:
ViewArea( QWidget* parent = 0 );
void setImage( CalypFrame* pcFrame );
void setImage( const QPixmap& pixmap );
void setImage( std::shared_ptr<CalypFrame> frame );
auto getFilteredChannel() -> std::optional<std::size_t>;
void setFilteredChannel( std::size_t channel );
void clearFilteredChannel();
void setMode( int mode );
void setMaskColor( const QColor& color = QColor() );
/**
* Clears any contents.
*/
void clear();
/**
* Select tool from the menu
*/
@@ -83,8 +81,6 @@ public:
*/
void clearMask();
QPixmap image() const { return m_pixmap; }
QBitmap mask() const { return m_mask; }
QRect selectedArea() const { return m_selectedArea; }
GridManager gridManager() const { return m_grid; }
QColor maskColor() const { return m_maskColor; }
@@ -110,12 +106,12 @@ public Q_SLOTS:
// void setSelectedArea( QRect &rect );
protected:
void paintEvent( QPaintEvent* event );
void resizeEvent( QResizeEvent* event );
void mousePressEvent( QMouseEvent* event );
void mouseMoveEvent( QMouseEvent* event );
void mouseReleaseEvent( QMouseEvent* event );
void wheelEvent( QWheelEvent* event );
void paintEvent( QPaintEvent* event ) override;
void resizeEvent( QResizeEvent* event ) override;
void mousePressEvent( QMouseEvent* event ) override;
void mouseMoveEvent( QMouseEvent* event ) override;
void mouseReleaseEvent( QMouseEvent* event ) override;
void wheelEvent( QWheelEvent* event ) override;
void updateSize();
void updateOffset();
@@ -150,33 +146,36 @@ private:
QPoint viewToWindow( const QPoint& pt ) const;
QRect viewToWindow( const QRect& rc ) const;
CalypFrame* m_pcCurrFrame;
std::shared_ptr<CalypFrame> m_currFrame;
QImage m_image;
std::shared_ptr<CalypFrame> m_nextFrame;
std::optional<std::size_t> m_filterSingleChannel;
ClpPel m_uiPixelHalfScale;
Tool m_eTool;
bool m_bGridVisible;
Tool m_eTool{ NavigationTool };
bool m_bGridVisible{ false };
QTimer m_zoomWinTimer;
double m_dZoomWinRatio;
double m_dZoomFactor;
double m_dZoomFactor{ 1.0 };
QPixmap m_pixmap;
// QPixmap m_pixmap;
QBitmap m_mask;
QRect m_selectedArea;
QPoint m_lastPos;
QPoint m_lastWindowPos;
GridManager m_grid;
ViewMode m_mode;
ViewMode m_mode{ NormalMode };
QColor m_maskColor;
int m_xOffset;
int m_yOffset;
bool m_blockTrackEnable;
int m_xOffset{ 0 };
int m_yOffset{ 0 };
bool m_blockTrackEnable{ false };
bool m_newShape;
bool m_snapToGrid;
bool m_snapToGrid{ false };
bool m_cursorInGrid;
bool m_visibleZoomRect;
bool m_visibleZoomRect{ true };
};
#endif // __VIEWAREA_H__
+21
View File
@@ -0,0 +1,21 @@
#
# CMakeLists for Calyp lis tests using catch2
#
FETCHCONTENT_MAKEAVAILABLE(Catch2)
SET(Calyp_App_Catch2_Tests_SRCS CalypAppTests.cpp CalypResourcesTests.cpp)
ADD_DEFINITIONS(-DCALYP_TEST_DATA_DIR=\"${CALYP_TEST_DATA_DIR}\")
ADD_EXECUTABLE(CalypAppCatch2Tests ${Calyp_App_Catch2_Tests_SRCS})
TARGET_LINK_LIBRARIES(
CalypAppCatch2Tests
${PROJECT_LIBRARY}
CalypModules
${APP_LINKER_LIBS}
${QT_LINKER_LIBS}
QCustomPlotLib
Catch2::Catch2WithMain
)
CATCH_DISCOVER_TESTS(CalypAppCatch2Tests)
+26
View File
@@ -0,0 +1,26 @@
/* This file is a part of plaYUVer project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file CalypLibTests.cpp
* \brief CalypLib main test file
*/
#define CATCH_CONFIG_MAIN
#include <catch2/catch_test_macros.hpp>
+285
View File
@@ -0,0 +1,285 @@
/* This file is a part of plaYUVer project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file CalypResourcesTests.cpp
* \brief Resouce handling tests
*/
#include <QString>
#include <catch2/catch_all.hpp>
#include <filesystem>
#include <iostream>
#include <variant>
#include "ResourceHandle.h"
#include "lib/CalypFrame.h"
#include "lib/CalypStream.h"
#include "models/VideostreamResource.h"
using namespace std::chrono_literals;
constexpr int kFrameRate{ 30 };
constexpr auto kStreamType = CalypStream::Type::Input;
auto getFileTestFilename( const char* test_sequence ) -> std::string
{
return std::string( CALYP_TEST_DATA_DIR ) + std::string( "/" ) + std::string( test_sequence );
}
TEST_CASE( "Can construct and destruct a resource", "VideoResource" )
{
auto videoResource = std::make_unique<VideostreamResource>();
CHECK( videoResource != nullptr );
}
TEST_CASE( "Can load a YUV file", "VideoResource" )
{
constexpr unsigned int kWidth{ 352 };
constexpr unsigned int kHeight{ 288 };
constexpr auto kInputFormat{ ClpPixelFormats::YUV420p };
constexpr unsigned int kBitsPel{ 8 };
constexpr auto KEndianness{ CLP_LITTLE_ENDIAN };
const auto kFilename = getFileTestFilename( "Foreman.yuv" );
REQUIRE( std::filesystem::exists( std::filesystem::path( kFilename ) ) );
auto resourceHandle = std::make_unique<ResourceHandle>();
auto videoResource = std::make_unique<VideostreamResource>();
CalypFileInfo streamInfo{ .m_cFilename = QString::fromStdString( kFilename ) };
CHECK_FALSE( videoResource->loadFile( streamInfo, false ) );
SECTION( "Now use a valid config" )
{
streamInfo = CalypFileInfo{ .m_cFilename = QString::fromStdString( kFilename ),
.m_uiWidth = kWidth,
.m_uiHeight = kHeight,
.m_iPelFormat = kInputFormat,
.m_uiBitsPelPixel = kBitsPel,
.m_iEndianness = KEndianness,
.m_uiFrameRate = kFrameRate };
REQUIRE( videoResource->loadFile( streamInfo ) );
const auto& test_stream = videoResource->getStream();
CHECK( test_stream.getWidth() == kWidth );
CHECK( test_stream.getHeight() == kHeight );
CHECK( test_stream.getBitsPerPixel() == kBitsPel );
CHECK( test_stream.getFormatName() == "YUV" );
CHECK( test_stream.getCodecName() == "Raw Video" );
CHECK( test_stream.getEndianess() == CLP_BIG_ENDIAN );
auto frame = videoResource->getCurrFrame();
CHECK( frame->getPixel( 2, 0 ) == CalypPixel{ CLP_COLOR_YUV, 201, 129, 125 } );
CHECK( frame->getPixel( 336, 278 ) == CalypPixel{ CLP_COLOR_YUV, 99, 111, 142 } );
}
}
TEST_CASE( "Can load a MKV file", "VideoResource" )
{
constexpr unsigned int kWidth{ 352 };
constexpr unsigned int kHeight{ 288 };
constexpr unsigned int kBitsPel{ 8 };
const auto kFilename = getFileTestFilename( "Foreman.mkv" );
REQUIRE( std::filesystem::exists( std::filesystem::path( kFilename ) ) );
auto resourceHandle = std::make_unique<ResourceHandle>();
auto videoResource = std::make_unique<VideostreamResource>( nullptr );
CalypFileInfo streamInfo{ .m_cFilename = QString::fromStdString( kFilename ) };
REQUIRE( videoResource->loadFile( streamInfo ) );
const auto& test_stream = videoResource->getStream();
CHECK( test_stream.getWidth() == kWidth );
CHECK( test_stream.getHeight() == kHeight );
CHECK( test_stream.getBitsPerPixel() == kBitsPel );
CHECK( test_stream.getFormatName() == "MKV" );
CHECK( test_stream.getCodecName() == "h264" );
CHECK( test_stream.getEndianess() == CLP_BIG_ENDIAN );
auto frame = videoResource->getCurrFrame();
CHECK( frame->getPixel( 311, 255 ) == CalypPixel{ CLP_COLOR_YUV, 83, 120, 132 } );
}
TEST_CASE( "Can load a PNG file", "VideoResource" )
{
constexpr unsigned int kWidth{ 352 };
constexpr unsigned int kHeight{ 288 };
constexpr unsigned int kBitsPel{ 8 };
const auto kFilename = getFileTestFilename( "Foreman.png" );
REQUIRE( std::filesystem::exists( std::filesystem::path( kFilename ) ) );
auto resourceHandle = std::make_unique<ResourceHandle>();
auto videoResource = std::make_unique<VideostreamResource>( nullptr );
CalypFileInfo streamInfo{ .m_cFilename = QString::fromStdString( kFilename ) };
REQUIRE( videoResource->loadFile( streamInfo ) );
const auto& test_stream = videoResource->getStream();
CHECK( test_stream.getWidth() == kWidth );
CHECK( test_stream.getHeight() == kHeight );
CHECK( test_stream.getBitsPerPixel() == kBitsPel );
CHECK( test_stream.getFormatName() == "PNG" );
CHECK( test_stream.getCodecName() == "png" );
CHECK( test_stream.getEndianess() == CLP_BIG_ENDIAN );
auto frame = videoResource->getCurrFrame();
CHECK( frame->getPixel( 292, 263 ) == CalypPixel{ CLP_COLOR_RGB, 92, 83, 54 } );
}
TEST_CASE( "Resource handle can store a video resource", "VideoResource" )
{
constexpr unsigned int kWidth{ 352 };
constexpr unsigned int kHeight{ 288 };
constexpr auto kInputFormat{ ClpPixelFormats::YUV420p };
constexpr unsigned int kBitsPel{ 8 };
constexpr auto KEndianness{ CLP_LITTLE_ENDIAN };
const auto kFilename = getFileTestFilename( "Foreman.yuv" );
REQUIRE( std::filesystem::exists( std::filesystem::path( kFilename ) ) );
auto resourceHandle = std::make_unique<ResourceHandle>();
CalypFileInfo streamInfo{ .m_cFilename = QString::fromStdString( kFilename ),
.m_uiWidth = kWidth,
.m_uiHeight = kHeight,
.m_iPelFormat = kInputFormat,
.m_uiBitsPelPixel = kBitsPel,
.m_iEndianness = KEndianness,
.m_uiFrameRate = kFrameRate };
{
auto videoResource = std::make_unique<VideostreamResource>( nullptr );
REQUIRE( videoResource != nullptr );
CHECK( videoResource->loadFile( streamInfo ) );
CHECK( resourceHandle->appendResource( std::move( videoResource ) ) == 0 );
}
auto videoResource = std::make_unique<VideostreamResource>( nullptr );
REQUIRE( videoResource != nullptr );
CHECK( videoResource->loadFile( streamInfo ) );
auto resource_id = resourceHandle->appendResource( std::move( videoResource ) );
CHECK( resource_id == 1 );
SECTION( "Can start and stop resource" )
{
resourceHandle->startResourceWorker( resource_id );
std::this_thread::sleep_for( 20ms );
resourceHandle->stopResourceWorker( resource_id );
CHECK( true );
}
SECTION( "Can start without stopping (RAII will clear resource)" )
{
resourceHandle->startResourceWorker( resource_id );
CHECK( true );
}
resourceHandle->removeResource( resource_id );
}
TEST_CASE( "Resource handle can play a video resource", "VideoResource" )
{
constexpr unsigned int kWidth{ 352 };
constexpr unsigned int kHeight{ 288 };
constexpr auto kInputFormat{ ClpPixelFormats::YUV420p };
constexpr unsigned int kBitsPel{ 8 };
constexpr auto KEndianness{ CLP_LITTLE_ENDIAN };
const auto kFilename = getFileTestFilename( "Foreman.yuv" );
REQUIRE( std::filesystem::exists( std::filesystem::path( kFilename ) ) );
auto resourceHandle = std::make_unique<ResourceHandle>();
CalypFileInfo streamInfo{ .m_cFilename = QString::fromStdString( kFilename ),
.m_uiWidth = kWidth,
.m_uiHeight = kHeight,
.m_iPelFormat = kInputFormat,
.m_uiBitsPelPixel = kBitsPel,
.m_iEndianness = KEndianness,
.m_uiFrameRate = kFrameRate };
auto videoResource = std::make_unique<VideostreamResource>( nullptr );
REQUIRE( videoResource != nullptr );
CHECK( videoResource->loadFile( streamInfo ) );
auto frame = videoResource->getCurrFrame();
CHECK( frame->getPixel( 2, 0 ) == CalypPixel{ CLP_COLOR_YUV, 201, 129, 125 } );
CHECK( frame->getPixel( 336, 278 ) == CalypPixel{ CLP_COLOR_YUV, 99, 111, 142 } );
auto resource_id = resourceHandle->appendResource( std::move( videoResource ) );
resourceHandle->executeResourceAction<VideostreamResource>( resource_id, []( auto* resource ) {
resource->play();
return true;
} );
resourceHandle->startResourceWorker( resource_id );
resourceHandle->executeResourceAction<VideostreamResource>( resource_id, [&frame]( auto* resource ) {
resource->playEvent();
frame = resource->getCurrFrame();
return true;
} );
CHECK( frame->getPixel( 298, 237 ) == CalypPixel{ CLP_COLOR_YUV, 82, 115, 134 } );
resourceHandle->executeResourceAction<VideostreamResource>( resource_id, [&frame]( auto* resource ) {
resource->playEvent();
frame = resource->getCurrFrame();
return true;
} );
CHECK_FALSE( frame->getPixel( 298, 237 ) == CalypPixel{ CLP_COLOR_YUV, 82, 115, 134 } );
SECTION( "Can Stop" )
{
resourceHandle->executeResourceAction<VideostreamResource>( resource_id, [&frame]( auto* resource ) {
resource->playEvent();
frame = resource->getCurrFrame();
return true;
} );
resourceHandle->executeResourceAction<VideostreamResource>( resource_id, [&frame]( auto* resource ) {
resource->stop();
frame = resource->getCurrFrame();
return true;
} );
CHECK( frame->getPixel( 2, 0 ) == CalypPixel{ CLP_COLOR_YUV, 201, 129, 125 } );
CHECK( frame->getPixel( 336, 278 ) == CalypPixel{ CLP_COLOR_YUV, 99, 111, 142 } );
}
resourceHandle->stopResourceWorker( resource_id );
}
+13 -6
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
* Joao Santos (joaompssantos@gmail.com)
*
@@ -27,14 +27,14 @@
#include "AboutDialog.h"
#include "config.h"
#include <QApplication>
#include <QDialogButtonBox>
#include <QLabel>
#include <QTextEdit>
#include <QVBoxLayout>
#include "config.h"
#define TAB_FROM_SPACES "&nbsp;&nbsp;&nbsp;"
AboutDialog::AboutDialog( QWidget* parent )
@@ -49,7 +49,7 @@ AboutDialog::AboutDialog( QWidget* parent )
.arg( QApplication::applicationVersion() ) );
label->setWordWrap( false );
QString featuresList = QStringLiteral( "<p><h3><b>Features:</b></h3><ul>" );
QString featuresList = QStringLiteral( "<p><h4><b>Features:</b></h4><ul>" );
#ifdef USE_QTDBUS
featuresList.append( QStringLiteral( "<li>Support for Qt DBus messages" ) );
@@ -63,14 +63,21 @@ AboutDialog::AboutDialog( QWidget* parent )
featuresList.append( QStringLiteral( "</ul></p>" ) );
QLabel* labelFeatures = new QLabel( featuresList );
QLabel* labelCopyright = new QLabel( QStringLiteral( "Copyright © 2014–2018 Joao Carreira and Luis Lucas" ) );
QString thanksList = QStringLiteral( "<p><h4><b>Thanks to:</b></h4><ul>" );
thanksList.append( QStringLiteral( "<li>Joao Santos" ) );
thanksList.append( QStringLiteral( "<li>Jose Filipe" ) );
thanksList.append( QStringLiteral( "</ul></p>" ) );
QLabel* labelContributors = new QLabel( thanksList );
QLabel* labelCopyright = new QLabel( QStringLiteral( "Copyright 2014–2021 Joao Carreira and Luis Lucas" ) );
QWidget* topWidget = new QWidget;
QVBoxLayout* topLayout = new QVBoxLayout;
topLayout->addWidget( pixmapLabel, 0, Qt::AlignHCenter );
topLayout->addWidget( label );
topLayout->addWidget( labelFeatures );
topLayout->addWidget( labelCopyright );
topLayout->addWidget( labelFeatures );
topLayout->addWidget( labelContributors );
topWidget->setLayout( topLayout );
// QTextEdit *textEdit = new QTextEdit(tr("<p>This program is free "
+1 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
+46 -44
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,8 +24,6 @@
#include "ConfigureFormatDialog.h"
#include "lib/CalypFrame.h"
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
@@ -39,6 +37,8 @@
#include <QString>
#include <QWidget>
#include "lib/CalypFrame.h"
#define MAX_SUPPORTED_RESOLUTION 99999
QDataStream& operator<<( QDataStream& out, const CalypStandardResolutionVector& array )
@@ -73,8 +73,7 @@ QDataStream& operator>>( QDataStream& in, CalypStandardResolutionVector& array )
class AddCustomFormat : public QDialog
{
public:
AddCustomFormat( QWidget* parent = NULL )
: QDialog( parent, Qt::Dialog | Qt::WindowTitleHint )
AddCustomFormat( QWidget* parent = NULL ) : QDialog( parent, Qt::Dialog | Qt::WindowTitleHint )
{
setWindowModality( Qt::ApplicationModal );
setWindowTitle( "Add custom resolution" );
@@ -137,8 +136,7 @@ private:
QSpinBox* m_spinHeight;
};
ConfigureFormatDialog::ConfigureFormatDialog( QWidget* parent )
: QDialog( parent )
ConfigureFormatDialog::ConfigureFormatDialog( QWidget* parent ) : QDialog( parent )
{
QString Name;
unsigned int uiWidth, uiHeight;
@@ -175,12 +173,18 @@ ConfigureFormatDialog::ConfigureFormatDialog( QWidget* parent )
QFont titleFont, menusFont, normalFont;
#if QT_VERSION > QT_VERSION_CHECK( 6, 0, 0 )
auto fontWeight = QFont::Weight::Bold;
#else
auto fontWeight = 75;
#endif
titleFont.setPointSize( 12 );
titleFont.setBold( true );
titleFont.setWeight( 75 );
titleFont.setWeight( fontWeight );
menusFont.setBold( true );
titleFont.setWeight( 75 );
titleFont.setWeight( fontWeight );
normalFont.setBold( false );
// menusFont.setPointSize( 12 );
@@ -382,8 +386,30 @@ ConfigureFormatDialog::ConfigureFormatDialog( QWidget* parent )
setFixedSize( MainLayout->sizeHint() );
}
int ConfigureFormatDialog::runConfigureFormatDialog( const QString& Filename, unsigned int& rWidth, unsigned int& rHeight,
int& rInputFormat, unsigned int& rBits, int& rEndianess, unsigned int& rFrameRate )
auto findPelFormatColorSpace( ClpPixelFormats rInputFormat ) -> std::pair<int, std::int64_t>
{
if( rInputFormat != ClpPixelFormats::Invalid )
{
auto pelFmtName = CalypFrame::pixelFormatName( rInputFormat );
for( unsigned int j = 0; j < CalypFrame::supportedColorSpacesListNames().size(); j++ )
{
const auto& formats_list = CalypFrame::supportedPixelFormatListNames( j );
for( const auto& [key, name] : formats_list )
{
if( pelFmtName == name )
{
return std::make_pair( j, static_cast<int>( key ) );
}
}
}
}
return std::make_pair( 0, 0 );
}
auto ConfigureFormatDialog::runConfigureFormatDialog( const QString& Filename, unsigned int& rWidth,
unsigned int& rHeight, ClpPixelFormats& rInputFormat,
unsigned int& rBits, int& rEndianess,
unsigned int& rFrameRate ) -> QDialog::DialogCode
{
// Set default values
// setWindowTitle( "Configure resolution for " + Filename );
@@ -391,24 +417,8 @@ int ConfigureFormatDialog::runConfigureFormatDialog( const QString& Filename, un
m_spinBoxWidth->setValue( rWidth );
m_spinBoxheight->setValue( rHeight );
int colorSpace = 0;
int sampling = 0;
if( rInputFormat >= 0 )
{
ClpString pelFmtName = CalypFrame::supportedPixelFormatListNames()[rInputFormat];
for( unsigned int j = 0; j < CalypFrame::supportedColorSpacesListNames().size(); j++ )
{
for( unsigned int i = 0; i < CalypFrame::supportedPixelFormatListNames( j ).size(); i++ )
{
if( pelFmtName == CalypFrame::supportedPixelFormatListNames( j )[i] )
{
colorSpace = j;
sampling = i;
break;
}
}
}
}
auto [colorSpace, sampling] = findPelFormatColorSpace( rInputFormat );
m_comboBoxColorSpace->setCurrentIndex( colorSpace );
m_comboBoxPixelFormat->setCurrentIndex( sampling );
m_spinBoxBits->setValue( rBits );
@@ -441,16 +451,8 @@ int ConfigureFormatDialog::runConfigureFormatDialog( const QString& Filename, un
rWidth = m_spinBoxWidth->value();
rHeight = m_spinBoxheight->value();
colorSpace = m_comboBoxColorSpace->currentIndex();
sampling = m_comboBoxPixelFormat->currentIndex();
ClpString pelFmtName = CalypFrame::supportedPixelFormatListNames( colorSpace )[sampling];
for( unsigned int i = 0; i < CalypFrame::supportedPixelFormatListNames().size(); i++ )
{
if( pelFmtName == CalypFrame::supportedPixelFormatListNames()[i] )
{
rInputFormat = i;
break;
}
}
sampling = m_comboBoxPixelFormat->currentData().toInt();
rInputFormat = static_cast<ClpPixelFormats>( sampling );
rBits = m_spinBoxBits->value();
rEndianess = m_comboBoxEndianness->currentIndex();
rFrameRate = m_spinBoxFrameRate->value();
@@ -508,13 +510,13 @@ void ConfigureFormatDialog::slotResolutionChange()
void ConfigureFormatDialog::slotColorSpaceChange( int idx )
{
if( idx == -1 )
return;
if( idx == -1 ) return;
m_comboBoxPixelFormat->clear();
for( unsigned int i = 0; i < CalypFrame::supportedPixelFormatListNames( idx ).size(); i++ )
const auto& formats_list = CalypFrame::supportedPixelFormatListNames( idx );
for( const auto& [key, name] : formats_list )
{
m_comboBoxPixelFormat->insertItem( i, CalypFrame::supportedPixelFormatListNames( idx )[i].c_str() );
m_comboBoxPixelFormat->addItem( QString::fromStdString( std::string( name ) ), static_cast<int>( key ) );
}
m_comboBoxPixelFormat->setCurrentIndex( 0 );
}
@@ -542,6 +544,6 @@ void ConfigureFormatDialog::writeSettings()
{
QSettings appSettings;
QVariant var;
var.setValue<CalypStandardResolutionVector>( aRCustomFileFormats );
var.setValue( aRCustomFileFormats );
appSettings.setValue( "ConfigureFormatDialog/CustomFormats", var );
}
+5 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,7 @@ class QSpinBox;
class QString;
class QWidget;
typedef QVector<CalypStandardResolution> CalypStandardResolutionVector;
using CalypStandardResolutionVector = QVector<CalypStandardResolution>;
QDataStream& operator<<( QDataStream& out, const CalypStandardResolutionVector& array );
QDataStream& operator>>( QDataStream& in, CalypStandardResolutionVector& array );
@@ -51,8 +51,9 @@ class ConfigureFormatDialog : public QDialog
public:
ConfigureFormatDialog( QWidget* parent = 0 );
int runConfigureFormatDialog( const QString& Filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBits,
int& rEndianess, unsigned int& rFrameRate );
auto runConfigureFormatDialog( const QString& Filename, unsigned int& rWidth, unsigned int& rHeight,
ClpPixelFormats& rInputFormat, unsigned int& rBits, int& rEndianess,
unsigned int& rFrameRate ) -> QDialog::DialogCode;
void readSettings();
void writeSettings();
+22 -25
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,8 +24,6 @@
#include "ModulesHandleOptDialog.h"
#include "lib/CalypOptions.h"
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
@@ -34,20 +32,21 @@
#include <QVector>
#include <QWidget>
#include "lib/CalypOptions.h"
class QLineEdit;
class OpionConfiguration : public QWidget
class OptionConfiguration : public QWidget
{
public:
OpionConfiguration( OptionBase* option )
OptionConfiguration( CalypOptions::OptionBase* option )
: m_cName{ option->opt_string }
{
m_pcChecked = NULL;
m_cName = option->opt_string;
m_pcDescription = new QLabel;
auto* pcDescription = new QLabel;
QString desc = QString::fromStdString( option->opt_desc );
m_pcDescription->setText( desc );
pcDescription->setText( desc );
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget( m_pcDescription, 0, Qt::AlignLeft );
layout->addWidget( pcDescription, 0, Qt::AlignLeft );
if( !option->isBinary() )
{
m_pcValue = new QLineEdit;
@@ -64,7 +63,7 @@ public:
layout->setContentsMargins( 1, 1, 1, 1 );
setLayout( layout );
}
const QString getValue() const
auto getValue() const -> QString
{
if( m_pcChecked )
{
@@ -72,13 +71,12 @@ public:
}
return m_pcValue->text();
}
const ClpString& getName() { return m_cName; }
auto getName() const -> std::string { return m_cName; }
private:
QLineEdit* m_pcValue;
QCheckBox* m_pcChecked;
QLabel* m_pcDescription;
ClpString m_cName;
QLineEdit* m_pcValue{ nullptr };
QCheckBox* m_pcChecked{ nullptr };
std::string m_cName;
};
ModulesHandleOptDialog::ModulesHandleOptDialog( QWidget* parent, CalypAppModuleIf* pcCurrModuleIf )
@@ -87,13 +85,12 @@ ModulesHandleOptDialog::ModulesHandleOptDialog( QWidget* parent, CalypAppModuleI
resize( 400, 10 );
setWindowTitle( "Select module parameters" );
const CalypOptions::OptionsList& moduleOptions = m_pcCurrModuleIf->m_pcModule->m_cModuleOptions.getOptionList();
auto& moduleOptions = m_pcCurrModuleIf->m_pcModule->m_cModuleOptions.getOptionList();
QVBoxLayout* optionsLayout = new QVBoxLayout;
OpionConfiguration* pcOption;
for( CalypOptions::OptionsList::const_iterator it = moduleOptions.begin(); it != moduleOptions.end(); ++it )
for( auto& option : moduleOptions )
{
pcOption = new OpionConfiguration( ( *it )->opt );
auto pcOption = new OptionConfiguration( option->base_opt.get() );
m_apcOptionList.append( pcOption );
optionsLayout->addWidget( pcOption );
}
@@ -121,17 +118,17 @@ int ModulesHandleOptDialog::runConfiguration()
return QDialog::Rejected;
}
std::vector<ClpString> argsArray;
ClpString optionString;
std::vector<std::string> argsArray;
std::string optionString;
QString valueString( "" );
for( int i = 0; i < m_apcOptionList.size(); i++ )
for( const auto& option : m_apcOptionList )
{
valueString = m_apcOptionList.at( i )->getValue();
valueString = option->getValue();
if( !valueString.isEmpty() )
{
optionString.append( "--" );
optionString.append( m_apcOptionList.at( i )->getName() );
optionString.append( option->getName() );
if( !( valueString == "true" ) )
{
optionString.append( "=" );
+6 -6
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,14 +25,14 @@
#ifndef __MODULEHANDLEOPTDIALOG_H__
#define __MODULEHANDLEOPTDIALOG_H__
#include <QDialog>
#include <QVector>
#include "CalypAppModuleIf.h"
#include "CommonDefs.h"
#include "config.h"
#include <QDialog>
#include <QVector>
class OpionConfiguration;
class OptionConfiguration;
/**
*
@@ -47,7 +47,7 @@ public:
private:
CalypAppModuleIf* m_pcCurrModuleIf;
QVector<OpionConfiguration*> m_apcOptionList;
QVector<OptionConfiguration*> m_apcOptionList;
};
#endif // __MODULEHANDLEOPTDIALOG_H__
+1 -2
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,6 @@
#include "ProgressBar.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QLabel>
#include <QProgressBar>
#include <QVBoxLayout>
+3 -3
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,11 +25,11 @@
#ifndef __PROGRESSBAR_H__
#define __PROGRESSBAR_H__
#include "CommonDefs.h"
#include <QDialog>
#include <QWidget>
#include "CommonDefs.h"
class QProgressBar;
class ProgressBar : public QWidget
+4 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,8 +24,6 @@
#include "SeekStreamDialog.h"
#include "lib/CalypStream.h"
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QLabel>
@@ -33,7 +31,9 @@
#include <QVector>
#include <QWidget>
SeekStreamDialog::SeekStreamDialog( CalypStream* pcCurrStream, QWidget* parent )
#include "lib/CalypStream.h"
SeekStreamDialog::SeekStreamDialog( const CalypStream* pcCurrStream, QWidget* parent )
: QDialog( parent, Qt::Dialog | Qt::WindowTitleHint ), m_iSelectedFrameNum()
{
m_iSelectedFrameNum = pcCurrStream->getCurrFrameNum();
+5 -5
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,13 +25,13 @@
#ifndef __SEEKSTREAMDIALOG_H__
#define __SEEKSTREAMDIALOG_H__
#include <QDialog>
#include <QVector>
#include "CalypAppModuleIf.h"
#include "CommonDefs.h"
#include "config.h"
#include <QDialog>
#include <QVector>
class QSpinBox;
/**
@@ -42,7 +42,7 @@ class SeekStreamDialog : public QDialog
Q_OBJECT
public:
SeekStreamDialog( CalypStream* pcCurrStream, QWidget* parent = 0 );
SeekStreamDialog( const CalypStream* pcCurrStream, QWidget* parent = 0 );
int runDialog();
private:
+4 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,12 +24,12 @@
#include "SubWindowSelectorDialog.h"
#include "SubWindowHandle.h"
#include "VideoSubWindow.h"
#include <QCheckBox>
#include <QGroupBox>
#include "SubWindowHandle.h"
#include "VideoSubWindow.h"
SubWindowSelectorDialog::SubWindowSelectorDialog( QWidget* parent, SubWindowHandle* windowManager,
unsigned int uiCategory, int minWindowsSelected, int maxWindowsSelected )
: QDialog( parent )
+4 -5
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,13 +25,12 @@
#ifndef __DIALOGSUBWINDOWSELECTOR_H__
#define __DIALOGSUBWINDOWSELECTOR_H__
#include "CommonDefs.h"
#include "config.h"
#include <QVector>
#include <QtCore>
#include <QtWidgets>
#include <QVector>
#include "CommonDefs.h"
#include "config.h"
class QPixmap;
class QColor;
+59 -37
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -28,12 +28,12 @@
#include <QtGui>
#include <cmath>
#include "lib/CalypStream.h"
FramePropertiesDock::FramePropertiesDock( QWidget* parent, bool* pbMainPlaySwitch )
: QWidget( parent ), m_pbIsPlaying( pbMainPlaySwitch )
: QWidget( parent ), m_bIsPlaying( false ), m_bHasFrame( false )
{
// -------------- Variables definition --------------
m_pcFrame = NULL;
m_pcSelectedFrame = NULL;
m_iLastFrameType = -1;
// Histogram area -----------------------------------------------------
@@ -204,6 +204,11 @@ FramePropertiesDock::FramePropertiesDock( QWidget* parent, bool* pbMainPlaySwitc
labelMedianValue = new QLabel;
labelMedianValue->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
QLabel* entropyLabel = new QLabel( tr( "Entropy:" ) );
entropyLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
labelEntropyValue = new QLabel;
labelEntropyValue->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
QLabel* percentileLabel = new QLabel( tr( "Percentile:" ) );
percentileLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
labelPercentileValue = new QLabel;
@@ -225,6 +230,10 @@ FramePropertiesDock::FramePropertiesDock( QWidget* parent, bool* pbMainPlaySwitc
statisticsLayout->addWidget( labelStdDevValue, gridRow++, 1 );
statisticsLayout->addWidget( medianLabel, gridRow, 0 );
statisticsLayout->addWidget( labelMedianValue, gridRow++, 1 );
statisticsLayout->addWidget( percentileLabel, gridRow, 0 );
statisticsLayout->addWidget( labelPercentileValue, gridRow++, 1 );
statisticsLayout->addWidget( entropyLabel, gridRow, 0 );
statisticsLayout->addWidget( labelEntropyValue, gridRow++, 1 );
QGroupBox* statisticsGroup = new QGroupBox( tr( "Statistics" ) );
statisticsGroup->setLayout( statisticsLayout );
@@ -271,16 +280,15 @@ QSize FramePropertiesDock::sizeHint() const
void FramePropertiesDock::reset()
{
m_pcFrame = NULL;
m_pcFrame = nullptr;
m_pcSelectedFrame = nullptr;
m_bHasFrame = false;
m_cSelectionArea = QRect();
if( m_pcSelectedFrame )
{
delete m_pcSelectedFrame;
m_pcSelectedFrame = NULL;
}
m_iLastFrameType = -1;
labelRangeValue->clear();
labelNEBinsValue->clear();
labelMeanValue->clear();
labelPixelsValue->clear();
@@ -288,6 +296,7 @@ void FramePropertiesDock::reset()
labelCountValue->clear();
labelMedianValue->clear();
labelPercentileValue->clear();
labelEntropyValue->clear();
// Remove the histogram data from memory
histogramWidget->reset();
@@ -295,7 +304,7 @@ void FramePropertiesDock::reset()
setEnabled( false );
}
void FramePropertiesDock::setFrame( CalypFrame* pcFrame )
void FramePropertiesDock::setFrame( std::shared_ptr<CalypFrame> pcFrame, bool isPlaying )
{
int colorSpace = pcFrame->getColorSpace();
if( m_iLastFrameType != colorSpace )
@@ -357,35 +366,40 @@ void FramePropertiesDock::setFrame( CalypFrame* pcFrame )
}
}
setEnabled( true );
if( m_pcFrame || !( *m_pbIsPlaying ) )
m_bIsPlaying = isPlaying;
if( !m_bIsPlaying )
{
m_pcFrame = pcFrame;
updateDataHistogram();
if( pcFrame )
{
m_bHasFrame = true;
m_pcFrame = pcFrame;
}
else
{
m_bHasFrame = false;
}
}
updateDataHistogram();
}
void FramePropertiesDock::setSelection( const QRect& selectionArea )
{
if( m_pcFrame )
if( m_bHasFrame )
{
bool bSelectionChanged = !( selectionArea.size() == m_cSelectionArea.size() );
m_cSelectionArea = selectionArea;
if( selectionArea.isValid() )
{
m_cSelectionArea = selectionArea;
histogramWidget->stopHistogramComputation();
/*
* Allocate a new image for the selection
* or just copy information
* Crop selection from frame
*/
if( bSelectionChanged )
{
if( m_pcSelectedFrame )
{
delete m_pcSelectedFrame;
}
m_pcSelectedFrame = new CalypFrame( m_pcFrame, selectionArea.x(), selectionArea.y(), selectionArea.width(),
selectionArea.height() );
m_pcSelectedFrame = std::make_shared<CalypFrame>( *m_pcFrame, selectionArea.x(),
selectionArea.y(),
selectionArea.width(),
selectionArea.height() );
}
updateDataHistogram();
selectionImageButton->click();
@@ -402,13 +416,21 @@ void FramePropertiesDock::setSelection( const QRect& selectionArea )
void FramePropertiesDock::updateDataHistogram()
{
if( m_pcFrame && isVisible() )
if( m_bHasFrame && isVisible() )
{
if( !*m_pbIsPlaying )
if( m_bIsPlaying )
{
if( m_pcSelectedFrame )
histogramWidget->setLoadingSkipped();
}
else
{
if( m_cSelectionArea.isValid() )
{
m_pcSelectedFrame->copyFrom( m_pcFrame, m_cSelectionArea.x(), m_cSelectionArea.y() );
m_pcSelectedFrame = std::make_shared<CalypFrame>( *m_pcFrame,
m_cSelectionArea.x(),
m_cSelectionArea.y(),
m_cSelectionArea.width(),
m_cSelectionArea.height() );
fullImageButton->show();
selectionImageButton->show();
}
@@ -417,12 +439,9 @@ void FramePropertiesDock::updateDataHistogram()
fullImageButton->hide();
selectionImageButton->hide();
}
histogramWidget->updateData( m_pcFrame, m_pcSelectedFrame );
}
else
{
histogramWidget->setLoadingSkipped();
histogramWidget->updateData( m_pcFrame, m_cSelectionArea.isValid() ? m_pcSelectedFrame : nullptr );
}
histogramWidget->update();
}
else
@@ -443,7 +462,7 @@ void FramePropertiesDock::updateStatistiques()
if( channel == CalypFrame::HIST_ALL_CHANNELS )
channel = colorsCB->itemData( colorsCB->currentIndex() ).toInt();
CalypFrame* frame;
std::shared_ptr<CalypFrame> frame;
if( histogramWidget->m_renderingType == HistogramWidget::FullImageHistogram )
frame = histogramWidget->m_fullImage;
@@ -472,7 +491,10 @@ void FramePropertiesDock::updateStatistiques()
labelCountValue->setText( value.setNum( (float)counts, 'f', 0 ) );
double median = frame->getMedian( channel, min, max );
labelMedianValue->setText( value.setNum( median, 'f', 1 ) );
labelMedianValue->setText( value.setNum( median, 'f', 0 ) );
double entropy = frame->getEntropy( channel, min, max );
labelEntropyValue->setText( value.setNum( entropy, 'f', 2 ) );
double percentile = ( pixels > 0 ? ( 100.0 * counts / pixels ) : 0.0 );
labelPercentileValue->setText( value.setNum( percentile, 'f', 1 ) );
@@ -513,7 +535,7 @@ void FramePropertiesDock::slotRefreshOptions( int range )
void FramePropertiesDock::slotHistogramComputationFailed()
{
m_pcFrame = NULL;
m_bHasFrame = false;
}
void FramePropertiesDock::slotChannelChanged( int index )
+10 -8
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,13 +25,14 @@
#ifndef __FRAMEPROPERTIESDOCK_H__
#define __FRAMEPROPERTIESDOCK_H__
#include <QtWidgets>
#include "CommonDefs.h"
#include "HistogramWidget.h"
#include "config.h"
#include "lib/CalypFrame.h"
#include "lib/CalypStream.h"
#include <QtWidgets>
class CalypStream;
class FramePropertiesDock : public QWidget
{
@@ -42,17 +43,17 @@ public:
QSize sizeHint() const;
void setFrame( CalypFrame* m_pcFrame );
void setFrame( std::shared_ptr<CalypFrame> m_pcFrame, bool isPlaying );
void setSelection( const QRect& selectionArea );
void reset();
void stopHistogram();
private:
CalypFrame* m_pcFrame;
CalypFrame* m_pcSelectedFrame;
std::shared_ptr<CalypFrame> m_pcFrame;
std::shared_ptr<CalypFrame> m_pcSelectedFrame;
int m_iLastFrameType;
bool* m_pbIsPlaying;
bool m_bIsPlaying;
bool m_bHasFrame;
QComboBox* channelCB;
QComboBox* colorsCB;
@@ -76,6 +77,7 @@ private:
QLabel* labelMeanValue;
QLabel* labelStdDevValue;
QLabel* labelMedianValue;
QLabel* labelEntropyValue;
QLabel* labelPercentileValue;
QLabel* colorsLabel;
+8 -10
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,14 +24,14 @@
#include "ModuleHandleDock.h"
#include "CalypAppModuleIf.h"
#include "ModulesHandle.h"
#include <QGridLayout>
#include <QLabel>
#include <QString>
#include <QtGui>
#include "CalypAppModuleIf.h"
#include "ModulesHandle.h"
ModuleHandleDock::ModuleHandleDock( QWidget* parent, CalypAppModuleIf* moduleIf )
: QWidget( parent ), m_pcCurrModuleIf( moduleIf )
{
@@ -58,9 +58,9 @@ ModuleHandleDock::ModuleHandleDock( QWidget* parent, CalypAppModuleIf* moduleIf
setEnabled( true );
}
ModuleHandleDock::~ModuleHandleDock() {}
ModuleHandleDock::~ModuleHandleDock() = default;
void ModuleHandleDock::setModulueReturnValue( double value )
void ModuleHandleDock::setModuleReturnValue( double value )
{
labelModulueReturnValue->clear();
QString strValue = QString( "%1" ).arg( value );
@@ -69,11 +69,9 @@ void ModuleHandleDock::setModulueReturnValue( double value )
void ModuleHandleDock::visibilityChangedSlot( bool visiblity )
{
if( !visiblity && m_pcCurrModuleIf )
if( !visiblity )
{
CalypAppModuleIf* pcCurrentModule = m_pcCurrModuleIf;
m_pcCurrModuleIf = NULL;
ModulesHandle::destroyModuleIf( pcCurrentModule );
m_pcCurrModuleIf->disable();
}
}
+5 -5
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,12 +25,12 @@
#ifndef __MODULEHANDLEDOCK_H__
#define __MODULEHANDLEDOCK_H__
#include "CommonDefs.h"
#include "config.h"
#include <QSize>
#include <QWidget>
#include "CommonDefs.h"
#include "config.h"
class QLabel;
class CalypAppModuleIf;
@@ -42,7 +42,7 @@ public:
ModuleHandleDock( QWidget* parent, CalypAppModuleIf* moduleIf );
~ModuleHandleDock();
void setModulueReturnValue( double value );
void setModuleReturnValue( double value );
QSize sizeHint() const;
+3 -3
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,11 +24,11 @@
#include "QualityMeasurementSidebar.h"
#include <QtGui>
#include "SubWindowHandle.h"
#include "VideoSubWindow.h"
#include <QtGui>
QualityMeasurementSidebar::QualityMeasurementSidebar( QWidget* parent, SubWindowHandle* windowManager )
: QWidget( parent ), m_pcMainWindowManager( windowManager ), m_pcCurrentVideoSubWindow( NULL )
{
+3 -3
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,14 +25,14 @@
#ifndef __QUALITYMEASUREMENTSIDEBAR_H__
#define __QUALITYMEASUREMENTSIDEBAR_H__
#include <QtWidgets>
#include "CommonDefs.h"
#include "HistogramWidget.h"
#include "config.h"
#include "lib/CalypFrame.h"
#include "lib/CalypStream.h"
#include <QtWidgets>
class SubWindowHandle;
class VideoSubWindow;
+4 -4
View File
@@ -1,5 +1,5 @@
###
### CMakeLists for calyp external components
###
#
# CMakeLists for calyp external components
#
ADD_SUBDIRECTORY( qcustomplot )
ADD_SUBDIRECTORY(qcustomplot)
+21 -16
View File
@@ -1,20 +1,25 @@
###
### CMakeLists for qcustomplot
###
#
# CMakeLists for qcustomplot
#
FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport )
IF(${USE_QT6})
FIND_PACKAGE(Qt6 QUIET COMPONENTS Core Gui Widgets PrintSupport)
IF (NOT Qt6_FOUND)
FIND_PACKAGE(Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport)
ENDIF()
ELSE()
FIND_PACKAGE(Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport)
ENDIF()
set(qcustomplot_SRCS
qcustomplot.cpp
qcustomplot.h
)
ADD_LIBRARY( QCustomPlotLib STATIC ${qcustomplot_SRCS} )
TARGET_LINK_LIBRARIES( QCustomPlotLib
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::PrintSupport
)
SET(qcustomplot_SRCS qcustomplot.cpp qcustomplot.h)
TARGET_INCLUDE_DIRECTORIES(QCustomPlotLib PUBLIC . )
SET(CMAKE_AUTOMOC ON)
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-deprecated-enum-enum-conversion")
ENDIF()
ADD_LIBRARY(QCustomPlotLib STATIC ${qcustomplot_SRCS})
TARGET_LINK_LIBRARIES(QCustomPlotLib Qt::Core Qt::Gui Qt::Widgets Qt::PrintSupport)
TARGET_INCLUDE_DIRECTORIES(QCustomPlotLib PUBLIC .)
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Vendored Regular → Executable
+52
View File
@@ -1,3 +1,55 @@
#### Version 2.1.1 released on 06.11.22 ####
Added features:
- Qt6.4 Compatibility
Bugfixes:
- dynamically changing device pixel ratios (e.g. when moving between different DPI screens) is handled properly
- bugfix Colormap autoscaling: recalculateDataBounds() if (0, 0) data point is NaN.
- minor bugfix in getMantissa for certain values due to rounding errors
- Graphs with line style lsImpulse properly ignore NaN data points
- fixed issue where QCP wasn't greyed out together with the rest of the UI on embedded systems when a modal dialog is shown
(QCustomPlot no longer has the Qt::WA_OpaquePaintEvent attribute enabled by default)
Other:
- in QCPAxisPainterPrivate::getTickLabelData, don't use fixed 'e', but locale aware character of parent plot locale
- Axis rescaling now ignores +/- Inf in data values
- slight performance improvements of QCPColorMap colorization and fills.
#### Version 2.1.0 released on 29.03.21 ####
Added features:
- Compatibility up to Qt 6.0
- Tech Preview: Radial Plots (see setupPolarPlotDemo in examples project)
- QCPAxisTickerDateTime can now be configured with a QTimeZone for adjusting the label display to arbitrary time zones
- QCPColorGradient (and thus also QCPColorMap) now has explicit configurable NaN handling (see QCPColorGradient::setNanHandling)
- added timing/benchmarking method QCustomPlot::replotTime(bool average) which returns the milliseconds per replot
- QCustomPlot::plottableAt has an optional output parameter dataIndex, providing the index of the data point at the probed position
- QCustomPlot::plottableAt<T> template method allows limiting the search to the specified QCPAbstractPlottable subclass T
- QCustomPlot::itemAt<T> template method allows limiting the search to the specified QCPAbstractItem subclass T
- Added Interaction flag QCP::iSelectPlottablesBeyondAxisRect, allows selection of data points very close to (and beyond of) the axes
- QCPAxisTickerDateTime::dateTimeToKey(QDate &) now also takes a TimeSpec to specify the interpretation of the start-of-day
- QCPAxisTickerLog now switches to linear ticks if zoomed in beyond where logarithmic ticks are reasonable
- Added QCustomPlot::afterLayout signal, for user code that crucially depends on layout sizes/positions, right before the draw step during a replot
Bugfixes:
- Fixed bug where QCPLayer::replot wouldn't issue full replot even though invalidated buffers existed
- Fixed QCPCurve bug causing rendering artifacts when using keys/values smaller than about 1e-12 in some constellations
- Fixed getValueRange when used with explicit keyRange, now doesn't use key range expanded by one point to each side anymore
- Fixed bug of QCPAxis tick label font size change only propagating to the layout after second call to replot
- Fixed bug of QCPTextElement not respecting the configured text alignment flag (setTextFlags)
- Various documentation typos and improvements
Other:
- QCP Now requires C++11. However, Qt4.6 compatibility is maintained in the QCP 2.x release series
- QCPColorScale is now initialized with gpCold gradient preset, which prevents color maps turning black when linking them to a default-created color scale without explicitly setting a gradient
- QCPLegend::clearItems is now faster in case of many legend items (>1000)
- Modernized expressions and thereby avoided some warnings (e.g. nullptr and casts)
- Switched to foreach (Qt macro) where possible (in preparation for switch to range-based for (C++11), soonest at next major release)
- Work around Qt bug, drawing lines with pen width 1 as slow as with pen widths > 1 (polyfill instead of line algorithm, also on Normal-DPI), by using pen width 0 in such cases.
- Added QCP::Interaction flag iNone=0x000 to allow explicitly specifying no interaction (Avoids QFlags::zero, which was deprecated in Qt5.14)
- QCP is now compatible with defines QT_USE_QSTRINGBUILDER, QT_USE_FAST_CONCATENATION (Qt<4.8), QT_USE_FAST_OPERATOR_PLUS (Qt<4.8)
#### Version 2.0.1 released on 25.06.18 ####
Bugfixes:
+6383 -1068
View File
File diff suppressed because it is too large. Load diff
+1320 -219
View File
File diff suppressed because it is too large. Load diff
+14 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,10 @@
* \brief main file
*/
#include <QApplication>
#include <QMetaType>
#include <QStyleFactory>
#include "CommonDefs.h"
#include "ConfigureFormatDialog.h"
#include "MainWindow.h"
@@ -30,7 +34,7 @@
#ifdef USE_QTDBUS
#include "DBusAppAdaptor.h"
#endif
#include <QApplication>
#ifdef USE_FERVOR
#include "fvupdater.h"
#endif
@@ -42,15 +46,21 @@
int main( int argc, char* argv[] )
{
qRegisterMetaType<CalypFileInfoVector>();
qRegisterMetaTypeStreamOperators<CalypFileInfoVector>();
qRegisterMetaType<CalypStandardResolutionVector>();
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
qRegisterMetaTypeStreamOperators<CalypFileInfoVector>();
qRegisterMetaTypeStreamOperators<CalypStandardResolutionVector>();
#endif
QApplication::setStyle( "macOS" );
QApplication application( argc, argv );
QApplication::setApplicationName( QStringLiteral( "Calyp" ) );
QApplication::setApplicationVersion( QStringLiteral( CALYP_VERSION_STRING ) );
QApplication::setOrganizationName( QStringLiteral( "PixLRA" ) );
#if _WIN32
application.setStyle( QStyleFactory::create( "Fusion" ) );
#endif
#ifdef USE_QTDBUS
/**
* use dbus, if available
+52
View File
@@ -0,0 +1,52 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file CalypResource.h
* \brief Abstract calyp resource
*/
#ifndef __CALYPRESOURCE_H__
#define __CALYPRESOURCE_H__
#include <QObject>
#include "lib/CalypStream.h"
class CalypResource
{
public:
virtual ~CalypResource() = default;
virtual auto iteration() -> bool = 0;
virtual auto isReady() -> bool = 0;
virtual auto getResourceName() -> std::string = 0;
// TODO(JC) [[deprecated( "Do not directly access the resource" )]] after refactoring
virtual auto getResource() -> CalypStream* = 0;
protected:
CalypResource() = default;
CalypResource( CalypResource&& other ) noexcept = default;
CalypResource( const CalypResource& other ) = default;
auto operator=( CalypResource&& other ) noexcept -> CalypResource& = default;
auto operator=( const CalypResource& other ) -> CalypResource& = default;
};
#endif // __CALYPRESOURCE_H__
+351
View File
@@ -0,0 +1,351 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file VideostreamResource.h
* \brief Class to control video playback
*/
#include "VideostreamResource.h"
#include <qfileinfo.h>
#include <QDataStream>
#include <QElapsedTimer>
#include <QFileInfo>
#include <QRegularExpression>
#include <memory>
#include "lib/CalypFrame.h"
/**
* \brief Functions to control data stream from stream information
*/
auto operator<<( QDataStream& out, const CalypFileInfoVector& infos ) -> QDataStream&
{
out << infos.size();
for( const auto& info : infos )
{
out << info.m_cFilename << info.m_uiWidth << info.m_uiHeight << static_cast<int>( info.m_iPelFormat )
<< info.m_uiBitsPelPixel << info.m_iEndianness << info.m_uiFrameRate << info.m_uiFileSize << info.m_bForceRaw;
}
return out;
}
auto operator>>( QDataStream& in, CalypFileInfoVector& infos ) -> QDataStream&
{
auto array_size = infos.size();
in >> array_size;
for( int i = 0; i < array_size; i++ )
{
CalypFileInfo d;
int pelFormat{ 0 };
in >> d.m_cFilename;
in >> d.m_uiWidth;
in >> d.m_uiHeight;
in >> pelFormat;
in >> d.m_uiBitsPelPixel;
in >> d.m_iEndianness;
in >> d.m_uiFrameRate;
in >> d.m_uiFileSize;
in >> d.m_bForceRaw;
d.m_iPelFormat = static_cast<ClpPixelFormats>( pelFormat );
infos.append( d );
}
return in;
}
auto findCalypStreamInfo( const CalypFileInfoVector& array, const QString& filename ) -> int
{
for( int i = 0; i < array.size(); i++ )
{
if( array.at( i ).m_cFilename == filename ) return i;
}
return -1;
}
VideostreamResource::VideostreamResource( QObject* parent ) : QObject{ parent } {}
VideostreamResource::~VideostreamResource() = default;
auto VideostreamResource::iteration() -> bool
{
m_currStream.readNextFrameFillRGBBuffer();
return true;
}
auto VideostreamResource::isReady() -> bool
{
return m_currStream.hasWritingSlot();
}
bool VideostreamResource::loadFile( const CalypFileInfo& streamInfo, bool optimistic )
{
m_sStreamInfo = streamInfo;
ClpPixelFormats inputFormat = static_cast<ClpPixelFormats>( m_sStreamInfo.m_iPelFormat );
try
{
if( !m_currStream.open( streamInfo.m_cFilename.toStdString(), streamInfo.m_uiWidth, streamInfo.m_uiHeight,
inputFormat, streamInfo.m_uiBitsPelPixel, streamInfo.m_iEndianness,
streamInfo.m_uiFrameRate, streamInfo.m_bForceRaw, CalypStream::Type::Input ) )
{
return false;
}
}
catch( CalypFailure& e )
{
if( !optimistic )
{
return false;
}
throw( e );
}
m_currStream.getFormat( m_sStreamInfo.m_uiWidth, m_sStreamInfo.m_uiHeight, m_sStreamInfo.m_iPelFormat,
m_sStreamInfo.m_uiBitsPelPixel, m_sStreamInfo.m_iEndianness, m_sStreamInfo.m_uiFrameRate );
m_sStreamInfo.m_uiFileSize = QFileInfo{ streamInfo.m_cFilename }.size();
return true;
}
auto VideostreamResource::getCurrFrame() -> std::shared_ptr<CalypFrame>
{
return m_currStream.getCurrFrameAsset();
}
bool VideostreamResource::play()
{
bool isPlaying = false;
if( m_currStream.getFrameNum() > 1 )
{
isPlaying = true;
}
m_bIsPlaying = isPlaying;
return m_bIsPlaying;
}
bool VideostreamResource::playEvent()
{
bool bEndOfSeq = false;
if( m_bIsPlaying )
{
bEndOfSeq = goToNextFrame( true );
}
return bEndOfSeq;
}
void VideostreamResource::pause()
{
m_bIsPlaying = false;
triggerRefresh();
}
void VideostreamResource::seekAbsoluteEvent( unsigned int new_frame_num )
{
if( m_currStream.seekInput( new_frame_num ) ) triggerRefresh();
}
void VideostreamResource::seekRelativeEvent( bool bIsForward )
{
if( bIsForward )
{
goToNextFrame( true );
}
else
{
m_currStream.seekInputRelative( bIsForward );
triggerRefresh();
}
}
void VideostreamResource::stop()
{
m_bIsPlaying = false;
seekAbsoluteEvent( 0 );
return;
}
auto VideostreamResource::goToNextFrame( bool bThreaded ) -> bool
{
while( !m_currStream.hasNextFrame() && !m_currStream.isEof() )
{
}
bool bEndOfSeq = m_currStream.setNextFrame();
if( !bEndOfSeq )
{
triggerRefresh();
}
return bEndOfSeq;
}
void VideostreamResource::triggerRefresh() {}
auto video_resource_guess_format( const QString& filename, unsigned int& rWidth, unsigned int& rHeight,
ClpPixelFormats& rInputFormat, unsigned int& rBitsPerPixel, int& rEndianness,
unsigned int& rFrameRate ) -> bool
{
std::vector<CalypStandardResolution> stdResList = CalypStream::stdResolutionSizes();
bool bGuessed = true;
bool bGuessedByFilesize = false;
QString FilenameShort = QFileInfo( filename ).fileName();
QString fileExtension = QFileInfo( filename ).suffix();
if( filename.startsWith( "/dev/" ) )
{
return true;
}
if( !fileExtension.compare( "yuv", Qt::CaseInsensitive ) || !fileExtension.compare( "rgb", Qt::CaseInsensitive ) ||
!fileExtension.compare( "gray", Qt::CaseInsensitive ) )
{
bGuessed = false;
// Guess pixel format
const auto& formats_list = CalypFrame::supportedPixelFormatListNames();
for( const auto& [key, name] : formats_list )
{
if( FilenameShort.contains( QString::fromStdString( std::string( name ) ), Qt::CaseInsensitive ) )
{
rInputFormat = key;
break;
}
}
if( rWidth == 0 || rHeight == 0 )
{
// Guess resolution - match resolution name
int iMatch = -1;
for( unsigned int i = 0; i < stdResList.size(); i++ )
{
if( FilenameShort.contains( QString::fromStdString( stdResList[i].shortName ) ) )
{
iMatch = i;
}
}
if( iMatch >= 0 )
{
rWidth = stdResList[iMatch].uiWidth;
rHeight = stdResList[iMatch].uiHeight;
}
// Guess resolution - match %dx%d
// QRegularExpressionMatch resolutionMatch = QRegularExpression( "_\\d*x\\d*" ).match( FilenameShort );
QRegularExpressionMatch resolutionMatch = QRegularExpression( "_[0-9]+x[0-9]+" ).match( FilenameShort );
if( resolutionMatch.hasMatch() )
{
QString resolutionString = resolutionMatch.captured( resolutionMatch.lastCapturedIndex() );
if( resolutionString.startsWith( "_" ) || resolutionString.endsWith( "_" ) )
{
resolutionString.remove( "_" );
QStringList resolutionArgs = resolutionString.split( "x" );
if( resolutionArgs.size() == 2 )
{
rWidth = resolutionArgs.at( 0 ).toUInt();
rHeight = resolutionArgs.at( 1 ).toUInt();
}
}
}
}
// Guess resolution by file size
if( rWidth == 0 && rHeight == 0 )
{
FILE* pF = fopen( filename.toStdString().c_str(), "rb" );
if( pF )
{
fseek( pF, 0, SEEK_END );
unsigned long long int uiFileSize = ftell( pF );
fclose( pF );
int count = 0;
int match = -1;
for( unsigned int i = 0; i < stdResList.size(); i++ )
{
auto frame_bytes =
CalypFrame::getBytesPerFrame( stdResList[i].uiWidth, stdResList[i].uiHeight, rInputFormat, 8 );
auto module = uiFileSize % frame_bytes;
if( module == 0 )
{
match = i;
count++;
}
}
if( count == 1 )
{
rWidth = stdResList[match].uiWidth;
rHeight = stdResList[match].uiHeight;
bGuessedByFilesize = true;
}
}
}
// [.|_]
// Guess bits per pixel - match %dbpp
QRegularExpressionMatch BppMatch = QRegularExpression( "_[0-9]+bpp" ).match( FilenameShort );
if( BppMatch.hasMatch() )
{
QString matchString = BppMatch.captured( BppMatch.lastCapturedIndex() );
matchString.remove( "_" );
matchString.remove( "bpp" );
rBitsPerPixel = matchString.toUInt();
if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) )
{
rBitsPerPixel = -1;
}
}
QRegularExpressionMatch BppOnlyMatch = QRegularExpression( "_[0-9]+b" ).match( FilenameShort );
if( BppOnlyMatch.hasMatch() )
{
QString matchString = BppOnlyMatch.captured( BppOnlyMatch.lastCapturedIndex() );
matchString.remove( "_" );
matchString.remove( "b" );
rBitsPerPixel = matchString.toUInt();
if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) )
{
rBitsPerPixel = -1;
}
}
// Guess frame rate - match %dbpp
QRegularExpressionMatch FpsMatch = QRegularExpression( "_[0-9]+fps" ).match( FilenameShort );
if( FpsMatch.hasMatch() )
{
QString matchString = FpsMatch.captured( FpsMatch.lastCapturedIndex() );
matchString.remove( "_" );
matchString.remove( "fps" );
rFrameRate = matchString.toUInt();
if( rFrameRate < 0 )
{
rFrameRate = 30;
}
}
// Guess Endianness
if( FilenameShort.contains( QStringLiteral( "be" ), Qt::CaseInsensitive ) )
{
rEndianness = CLP_BIG_ENDIAN;
}
if( FilenameShort.contains( QStringLiteral( "le" ), Qt::CaseInsensitive ) )
{
rEndianness = CLP_LITTLE_ENDIAN;
}
if( rWidth > 0 && rHeight > 0 && rInputFormat != ClpPixelFormats::Invalid ) bGuessed = true && !bGuessedByFilesize;
}
return bGuessed;
}
+106
View File
@@ -0,0 +1,106 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file VideostreamResource.h
* \brief Class to control video playback
*/
#ifndef __VIDEOSTREAMRESOURCE_H__
#define __VIDEOSTREAMRESOURCE_H__
#include <QElapsedTimer>
#include <QWidget>
#include "CalypResource.h"
#include "CommonDefs.h"
#include "config.h"
#include "lib/CalypStream.h"
struct CalypFileInfo
{
QString m_cFilename;
unsigned int m_uiWidth;
unsigned int m_uiHeight;
ClpPixelFormats m_iPelFormat;
unsigned int m_uiBitsPelPixel{ 8 };
int m_iEndianness{ CLP_LITTLE_ENDIAN };
unsigned int m_uiFrameRate{ 30 };
unsigned long long int m_uiFileSize;
bool m_bForceRaw{ false };
};
using CalypFileInfoVector = QVector<CalypFileInfo>;
auto operator<<( QDataStream& out, const CalypFileInfoVector& infos ) -> QDataStream&;
auto operator>>( QDataStream& in, CalypFileInfoVector& infos ) -> QDataStream&;
auto findCalypStreamInfo( const CalypFileInfoVector& array, const QString& filename ) -> int;
class VideostreamResource : public QObject, public CalypResource
{
Q_OBJECT
public:
VideostreamResource( QObject* parent = nullptr );
VideostreamResource( VideostreamResource&& other ) noexcept = delete;
VideostreamResource& operator=( VideostreamResource&& other ) noexcept = delete;
VideostreamResource( const VideostreamResource& other ) = delete;
VideostreamResource& operator=( const VideostreamResource& other ) = delete;
~VideostreamResource();
auto getResourceName() -> std::string override { return m_currStream.getFileName(); };
auto iteration() -> bool override;
auto isReady() -> bool override;
auto loadFile( const CalypFileInfo& streamInfo, bool optimistic = true ) -> bool;
auto getStreamInfo() const -> CalypFileInfo { return m_sStreamInfo; }
auto getResource() -> CalypStream* override { return &m_currStream; };
auto getStream() const -> const CalypStream& { return m_currStream; };
auto getCurrFrame() -> std::shared_ptr<CalypFrame>;
bool play();
void pause();
void stop();
bool playEvent();
void seekAbsoluteEvent( unsigned int new_frame_num );
void seekRelativeEvent( bool bIsForward );
private:
auto goToNextFrame( bool bThreaded ) -> bool;
void triggerRefresh();
// Q_SIGNALS:
// private Q_SLOTS:
private: // NOLINT
CalypStream m_currStream;
CalypFileInfo m_sStreamInfo;
bool m_bIsPlaying;
};
auto video_resource_guess_format( const QString& filename, unsigned int& rWidth, unsigned int& rHeight,
ClpPixelFormats& rInputFormat, unsigned int& rBitsPerPixel, int& rEndianness,
unsigned int& rFrameRate ) -> bool;
Q_DECLARE_METATYPE( CalypFileInfo ) // NOLINT
Q_DECLARE_METATYPE( CalypFileInfoVector ) // NOLINT
#endif // __VIDEOSTREAMRESOURCE_H__
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
+4 -4
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,17 +25,17 @@
#ifndef __WIDGETFRAMENUMBER_H__
#define __WIDGETFRAMENUMBER_H__
#include <QWidget>
#include "CommonDefs.h"
#include "config.h"
#include <QWidget>
class QLabel;
class FrameNumberWidget : public QWidget
{
public:
FrameNumberWidget( QWidget* parent = 0 );
explicit FrameNumberWidget( QWidget* parent = 0 );
void setCurrFrameNum( int number );
void setTotalFrameNum( int number );
void clear();
+32 -46
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -41,60 +41,42 @@ class HistogramWorker : public QThread
{
private:
QObject* m_parent;
CalypFrame* m_pcFrame;
std::shared_ptr<CalypFrame> m_pcFrame{ nullptr };
public:
HistogramWorker( QObject* parent )
{
m_pcFrame = NULL;
m_parent = parent;
}
: m_parent{ parent } {}
void setup( CalypFrame* frame )
void reset() { m_pcFrame = nullptr; }
void setup( std::shared_ptr<CalypFrame> frame )
{
m_pcFrame = frame;
// run();
m_pcFrame = std::move( frame );
EventData* eventData = new EventData(); // NOLINT
eventData->starting = true;
// QCoreApplication::postEvent( m_parent, eventData );
start();
}
void run()
void run() override
{
if( m_pcFrame && m_parent )
EventData* eventData = new EventData(); // NOLINT
if( m_pcFrame != nullptr )
{
EventData* eventData = new EventData();
// eventDm_imageHistogramata->starting = true;
// eventData->success = false;
// eventData->histogram = m_histogram;
// QCoreApplication::postEvent( m_parent, eventData );
eventData->starting = true;
m_pcFrame->calcHistogram();
eventData->starting = false;
// eventData->success = m_pcFrame->getHasHistogram();
eventData->success = true;
eventData->frame = m_pcFrame;
QCoreApplication::postEvent( m_parent, eventData );
eventData->frame = m_pcFrame.get();
}
eventData->success = true;
QCoreApplication::postEvent( m_parent, eventData );
}
/**
* Custom Event
*/
class EventData : public QEvent
{
public:
EventData()
: QEvent( QEvent::User )
{
starting = false;
success = false;
frame = NULL;
}
bool starting;
bool success;
CalypFrame* frame;
: QEvent( QEvent::User ), frame{ nullptr } {}
CalypFrame* frame{ nullptr };
bool starting{ false };
bool success{ false };
};
};
@@ -239,8 +221,10 @@ void HistogramWidget::reset()
d->guideVisible = false;
d->clearFlag = HistogramWidgetPrivate::HistogramNone;
// Remove histogram data from memory.
m_fullImage = NULL;
m_selectionImage = NULL;
m_fullImage = nullptr;
m_selectionImage = nullptr;
m_imageWorker->setup( nullptr );
m_selectionWorker->setup( nullptr );
update();
}
@@ -262,7 +246,7 @@ void HistogramWidget::customEvent( QEvent* event )
return;
}
if( ed->frame != m_fullImage && ed->frame != m_selectionImage )
if( ed->frame != m_fullImage.get() && ed->frame != m_selectionImage.get() )
{
return;
}
@@ -323,8 +307,6 @@ void HistogramWidget::customEvent( QEvent* event )
emit signalHistogramComputationFailed();
}
}
// delete ed;
}
////////////////////////////////////////////////////////////////////////////////
// Data Loading Functions
@@ -379,7 +361,7 @@ void HistogramWidget::stopHistogramComputation()
// Update Data Methods
////////////////////////////////////////////////////////////////////////////////
void HistogramWidget::updateData( CalypFrame* pcFrame, CalypFrame* pcFrameSelection )
void HistogramWidget::updateData( std::shared_ptr<CalypFrame> pcFrame, std::shared_ptr<CalypFrame> pcFrameSelection )
{
d->imageBits = pcFrame->getBitsPel();
switch( pcFrame->getColorSpace() )
@@ -497,7 +479,7 @@ void HistogramWidget::paintEvent( QPaintEvent* )
int wWidth = width() - 1;
int wHeight = height() - 1;
double max;
CalypFrame* frame;
std::shared_ptr<CalypFrame> frame;
if( m_renderingType == ImageSelectionHistogram && m_selectionImage )
frame = m_selectionImage;
@@ -938,7 +920,11 @@ void HistogramWidget::paintEvent( QPaintEvent* )
tipText += cellBeg + tr( "Median:" ) + cellMid;
double median = frame->getMedian( m_channelType, 0, frame->getNumHistogramSegment() - 1 );
tipText += value.setNum( median, 'f', 1 ) + cellEnd;
tipText += value.setNum( median, 'f', 0 ) + cellEnd;
tipText += cellBeg + tr( "Entropy:" ) + cellMid;
double entropy = frame->getEntropy( m_channelType, 0, frame->getNumHistogramSegment() - 1 );
tipText += value.setNum( entropy, 'f', 2 ) + cellEnd;
tipText += cellBeg + tr( "Percent:" ) + cellMid;
double percentile = ( pixels > 0 ? ( 100.0 * counts / pixels ) : 0.0 );
+7 -9
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,13 +26,13 @@
#ifndef __HISTOGRAMWIDGET_H__
#define __HISTOGRAMWIDGET_H__
#include <QColor>
#include <QWidget>
#include "CommonDefs.h"
#include "config.h"
#include "lib/CalypFrame.h"
#include <QColor>
#include <QWidget>
class QEvent;
class HistogramWorker;
@@ -90,7 +90,7 @@ public:
void stopHistogramComputation();
/** Update full image histogram data. */
void updateData( CalypFrame* pcFrame, CalypFrame* pcFrameSelection );
void updateData( std::shared_ptr<CalypFrame> pcFrame, std::shared_ptr<CalypFrame> pcFrameSelection );
/** @see @p HistogramOption */
void setOptions( HistogramOptions options = AllOptions );
@@ -113,12 +113,10 @@ public:
/** Full image */
HistogramWorker* m_imageWorker;
// CalypFrameStats* m_imageHistogram;
CalypFrame* m_fullImage;
std::shared_ptr<CalypFrame> m_fullImage;
/** Histogram area selection */
HistogramWorker* m_selectionWorker;
// CalypFrameStats* m_selectionHistogram;
CalypFrame* m_selectionImage;
std::shared_ptr<CalypFrame> m_selectionImage;
Q_SIGNALS:
void signalintervalChanged( int min, int max );
+94 -102
View File
@@ -1,147 +1,139 @@
# - Try to find the required ffmpeg components(default: AVFORMAT, AVUTIL, AVCODEC)
# * Try to find the required ffmpeg components(default: AVFORMAT, AVUTIL, AVCODEC)
#
# Once done this will define
# FFMPEG_FOUND - System has the all required components.
# FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers.
# FFMPEG_LIBRARIES - Link these to use the required ffmpeg components.
# FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components.
# Once done this will define FFMPEG_FOUND - System has the all required components. FFMPEG_INCLUDE_DIRS - Include directory necessary for
# using the required components headers. FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. FFMPEG_DEFINITIONS - Compiler
# switches required for using the required ffmpeg components.
#
# For each of the components it will additionally set.
# - AVCODEC
# - AVDEVICE
# - AVFORMAT
# - AVUTIL
# - POSTPROCESS
# - SWSCALE
# the following variables will be defined
# <component>_FOUND - System has <component>
# <component>_INCLUDE_DIRS - Include directory necessary for using the <component> headers
# <component>_LIBRARIES - Link these to use <component>
# <component>_DEFINITIONS - Compiler switches required for using <component>
# <component>_VERSION - The components version
# For each of the components it will additionally set. - AVCODEC - AVDEVICE - AVFORMAT - AVUTIL - POSTPROCESS - SWSCALE the following variables will
# be defined <component>_FOUND - System has <component> <component>_INCLUDE_DIRS - Include directory necessary for using the <component>
# headers <component>_LIBRARIES - Link these to use <component> <component>_DEFINITIONS - Compiler switches required for using <component>
# <component>_VERSION - The components version
#
# Copyright (c) 2006, Matthias Kretz, <kretz@kde.org>
# Copyright (c) 2008, Alexander Neundorf, <neundorf@kde.org>
# Copyright (c) 2011, Michael Jansen, <kde@michael-jansen.biz>
# Copyright (c) 2006, Matthias Kretz, <kretz@kde.org> Copyright (c) 2008, Alexander Neundorf, <neundorf@kde.org> Copyright (c) 2011, Michael Jansen,
# <kde@michael-jansen.biz>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Redistribution and use is allowed according to the terms of the BSD license. For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(FindPackageHandleStandardArgs)
INCLUDE(FindPackageHandleStandardArgs)
# The default components were taken from a survey over other FindFFMPEG.cmake files
if (NOT FFmpeg_FIND_COMPONENTS)
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL)
endif ()
IF(NOT FFmpeg_FIND_COMPONENTS)
SET(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL)
ENDIF()
#
### Macro: set_component_found
# Macro: set_component_found
#
# Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present.
#
macro(set_component_found _component )
if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS)
MACRO(set_component_found _component)
IF(${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS)
# message(STATUS " - ${_component} found.")
set(${_component}_FOUND TRUE)
else ()
SET(${_component}_FOUND TRUE)
ELSE()
# message(STATUS " - ${_component} not found.")
endif ()
endmacro()
ENDIF()
ENDMACRO()
#
### Macro: find_component
# Macro: find_component
#
# Checks for the given component by invoking pkgconfig and then looking up the libraries and
# include directories.
# Checks for the given component by invoking pkgconfig and then looking up the libraries and include directories.
#
macro(find_component _component _pkgconfig _library _header)
MACRO(find_component _component _pkgconfig _library _header)
if (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_${_component} ${_pkgconfig})
endif ()
endif (NOT WIN32)
IF(NOT WIN32)
# use pkg-config to get the directories and then use these values in the FIND_PATH() and FIND_LIBRARY() calls
FIND_PACKAGE(PkgConfig)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(PC_${_component} ${_pkgconfig})
ENDIF()
ENDIF(NOT WIN32)
find_path(${_component}_INCLUDE_DIRS ${_header}
HINTS
${PC_LIB${_component}_INCLUDEDIR}
${PC_LIB${_component}_INCLUDE_DIRS}
PATH_SUFFIXES
ffmpeg
FIND_PATH(
${_component}_INCLUDE_DIRS ${_header}
HINTS ${PC_LIB${_component}_INCLUDEDIR} ${PC_LIB${_component}_INCLUDE_DIRS}
PATH_SUFFIXES ffmpeg
)
find_library(${_component}_LIBRARIES NAMES ${_library}
HINTS
${PC_LIB${_component}_LIBDIR}
${PC_LIB${_component}_LIBRARY_DIRS}
)
set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.")
set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.")
set_component_found(${_component})
mark_as_advanced(
${_component}_INCLUDE_DIRS
FIND_LIBRARY(
${_component}_LIBRARIES
${_component}_DEFINITIONS
${_component}_VERSION)
NAMES ${_library}
HINTS ${PC_LIB${_component}_LIBDIR} ${PC_LIB${_component}_LIBRARY_DIRS}
)
endmacro()
SET(${_component}_DEFINITIONS
${PC_${_component}_CFLAGS_OTHER}
CACHE STRING "The ${_component} CFLAGS."
)
SET(${_component}_VERSION
${PC_${_component}_VERSION}
CACHE STRING "The ${_component} version number."
)
SET_COMPONENT_FOUND(${_component})
MARK_AS_ADVANCED(${_component}_INCLUDE_DIRS ${_component}_LIBRARIES ${_component}_DEFINITIONS ${_component}_VERSION)
ENDMACRO()
# Check for cached results. If there are skip the costly part.
if (NOT FFMPEG_LIBRARIES)
IF(NOT FFMPEG_LIBRARIES)
# Check for all possible component.
find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h)
find_component(AVFORMAT libavformat avformat libavformat/avformat.h)
find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h)
find_component(AVUTIL libavutil avutil libavutil/avutil.h)
find_component(SWSCALE libswscale swscale libswscale/swscale.h)
find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h)
FIND_COMPONENT(AVCODEC libavcodec avcodec libavcodec/avcodec.h)
FIND_COMPONENT(AVFORMAT libavformat avformat libavformat/avformat.h)
FIND_COMPONENT(AVDEVICE libavdevice avdevice libavdevice/avdevice.h)
FIND_COMPONENT(AVUTIL libavutil avutil libavutil/avutil.h)
FIND_COMPONENT(SWSCALE libswscale swscale libswscale/swscale.h)
FIND_COMPONENT(SWRESAMPLE libswresample swresample libswresample/swresample.h)
FIND_COMPONENT(POSTPROC libpostproc postproc libpostproc/postprocess.h)
# Check if the required components were found and add their stuff to the FFMPEG_* vars.
foreach (_component ${FFmpeg_FIND_COMPONENTS})
if (${_component}_FOUND)
FOREACH(_component ${FFmpeg_FIND_COMPONENTS})
IF(${_component}_FOUND)
# message(STATUS "Required component ${_component} present.")
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARIES})
set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS})
list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
else ()
SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARIES})
SET(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS})
LIST(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
ELSE()
# message(STATUS "Required component ${_component} missing.")
endif ()
endforeach ()
ENDIF()
ENDFOREACH()
# Build the include path with duplicates removed.
if (FFMPEG_INCLUDE_DIRS)
list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
endif ()
IF(FFMPEG_INCLUDE_DIRS)
LIST(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
ENDIF()
# cache the vars.
set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE)
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE)
set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE)
SET(FFMPEG_INCLUDE_DIRS
${FFMPEG_INCLUDE_DIRS}
CACHE STRING "The FFmpeg include directories." FORCE
)
SET(FFMPEG_LIBRARIES
${FFMPEG_LIBRARIES}
CACHE STRING "The FFmpeg libraries." FORCE
)
SET(FFMPEG_DEFINITIONS
${FFMPEG_DEFINITIONS}
CACHE STRING "The FFmpeg cflags." FORCE
)
mark_as_advanced(FFMPEG_INCLUDE_DIRS
FFMPEG_LIBRARIES
FFMPEG_DEFINITIONS)
MARK_AS_ADVANCED(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES FFMPEG_DEFINITIONS)
endif ()
ENDIF()
# Now set the noncached _FOUND vars for the components.
foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE)
set_component_found(${_component})
endforeach ()
FOREACH(_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE)
SET_COMPONENT_FOUND(${_component})
ENDFOREACH()
# Compile the list of required vars
set(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS)
foreach (_component ${FFmpeg_FIND_COMPONENTS})
list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS)
endforeach ()
SET(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS)
FOREACH(_component ${FFmpeg_FIND_COMPONENTS})
LIST(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS)
ENDFOREACH()
# Give a nice error message if some of the required vars are missing.
find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS})
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS})
+51 -50
View File
@@ -1,67 +1,68 @@
MACRO(ADD_EXTRA_MODULES dir)
SET( MODULE_LOCATION "${dir}/" )
ADD_SUBDIRECTORY( ${dir} ${CMAKE_CURRENT_BINARY_DIR}/extra-modules )
INCLUDE_DIRECTORIES( ${dir} )
SET( MODULE_LOCATION "${dir}/" PARENT_SCOPE )
ENDMACRO()
MACRO(ADD_MODULE name file )
# General function to add a module It receives the name of the module and the filename where it is defined. Used in modules/CMakeLists.txt
MACRO(ADD_MODULE name file)
SET(__modulename "Module${name}")
OPTION(MODULE_${name} "Use module ${name}" ON )
ADD_FEATURE_INFO(${name} MODULE_${name} "Module ${name}" )
IF( MODULE_${name} )
list(APPEND Calyp_Mod_SRCS ${MODULE_LOCATION}${file} )
LIST(APPEND MODULES_LIST_NAME ${name} )
LIST(APPEND MODULES_LIST_FILES ${file} )
SET( Calyp_Mod_SRCS "${Calyp_Mod_SRCS}" PARENT_SCOPE )
SET( MODULES_LIST_NAME "${MODULES_LIST_NAME}" PARENT_SCOPE )
SET( MODULES_LIST_FILES "${MODULES_LIST_FILES}" PARENT_SCOPE )
OPTION(MODULE_${name} "Use module ${name}" ON)
ADD_FEATURE_INFO(${name} MODULE_${name} "Module ${name}")
IF(MODULE_${name})
LIST(APPEND Calyp_Mod_SRCS ${MODULE_LOCATION}${file}.cpp)
LIST(APPEND MODULES_LIST_NAME ${name})
LIST(APPEND MODULES_LIST_FILES ${file})
SET(Calyp_Mod_SRCS
"${Calyp_Mod_SRCS}"
PARENT_SCOPE
)
SET(MODULES_LIST_NAME
"${MODULES_LIST_NAME}"
PARENT_SCOPE
)
SET(MODULES_LIST_FILES
"${MODULES_LIST_FILES}"
PARENT_SCOPE
)
ENDIF()
UNSET(__modulename)
ENDMACRO()
MACRO(ADD_MODULE_USE_OPENCV name file )
IF( USE_OPENCV )
SET( ADD_MODULE_USE_OPENCV_VERSION "2.4" )
CMAKE_PARSE_ARGUMENTS(ADD_MODULE_USE_OPENCV "" "VERSION" "MODULES" ${ARGN} )
IF( NOT ( ${OpenCV_VERSION} VERSION_LESS ${ADD_MODULE_USE_OPENCV_VERSION} ) )
SET( _HAS_MODULES TRUE )
FOREACH(opencv_module IN LISTS ADD_MODULE_USE_OPENCV_MODULES )
string(TOUPPER "${opencv_module}" opencv_moduleUP)
FIND_PACKAGE( OpenCV QUIET COMPONENTS ${opencv_module} )
IF( NOT ${OPENCV_${opencv_moduleUP}_FOUND} EQUAL "1" )
SET( _HAS_MODULES FALSE )
# General function to add a module It receives the name of the module and the filename where it is defined. Moreover it receives a VERSION and MODULES
# (OpenCV modules required) Used in modules/CMakeLists.txt
MACRO(ADD_MODULE_USE_OPENCV name file)
IF(USE_OPENCV)
SET(ADD_MODULE_USE_OPENCV_VERSION "2.4")
CMAKE_PARSE_ARGUMENTS(ADD_MODULE_USE_OPENCV "" "VERSION" "MODULES" ${ARGN})
IF(NOT (${OpenCV_VERSION} VERSION_LESS ${ADD_MODULE_USE_OPENCV_VERSION}))
SET(_HAS_MODULES TRUE)
FOREACH(opencv_module IN LISTS ADD_MODULE_USE_OPENCV_MODULES)
STRING(TOUPPER "${opencv_module}" opencv_moduleUP)
FIND_PACKAGE(OpenCV QUIET COMPONENTS ${opencv_module})
IF(NOT ${OPENCV_${opencv_moduleUP}_FOUND} EQUAL "1")
SET(_HAS_MODULES FALSE)
ELSE()
LIST(APPEND OPENCV_MODULES ${opencv_module} )
LIST(APPEND OPENCV_MODULES ${opencv_module})
ENDIF()
ENDFOREACH()
IF( _HAS_MODULES )
ADD_MODULE( ${name} ${file} )
IF(_HAS_MODULES)
ADD_MODULE(${name} ${file})
ENDIF()
UNSET( OPENCV_${opencv_moduleUP}_FOUND )
UNSET( _HAS_MODULES )
UNSET(OPENCV_${opencv_moduleUP}_FOUND)
UNSET(_HAS_MODULES)
ENDIF()
UNSET( ADD_MODULE_USE_OPENCV_VERSION )
UNSET(ADD_MODULE_USE_OPENCV_VERSION)
ENDIF()
ENDMACRO()
#
# Create header
#
MACRO(CREATE_MODULE_MACROS )
file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "// This files add the header files of each module\n"
"#ifndef __MODULESLISTHEADER_H__\n#define __MODULESLISTHEADER_H__\n" )
foreach(module ${MODULES_LIST_FILES})
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "#include \"${module}.h\"\n")
endforeach(module ${MODULES_LIST_FILES})
MACRO(CREATE_MODULE_MACROS)
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "// This files add the header files of each module\n"
"#ifndef __MODULESLISTHEADER_H__\n#define __MODULESLISTHEADER_H__\n"
)
FOREACH(module ${MODULES_LIST_FILES})
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "#include \"${module}.h\"\n")
ENDFOREACH(module ${MODULES_LIST_FILES})
file( APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "#define REGISTER_ALL_MODULES \\\n" )
foreach(module ${MODULES_LIST_NAME})
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "Register( \"${module}\", &(${module}::Create) ); \\\n")
endforeach(module ${MODULES_LIST_NAME})
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "#define REGISTER_ALL_MODULES \\\n")
FOREACH(module ${MODULES_LIST_NAME})
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "Register( \"${module}\", &(${module}::Create) ); \\\n")
ENDFOREACH(module ${MODULES_LIST_NAME})
file( APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "\n#endif // __MODULESLISTHEADER_H__\n" )
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ModulesListHeader.h "\n#endif // __MODULESLISTHEADER_H__\n")
ENDMACRO()
+67 -49
View File
@@ -1,63 +1,81 @@
#####################################################################################
# ####################################################################################################################################################
# DLLs and Win32 specific code
######################################################################################
# ####################################################################################################################################################
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "." )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "." )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "." )
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
FOREACH(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
STRING(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ".")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ".")
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ".")
ENDFOREACH(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
SET(MSVC_DLL_DIR "MSVC_DLL_DIR" CACHE PATH "Where to find MSVC dlls")
#INSTALL(FILES ${MSVC_DLL_DIR}/msvcr120.dll DESTINATION bin )
#INSTALL(FILES ${MSVC_DLL_DIR}/msvcp120.dll DESTINATION bin )
SET(MSVC_DLL_DIR
"MSVC_DLL_DIR"
CACHE PATH "Where to find MSVC dlls"
)
# INSTALL(FILES ${MSVC_DLL_DIR}/msvcr120.dll DESTINATION bin ) INSTALL(FILES ${MSVC_DLL_DIR}/msvcp120.dll DESTINATION bin )
SET(QT_DIR "QT-Dir" CACHE PATH "Where to find QT Lib on Windows")
SET(QT_ICU_VERSION "" CACHE STRING "Qt ICU version of dll's" )
SET(QT_DLL_POSTFIX "" CACHE STRING "Postfix to dll's name for debug" )
SET(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH} ${QT_DIR}" )
SET(QT_DIR
"QT-Dir"
CACHE PATH "Where to find QT Lib on Windows"
)
SET(QT_ICU_VERSION
""
CACHE STRING "Qt ICU version of dll's"
)
SET(QT_DLL_POSTFIX
""
CACHE STRING "Postfix to dll's name for debug"
)
SET(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH} ${QT_DIR}")
SET(WINDLLIB "Dl-location" CACHE PATH "Where to find DL Lib on Windows")
SET(WINDLLIB
"Dl-location"
CACHE PATH "Where to find DL Lib on Windows"
)
IF(NOT USE_QT4)
INSTALL(FILES ${QT_DIR}/bin/Qt5Core${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Gui${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Widgets${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5PrintSupport${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/plugins/platforms/qwindows${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms)
INSTALL(FILES ${QT_DIR}/plugins/platforms/qminimal${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms)
INSTALL(FILES ${QT_DIR}/plugins/platforms/qoffscreen${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms)
IF( NOT USE_QT4 )
INSTALL(FILES ${QT_DIR}/bin/Qt5Core${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Gui${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Widgets${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5PrintSupport${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/plugins/platforms/qwindows${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms )
INSTALL(FILES ${QT_DIR}/plugins/platforms/qminimal${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms )
INSTALL(FILES ${QT_DIR}/plugins/platforms/qoffscreen${QT_DLL_POSTFIX}.dll DESTINATION bin/platforms )
IF( USE_FERVOR )
INSTALL(FILES ${QT_DIR}/bin/Qt5Network${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5WebKit${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5WebKitWidgets${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Quick${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Qml${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Multimedia${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Sql${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Positioning${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5Sensors${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5MultimediaWidgets${QT_DLL_POSTFIX}.dll DESTINATION bin )
INSTALL(FILES ${QT_DIR}/bin/Qt5OpenGL${QT_DLL_POSTFIX}.dll DESTINATION bin )
IF(USE_FERVOR)
INSTALL(FILES ${QT_DIR}/bin/Qt5Network${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5WebKit${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5WebKitWidgets${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Quick${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Qml${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Multimedia${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Sql${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Positioning${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5Sensors${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5MultimediaWidgets${QT_DLL_POSTFIX}.dll DESTINATION bin)
INSTALL(FILES ${QT_DIR}/bin/Qt5OpenGL${QT_DLL_POSTFIX}.dll DESTINATION bin)
ENDIF()
ENDIF()
IF( USE_OPENCV )
SET(OpenCV_DLL_DIR "${OpenCV_DIR}/bin" CACHE PATH "Where to find OpenCV dlls")
SET(OpenCV_INSTALL_MODULES ${OPENCV_MODULES} CACHE STRING "List of OpenCV modules")
FOREACH(opencv_module IN LISTS OpenCV_INSTALL_MODULES )
INSTALL(FILES ${OpenCV_DLL_DIR}/opencv_${opencv_module}${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.dll DESTINATION bin )
IF(USE_OPENCV)
SET(OpenCV_DLL_DIR
"${OpenCV_DIR}/bin"
CACHE PATH "Where to find OpenCV dlls"
)
SET(OpenCV_INSTALL_MODULES
${OPENCV_MODULES}
CACHE STRING "List of OpenCV modules"
)
FOREACH(opencv_module IN LISTS OpenCV_INSTALL_MODULES)
INSTALL(FILES ${OpenCV_DLL_DIR}/opencv_${opencv_module}${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.dll DESTINATION bin)
ENDFOREACH()
ENDIF()
IF( USE_FFMPEG )
SET(FFMPEG_DIR "FFmpeg-Dir" CACHE PATH "Where to find FFmpeg Lib on Windows")
INSTALL(FILES ${FFMPEG_DIR}/bin/avcodec-${AVCODEC_VERSION}.dll DESTINATION bin )
INSTALL(FILES ${FFMPEG_DIR}/bin/avformat-${AVFORMAT_VERSION}.dll DESTINATION bin )
INSTALL(FILES ${FFMPEG_DIR}/bin/avutil-${AVUTIL_VERSION}.dll DESTINATION bin )
INSTALL(FILES ${FFMPEG_DIR}/bin/swscale-${SWSCALE_VERSION}.dll DESTINATION bin )
INSTALL(FILES ${FFMPEG_DIR}/bin/swresample-${SWRESAMPLE_VERSION}.dll DESTINATION bin )
IF(USE_FFMPEG)
SET(FFMPEG_DIR
"FFmpeg-Dir"
CACHE PATH "Where to find FFmpeg Lib on Windows"
)
INSTALL(DIRECTORY ${FFMPEG_DIR}/bin/ DESTINATION bin)
ENDIF()
+8 -5
View File
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -26,10 +26,10 @@
#define __CONFIG_CALYP_H__
/* Version definition */
#define CALYP_VERSION_MAJOR @CALYP_VERSION_MAJOR@
#define CALYP_VERSION_MINOR @CALYP_VERSION_MINOR@
#define CALYP_VERSION_PATCH @CALYP_VERSION_PATCH@
#define CALYP_VERSION @CALYP_VERSION@
#define CALYP_VERSION_MAJOR @CALYP_VERSION_MAJOR @
#define CALYP_VERSION_MINOR @CALYP_VERSION_MINOR @
#define CALYP_VERSION_PATCH @CALYP_VERSION_PATCH @
#define CALYP_VERSION @CALYP_VERSION @
#define CALYP_VERSION_STRING "@CALYP_VERSION_STRING@"
#define UPDATE_CHANNEL "@UPDATE_CHANNEL@"
@@ -55,4 +55,7 @@
/* Fervor update lib */
#cmakedefine USE_FERVOR
/* Use a resource manager to manage streams in different threads */
#cmakedefine CALYP_MANAGED_RESOURCES
#endif // __CONFIG_CALYP_H__
+5 -6
View File
@@ -1,7 +1,6 @@
###
### CMakeLists for examples
###
ADD_SUBDIRECTORY( modules )
#
# CMakeLists for examples
#
ADD_SUBDIRECTORY(modules)
ADD_SUBDIRECTORY(stream)
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@
*/
#include "AbsoluteFrameDifferenceExample.h"
#include <cstdlib>
REGISTER_CLASS_MAKER( AbsoluteFrameDifferenceExample )
@@ -32,15 +33,15 @@ AbsoluteFrameDifferenceExample::AbsoluteFrameDifferenceExample()
/* Module Definition */
m_iModuleAPI = CLP_MODULE_API_2; // Use API version 2 (recommended).
// See this example for details on the functions prototype
m_iModuleType = CLP_FRAME_PROCESSING_MODULE; // Apply module to the frames or to the whole sequence.
m_iModuleType = ClpModuleType::FrameProcessing; // Apply module to the frames or to the whole sequence.
m_pchModuleCategory = "Measurements"; // Category (sub-menu)
m_pchModuleName = "AbsoluteDifferenceExample"; // Name
m_pchModuleLongName = "Absolute Difference Example"; // Name
m_pchModuleTooltip = "Measure the absolute difference " // Description
"between two images (Y plane), e. g., abs( Y1 - Y2 )";
m_uiNumberOfFrames = 2; // Number of Frames required (ONE_FRAME, TWO_FRAMES, THREE_FRAMES)
m_uiModuleRequirements = CLP_MODULE_REQUIRES_NEW_WINDOW; // Module requirements (check CalypModulesIf.h).
// Several requirements should be "or" between each others.
m_uiNumberOfFrames = 2; // Number of Frames required (ONE_FRAME, TWO_FRAMES, THREE_FRAMES)
m_uiModuleRequirements = ClpModuleFeature::NewWindow; // Module requirements (check CalypModulesIf.h).
// Several requirements should be "or" between each others.
m_pcFrameDifference = NULL;
}
@@ -55,7 +56,7 @@ bool AbsoluteFrameDifferenceExample::create( std::vector<CalypFrame*> apcFrameLi
return false;
m_pcFrameDifference =
new CalypFrame( apcFrameList[0]->getWidth(), apcFrameList[0]->getHeight(), CLP_GRAY );
new CalypFrame( apcFrameList[0]->getWidth(), apcFrameList[0]->getHeight(), ClpPixelFormats::Gray );
return true;
}
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,14 +25,12 @@
#ifndef __ABSOLUTEFRAMEDIFFERENCEEXAMPLE_H__
#define __ABSOLUTEFRAMEDIFFERENCEEXAMPLE_H__
#include "CalypModuleIf.h"
#include <cassert>
class AbsoluteFrameDifferenceExample : public CalypModuleIf
{
REGISTER_CLASS_FACTORY( AbsoluteFrameDifferenceExample )
#include "CalypModuleIf.h"
class AbsoluteFrameDifferenceExample : public CalypModuleIf, public CalypModuleInstance<AbsoluteFrameDifferenceExample>
{
private:
CalypFrame* m_pcFrameDifference;
+10 -15
View File
@@ -1,21 +1,16 @@
###
### CMakeLists for modules_example
###
#
# CMakeLists for modules_example
#
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.0)
CMAKE_MINIMUM_REQUIRED( VERSION 2.8.9 )
PROJECT("modules_example")
PROJECT( "modules_example" )
# THIS FIND_PACKAGE( Calyp ) INCLUDE_DIRECTORIES( ${CALYP_INCLUDE_DIRS} ) OR
INCLUDE_DIRECTORIES(../../lib)
# THIS
# FIND_PACKAGE( Calyp )
#INCLUDE_DIRECTORIES( ${CALYP_INCLUDE_DIRS} )
# OR
INCLUDE_DIRECTORIES( ../../lib )
ADD_LIBRARY(FrameBinarization SHARED FrameBinarization_APIv1.cpp)
TARGET_LINK_LIBRARIES( FrameBinarization ${CALYP_LINKER_LIBS} )
ADD_LIBRARY(FrameBinarizationAPIv1 SHARED FrameBinarizationAPIv1.cpp)
TARGET_LINK_LIBRARIES(FrameBinarizationAPIv1 ${PROJECT_LIBRARY})
ADD_LIBRARY(AbsoluteFrameDifferenceExample SHARED AbsoluteFrameDifferenceExample.cpp)
TARGET_LINK_LIBRARIES( AbsoluteFrameDifferenceExample ${PROJECT_LIBRARY} ${CALYP_LINKER_LIBS} )
TARGET_LINK_LIBRARIES(AbsoluteFrameDifferenceExample ${PROJECT_LIBRARY})
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -18,24 +18,24 @@
*/
/**
* \file FrameBinarization_APIv1.cpp
* \file FrameBinarizationAPIv1.cpp
* \brief Binarize frame module (example of APIv1)
*/
#include "FrameBinarization_APIv1.h"
#include "FrameBinarizationAPIv1.h"
REGISTER_CLASS_MAKER( FrameBinarization_APIv1 )
REGISTER_CLASS_MAKER( FrameBinarizationAPIv1 )
FrameBinarization_APIv1::FrameBinarization_APIv1()
FrameBinarizationAPIv1::FrameBinarizationAPIv1()
{
/* Module Definition */
m_iModuleType = CLP_FRAME_PROCESSING_MODULE;
m_iModuleType = ClpModuleType::FrameProcessing;
m_pchModuleCategory = "Utilities";
m_pchModuleName = "FrameBinarization_APIv1";
m_pchModuleName = "FrameBinarizationAPIv1";
m_pchModuleLongName = "Frame Binarization API v1";
m_pchModuleTooltip = "Binarize frame";
m_uiNumberOfFrames = 1;
m_uiModuleRequirements = CLP_MODULE_REQUIRES_OPTIONS;
m_uiModuleRequirements = ClpModuleFeature::Options;
m_cModuleOptions.addOptions() /**/
( "threshold", m_uiThreshold, "Threshold level for binarization (0-255) [128]" );
@@ -44,13 +44,13 @@ FrameBinarization_APIv1::FrameBinarization_APIv1()
m_uiThreshold = 128;
}
void FrameBinarization_APIv1::create( CalypFrame* frame )
void FrameBinarizationAPIv1::create( CalypFrame* frame )
{
m_pcBinFrame = NULL;
m_pcBinFrame = new CalypFrame( frame->getWidth(), frame->getHeight(), CLP_GRAY, 8 );
m_pcBinFrame = new CalypFrame( frame->getWidth(), frame->getHeight(), ClpPixelFormats::Gray, 8 );
}
CalypFrame* FrameBinarization_APIv1::process( CalypFrame* frame )
CalypFrame* FrameBinarizationAPIv1::process( CalypFrame* frame )
{
const ClpPel* pPelInput = frame->getPelBufferYUV()[0][0];
ClpPel* pPelBin = m_pcBinFrame->getPelBufferYUV()[0][0];
@@ -62,7 +62,7 @@ CalypFrame* FrameBinarization_APIv1::process( CalypFrame* frame )
return m_pcBinFrame;
}
void FrameBinarization_APIv1::destroy()
void FrameBinarizationAPIv1::destroy()
{
if( m_pcBinFrame )
delete m_pcBinFrame;
@@ -1,5 +1,5 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2019 by Joao Carreira (jfmcarreira@gmail.com)
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -18,29 +18,27 @@
*/
/**
* \file FrameBinarization_APIv1.h
* \file FrameBinarizationAPIv1.h
* \brief Binarize frame module (example of APIv1)
*/
#ifndef __FRAMEBINARIZATION_APIV1_H__
#define __FRAMEBINARIZATION_APIV1_H__
#ifndef __FRAMEBINARIZATIONAPIV1_H__
#define __FRAMEBINARIZATIONAPIV1_H__
#include "CalypModuleIf.h"
class FrameBinarization_APIv1 : public CalypModuleIf
class FrameBinarizationAPIv1 : public CalypModuleIf, public CalypModuleInstance<FrameBinarizationAPIv1>
{
REGISTER_CLASS_FACTORY( FrameBinarization_APIv1 )
private:
CalypFrame* m_pcBinFrame;
unsigned int m_uiThreshold;
public:
FrameBinarization_APIv1();
virtual ~FrameBinarization_APIv1() {}
FrameBinarizationAPIv1();
virtual ~FrameBinarizationAPIv1() {}
void create( CalypFrame* );
CalypFrame* process( CalypFrame* );
void destroy();
};
#endif // __FRAMEBINARIZATION_APIV1_H__
#endif // __FRAMEBINARIZATIONAPIV1_H__
+9
View File
@@ -0,0 +1,9 @@
#
# CMakeLists for modules_example
#
INCLUDE_DIRECTORIES(../../lib)
ADD_DEFINITIONS(-DCALYP_TEST_DATA_DIR=\"${CALYP_TEST_DATA_DIR}\")
ADD_EXECUTABLE(testStreamReading testStreamReading.cpp)
TARGET_LINK_LIBRARIES(testStreamReading ${PROJECT_LIBRARY})
+68
View File
@@ -0,0 +1,68 @@
/* This file is a part of Calyp project
* Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com)
*
* Luis Lucas (luisfrlucas@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* \file testStreamReading.cpp
* \brief Example of open and reading from a stream
*/
#include <chrono>
#include <iostream>
#include "CalypFrame.h"
#include "CalypStream.h"
int main( int argc, char* argv[] )
{
// Use auto keyword to avoid typing long
// type definitions to get the timepoint
// at this instant use function now()
auto start = std::chrono::high_resolution_clock::now();
double n = 0;
CalypStream stream;
stream.open( std::string( CALYP_TEST_DATA_DIR ) + std::string( "/Foreman.yuv" ), 352, 288, 0, 8, CLP_BIG_ENDIAN, 1, true );
while( 1 )
{
CalypFrame* frame = stream.getCurrFrame();
frame->fillRGBBuffer();
n++;
if( stream.setNextFrame() )
break;
stream.readNextFrame();
}
// After function call
auto stop = std::chrono::high_resolution_clock::now();
// Subtract stop and start timepoints and
// cast it to required unit. Predefined units
// are nanoseconds, microseconds, milliseconds,
// seconds, minutes, hours. Use duration_cast()
// function.
auto duration = std::chrono::duration_cast<std::chrono::microseconds>( stop - start );
// To get the value of duration use the count()
// member function on the duration object
std::cout << duration.count() / 1000.0 / n << std::endl;
return 0;
}
+71 -67
View File
@@ -1,22 +1,18 @@
###
### CMakeLists for calyp lib component
###
#
# CMakeLists for calyp lib component
#
INCLUDE(GNUInstallDirs)
SET(CMAKE_EXPORT_PACKAGE_REGISTRY ON)
EXPORT(PACKAGE MyLib)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} )
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(Calyp_Lib_SRCS
LibMemory.h
CalypLib.h
CalypDefs.h
# Frame
CalypFrame.h
CalypFrame.cpp
CalypPixel.cpp
PixelFormats.h
PixelFormats.cpp
# Stream
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
SET(Calyp_Lib_Frame_SRCS CalypPixel.cpp PixelFormats.h PixelFormats.cpp CalypFrame.h CalypFrame.cpp)
SET(Calyp_Lib_Stream_SRCS
CalypStream.h
CalypStream.cpp
CalypStreamHandlerIf.h
@@ -24,81 +20,89 @@ set(Calyp_Lib_SRCS
StreamHandlerRaw.cpp
StreamHandlerPortableMap.h
StreamHandlerPortableMap.cpp
# Options Parser
CalypOptions.h
CalypOptions.cpp
# Modules
CalypModuleIf.h
CalypOpenCVModuleIf.h
)
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${PROJECT_LIBRARY} )
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} )
SET(Calyp_Lib_OptionParser_SRCS CalypOptions.h CalypOptions.cpp)
IF( USE_FFMPEG )
LIST( APPEND Calyp_Lib_SRCS StreamHandlerLibav.h )
LIST( APPEND Calyp_Lib_SRCS StreamHandlerLibav.cpp )
SET(Calyp_Lib_Modules_SRCS CalypModuleIf.h CalypModuleIf.cpp)
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${FFMPEG_LIBRARIES} )
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} )
SET(Calyp_Lib_SRCS CalypLib.h CalypDefs.h ${Calyp_Lib_Frame_SRCS} ${Calyp_Lib_Stream_SRCS} ${Calyp_Lib_OptionParser_SRCS} ${Calyp_Lib_Modules_SRCS})
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
IF(USE_FFMPEG)
LIST(APPEND Calyp_Lib_SRCS StreamHandlerLibav.h)
LIST(APPEND Calyp_Lib_SRCS StreamHandlerLibav.cpp)
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${FFMPEG_LIBRARIES})
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIRS})
LIST(APPEND CALYP_LIB_LINKER_DEPENDENCIES ${FFMPEG_LIBRARIES})
ENDIF()
IF( USE_OPENCV )
LIST( APPEND Calyp_Lib_SRCS StreamHandlerOpenCV.h )
LIST( APPEND Calyp_Lib_SRCS StreamHandlerOpenCV.cpp )
IF(USE_OPENCV)
LIST(APPEND Calyp_Lib_SRCS StreamHandlerOpenCV.h)
LIST(APPEND Calyp_Lib_SRCS StreamHandlerOpenCV.cpp)
LIST( APPEND Calyp_Lib_SRCS CalypOpenCVModuleIf.cpp )
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${OpenCV_LIBRARIES})
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS})
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${OpenCV_LIBRARIES} )
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS} )
LIST(APPEND CMAKE_CFG_LINKER_LIBSS ${PROJECT_LIBRARY})
LIST(APPEND CMAKE_CFG_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
LIST(APPEND CALYP_LIB_LINKER_DEPENDENCIES ${OpenCV_LIBRARIES})
ENDIF()
set(Calyp_Lib_HEADERS
CalypDefs.h
CalypFrame.h
CalypStream.h
CalypOptions.h
CalypModuleIf.h
CalypOpenCVModuleIf.h
SET(Calyp_Lib_HEADERS CalypFrame.h CalypStream.h CalypOptions.h CalypModuleIf.h)
INCLUDE(CMakePackageConfigHelpers)
CONFIGURE_PACKAGE_CONFIG_FILE(CalypConfig.cmake.in CalypConfig.cmake INSTALL_DESTINATION share/calyp)
WRITE_BASIC_PACKAGE_VERSION_FILE(
CalypConfigVersion.cmake
VERSION ${CALYP_VERSION}
COMPATIBILITY SameMajorVersion
)
CONFIGURE_FILE( CalypConfig.cmake.in CalypConfig.cmake @ONLY)
# CONFIGURE_FILE(CalypConfig.cmake.in CalypConfig.cmake @ONLY)
INCLUDE_DIRECTORIES( ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} )
IF( USE_STATIC )
ADD_LIBRARY( ${PROJECT_LIBRARY} STATIC ${Calyp_Lib_SRCS} )
IF(USE_STATIC)
ADD_LIBRARY(${PROJECT_LIBRARY} STATIC ${Calyp_Lib_SRCS})
ELSE()
ADD_LIBRARY( ${PROJECT_LIBRARY} SHARED ${Calyp_Lib_SRCS} )
ADD_LIBRARY(${PROJECT_LIBRARY} SHARED ${Calyp_Lib_SRCS})
ENDIF()
TARGET_LINK_LIBRARIES(${PROJECT_LIBRARY} ${CALYP_LIB_LINKER_DEPENDENCIES})
# TARGET_INCLUDE_DIRECTORIES(${PROJECT_LIBRARY} PUBLIC $<INSTALL_INTERFACE:include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
SET_TARGET_PROPERTIES(${PROJECT_LIBRARY} PROPERTIES VERSION ${CALYP_VERSION} SOVERSION ${CALYP_VERSION_MAJOR})
TARGET_LINK_LIBRARIES( ${PROJECT_LIBRARY}
${FFMPEG_LIBRARIES}
${OpenCV_LIBRARIES}
)
IF(USE_IWYU)
SET_PROPERTY(TARGET ${PROJECT_LIBRARY} PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path})
ENDIF()
TARGET_INCLUDE_DIRECTORIES(${PROJECT_LIBRARY}
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
)
EXPORT(TARGETS ${PROJECT_LIBRARY} FILE ${CMAKE_CURRENT_BINARY_DIR}/CalypTargets.cmake)
EXPORT(PACKAGE ${PROJECT_LIBRARY})
SET_TARGET_PROPERTIES( ${PROJECT_LIBRARY}
PROPERTIES VERSION ${CALYP_VERSION}
SOVERSION ${CALYP_VERSION_MAJOR}
)
IF( NOT USE_STATIC )
INSTALL( TARGETS ${PROJECT_LIBRARY}
IF(NOT USE_STATIC)
INSTALL(
TARGETS ${PROJECT_LIBRARY}
EXPORT "${PROJECT_LIBRARY}Targets"
RUNTIME DESTINATION bin
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
INSTALL(FILES ${Calyp_Lib_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" )
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/CalypConfig.cmake DESTINATION share/calyp )
INSTALL(FILES ${Calyp_Lib_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/CalypConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/CalypConfigVersion.cmake DESTINATION share/calyp)
INSTALL(EXPORT CalypTargets DESTINATION share/calyp)
ENDIF()
IF( BUILD_TESTS )
ADD_SUBDIRECTORY( tests )
IF(BUILD_TESTS)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(catch2)
ENDIF()
+9 -6
View File
@@ -12,7 +12,7 @@
#
#
# This file will define the following variables:
# - CALYP_LINKER_LIBS : The list of all imported targets for OpenCV modules.
# - CALYP_LIBRARIES : The list of all imported targets for OpenCV modules.
# - CALYP_CXX_FLAGS
# - CALYP_INCLUDE_DIRS : The Calyp include directories.
# - CALYP_VERSION : The version of this Calyp build: "@CALYP_VERSION@"
@@ -22,15 +22,18 @@
#
# ===================================================================================================================
@PACKAGE_INIT@
# ======================================================
# Variables:
# ======================================================
SET(CALYP_VERSION @CALYP_VERSION@)
SET(CALYP_VERSION_MAJOR @CALYP_VERSION_MAJOR@)
SET(CALYP_VERSION_MINOR @CALYP_VERSION_MINOR@)
SET(CALYP_VERSION_PATCH @CALYP_VERSION_PATCH@)
FIND_LIBRARY(CALYP_LIBRARY NAMES Calyp HINTS @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ )
SET( CALYP_CXX_FLAGS "" )
SET( CALYP_INCLUDE_DIRS "@CMAKE_CFG_INCLUDE_DIRS@" )
SET( CALYP_LINKER_LIBS "@CMAKE_CFG_LINKER_LIBSS@" )
SET( CALYP_LIBRARIES "${CALYP_LIBRARY}" )
LIST( APPEND CALYP_LIBRARIES "@CALYP_LIB_LINKER_DEPENDENCIES@")
set_and_check( CALYP_INCLUDE_DIRS "@CMAKE_CFG_INCLUDE_DIRS@" )
CHECK_REQUIRED_COMPONENTS(Calyp)
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff. Show more