Showing preview only (1,340K chars total). Download the full file or copy to clipboard to get everything.
Repository: YomikoR/VapourSynth-Editor
Branch: vs-api4
Commit: 9c2237c720dc
Files: 200
Total size: 1.2 MB
Directory structure:
gitextract_u1yk7l4b/
├── .gitignore
├── BUILDING
├── CHANGELOG
├── LICENSE
├── README
├── TODO.txt
├── common-src/
│ ├── application_instance_file_guard/
│ │ ├── application_instance_file_guard.cpp
│ │ └── application_instance_file_guard.h
│ ├── chrono.h
│ ├── frame_header_writers/
│ │ ├── frame_header_writer.cpp
│ │ ├── frame_header_writer.h
│ │ ├── frame_header_writer_null.cpp
│ │ ├── frame_header_writer_null.h
│ │ ├── frame_header_writer_y4m.cpp
│ │ └── frame_header_writer_y4m.h
│ ├── helpers.cpp
│ ├── helpers.h
│ ├── helpers_vs.h
│ ├── ipc_defines.h
│ ├── jobs/
│ │ ├── job.cpp
│ │ ├── job.h
│ │ ├── job_variables.cpp
│ │ └── job_variables.h
│ ├── libp2p/
│ │ ├── COPYING
│ │ ├── README.md
│ │ ├── p2p.h
│ │ ├── p2p_api.cpp
│ │ ├── p2p_api.h
│ │ ├── simd/
│ │ │ ├── cpuinfo_x86.cpp
│ │ │ ├── cpuinfo_x86.h
│ │ │ ├── p2p_simd.cpp
│ │ │ ├── p2p_simd.h
│ │ │ └── p2p_sse41.cpp
│ │ └── v210.cpp
│ ├── log/
│ │ ├── log_styles_model.cpp
│ │ ├── log_styles_model.h
│ │ ├── styled_log_view.cpp
│ │ ├── styled_log_view.h
│ │ ├── styled_log_view_core.cpp
│ │ ├── styled_log_view_core.h
│ │ ├── styled_log_view_settings_dialog.cpp
│ │ ├── styled_log_view_settings_dialog.h
│ │ ├── styled_log_view_settings_dialog.ui
│ │ ├── styled_log_view_structures.cpp
│ │ ├── styled_log_view_structures.h
│ │ ├── vs_editor_log.cpp
│ │ ├── vs_editor_log.h
│ │ ├── vs_editor_log_definitions.cpp
│ │ └── vs_editor_log_definitions.h
│ ├── settings/
│ │ ├── settings_definitions.cpp
│ │ ├── settings_definitions.h
│ │ ├── settings_definitions_core.cpp
│ │ ├── settings_definitions_core.h
│ │ ├── settings_manager.cpp
│ │ ├── settings_manager.h
│ │ ├── settings_manager_core.cpp
│ │ └── settings_manager_core.h
│ ├── timeline_slider/
│ │ ├── timeline_slider.cpp
│ │ └── timeline_slider.h
│ ├── vapoursynth/
│ │ ├── vapoursynth_script_processor.cpp
│ │ ├── vapoursynth_script_processor.h
│ │ ├── vs_pack_rgb.cpp
│ │ ├── vs_pack_rgb.h
│ │ ├── vs_script_library.cpp
│ │ ├── vs_script_library.h
│ │ ├── vs_script_processor_structures.cpp
│ │ ├── vs_script_processor_structures.h
│ │ ├── vs_set_matrix.cpp
│ │ └── vs_set_matrix.h
│ ├── version_info.cpp
│ ├── version_info.h
│ ├── win32_console.cpp
│ └── win32_console.h
├── msvc/
│ ├── VapourSynthEditor.sln
│ ├── VapourSynthEditor.vcxproj
│ ├── VapourSynthEditor.vcxproj.filters
│ ├── libp2p/
│ │ ├── libp2p.vcxproj
│ │ └── libp2p.vcxproj.filters
│ ├── vsedit/
│ │ ├── resource.h
│ │ ├── vsedit.rc
│ │ ├── vsedit.vcxproj
│ │ └── vsedit.vcxproj.filters
│ ├── vsedit-encode/
│ │ ├── resource.h
│ │ ├── vsedit-encode.rc
│ │ ├── vsedit-encode.vcxproj
│ │ └── vsedit-encode.vcxproj.filters
│ ├── vsedit-job-server/
│ │ ├── resource.h
│ │ ├── vsedit-job-server.rc
│ │ ├── vsedit-job-server.vcxproj
│ │ └── vsedit-job-server.vcxproj.filters
│ ├── vsedit-job-server-watcher/
│ │ ├── resource.h
│ │ ├── vsedit-job-server-watcher.rc
│ │ ├── vsedit-job-server-watcher.vcxproj
│ │ └── vsedit-job-server-watcher.vcxproj.filters
│ └── vsedit-previewer/
│ ├── resource.h
│ ├── vsedit-previewer.rc
│ ├── vsedit-previewer.vcxproj
│ └── vsedit-previewer.vcxproj.filters
├── pro/
│ ├── build-inno-setup.iss
│ ├── build-msvc.bat
│ ├── common.pri
│ ├── pro.pro
│ ├── vsedit/
│ │ └── vsedit.pro
│ ├── vsedit-encode/
│ │ └── vsedit-encode.pro
│ ├── vsedit-job-server/
│ │ └── vsedit-job-server.pro
│ ├── vsedit-job-server-watcher/
│ │ └── vsedit-job-server-watcher.pro
│ └── vsedit-previewer/
│ └── vsedit-previewer.pro
├── resources/
│ ├── dark/
│ │ ├── LICENSE.rst
│ │ ├── rc/
│ │ │ └── .keep
│ │ ├── style.qrc
│ │ └── style.qss
│ ├── vsedit-job-server-watcher.qrc
│ ├── vsedit.icns
│ └── vsedit.qrc
├── vsedit/
│ └── src/
│ ├── frame_consumers/
│ │ ├── benchmark_dialog.cpp
│ │ ├── benchmark_dialog.h
│ │ ├── benchmark_dialog.ui
│ │ ├── encode_dialog.cpp
│ │ ├── encode_dialog.h
│ │ └── encode_dialog.ui
│ ├── job_server_watcher_socket.cpp
│ ├── job_server_watcher_socket.h
│ ├── main.cpp
│ ├── main_window.cpp
│ ├── main_window.h
│ ├── main_window.ui
│ ├── preview/
│ │ ├── preview_advanced_settings_dialog.cpp
│ │ ├── preview_advanced_settings_dialog.h
│ │ ├── preview_advanced_settings_dialog.ui
│ │ ├── preview_area.cpp
│ │ ├── preview_area.h
│ │ ├── preview_dialog.cpp
│ │ ├── preview_dialog.h
│ │ ├── preview_dialog.ui
│ │ ├── scroll_navigator.cpp
│ │ ├── scroll_navigator.h
│ │ ├── zoom_ratio_spinbox.cpp
│ │ └── zoom_ratio_spinbox.h
│ ├── script_editor/
│ │ ├── number_matcher.cpp
│ │ ├── number_matcher.h
│ │ ├── script_completer.cpp
│ │ ├── script_completer.h
│ │ ├── script_completer_model.cpp
│ │ ├── script_completer_model.h
│ │ ├── script_editor.cpp
│ │ ├── script_editor.h
│ │ ├── syntax_highlighter.cpp
│ │ └── syntax_highlighter.h
│ ├── script_status_bar_widget/
│ │ ├── script_status_bar_widget.cpp
│ │ ├── script_status_bar_widget.h
│ │ └── script_status_bar_widget.ui
│ ├── script_templates/
│ │ ├── drop_file_category_model.cpp
│ │ ├── drop_file_category_model.h
│ │ ├── templates_dialog.cpp
│ │ ├── templates_dialog.h
│ │ └── templates_dialog.ui
│ ├── settings/
│ │ ├── actions_hotkey_edit_model.cpp
│ │ ├── actions_hotkey_edit_model.h
│ │ ├── clearable_key_sequence_editor.cpp
│ │ ├── clearable_key_sequence_editor.h
│ │ ├── item_delegate_for_hotkey.cpp
│ │ ├── item_delegate_for_hotkey.h
│ │ ├── settings_dialog.cpp
│ │ ├── settings_dialog.h
│ │ ├── settings_dialog.ui
│ │ ├── theme_elements_model.cpp
│ │ └── theme_elements_model.h
│ ├── vapoursynth/
│ │ ├── vapoursynth_plugins_manager.cpp
│ │ ├── vapoursynth_plugins_manager.h
│ │ ├── vs_plugin_data.cpp
│ │ ├── vs_plugin_data.h
│ │ ├── vs_script_processor_dialog.cpp
│ │ └── vs_script_processor_dialog.h
│ ├── vsedit_encode_main.cpp
│ └── vsedit_previewer_main.cpp
├── vsedit-job-server/
│ └── src/
│ ├── job_server.cpp
│ ├── job_server.h
│ ├── jobs/
│ │ ├── job_definitions.h
│ │ ├── jobs_manager.cpp
│ │ └── jobs_manager.h
│ └── main.cpp
└── vsedit-job-server-watcher/
└── src/
├── connect_to_server_dialog.cpp
├── connect_to_server_dialog.h
├── connect_to_server_dialog.ui
├── jobs/
│ ├── job_dependencies_delegate.cpp
│ ├── job_dependencies_delegate.h
│ ├── job_edit_dialog.cpp
│ ├── job_edit_dialog.h
│ ├── job_edit_dialog.ui
│ ├── job_state_delegate.cpp
│ ├── job_state_delegate.h
│ ├── jobs_model.cpp
│ └── jobs_model.h
├── main.cpp
├── main_window.cpp
├── main_window.h
├── main_window.ui
├── trusted_clients_addresses_dialog.cpp
├── trusted_clients_addresses_dialog.h
└── trusted_clients_addresses_dialog.ui
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
!/.gitignore
!*.pro
!*.pri
!*.bat
!/common-src/
!/vsedit/src/
!/vsedit-job-server/src/
!/vsedit-job-server-watcher/src/
!/resources/
!/BUILDING
!/CHANGELOG
!/LICENSE
!/README
!/TODO.txt
!/msvc/vsedit/vsedit.rc
!/msvc/vsedit/resource.h
!/msvc/vsedit-previewer/vsedit-previewer.rc
!/msvc/vsedit-previewer/resource.h
!/msvc/vsedit-job-server/vsedit-job-server.rc
!/msvc/vsedit-job-server/resource.h
!/msvc/vsedit-job-server-watcher/vsedit-job-server-watcher.rc
!/msvc/vsedit-job-server-watcher/resource.h
build
pro/*/*.rc
pro/*/Makefile.Release
pro/*/Makefile.Debug
pro/*/Makefile
pro/*/*.cpp
pro/dist
pro/.qmake.stash
pro/Makefile
pro/local_quirks.pri
**/generated
**/Release
**/Debug
msvc/**/*.aps
*.d
*.slo
*.lo
*.o
*.obj
*.gch
*.pch
*.so
*.dylib
*.dll
*.mod
*.smod
*.lai
*.la
*.a
*.lib
*.exe
*.out
*.app
*/.vs
*.vcxproj.user
*.log
*.props
================================================
FILE: BUILDING
================================================
THIS MANUAL IS A DRAFT. PLEASE REPORT ANY MISTAKES OR ADDITIONS AT https://github.com/YomikoR/VapourSynth-Editor/issues
## Prerequisites
You need C++17 (or higher) compiler and Qt 6 development distribution.
In Ubuntu 22.04 LTS, for example, the packages qt6-base-dev and libqt6websockets6-dev are required.
## Building VapourSynth Editor from source:
1) make sure you meet the above prerequisites;
2) open the system terminal and change working directory to the "pro" directory in the source tree;
3) (optional) set environment variable `VS_INCLUDE_PATH` for the include path of VapourSynth header files, e.g. for Windows CMD
```CMD
FOR /F "USEBACKQ tokens=*" %I IN (`python -c "import vapoursynth;print(vapoursynth.get_include())"`) DO (SET VS_INCLUDE_PATH=%I)
```
and for *nix
```shell
export VS_INCLUDE_PATH=`/usr/bin/env python3 -c "import vapoursynth;print(vapoursynth.get_include())"`
```
4) execute following command to generate the Makefile and other intermediate files
`qmake6 -norecursive pro.pro CONFIG+=release`
5) "make" the Makefile with platform specific make-tool, e.g. `nmake` for MS Visual Studio.
The program files will be built in compiler specific sub-directory in the "build" directory in source tree and ready to use.
If you encounter path issues during the building related to missing headers, etc., you may include them in the file "pro/local_quirks.pri".
Below are some tested compilers:
Windows MSVC
Linux GCC
MacOS clang (within brew)
================================================
FILE: CHANGELOG
================================================
r19-mod-6.10
-BUGFIX: Cannot load old vsscript from list due to change on the file name.
r19-mod-6.9
-BUGFIX: Aborting dead process in job server watcher causes ghost entry.
-Add match/case keywords to text editor highlighting (chrschmidt).
-Make "Home" toggle between the block start and the first column (chrschmidt).
-Disable color filling in the progress bars of job server watcher.
-Add display support for _Range frame property since VS R73.
-Search for vsscript library in environments since VS R74.
-Switch to Qt6 regex functions.
r19-mod-6.8
-BUGFIX: Switching output index could fail after immediate playback.
-Add hotkey options for switching to previous or next output index.
-Add standalone console launcher for encode panel.
r19-mod-6.7
-BUGFIX: Messages sent by core logging are missing after preview refresh.
-Add combo box for switching output index (enabled with VS R69 or later).
r19-mod-6.6
-BUGFIX: Previewer does not launch.
-Allow all VS versions with API4.
-Remove option that reloads script from disk before evaluation.
-Add option to periodically reload script from disk to sync with external changes.
-Add an asterisk in preview window title that indicates change in text editor.
-Add info texts to certain reserved frame props when displayed.
-Improve error handling of the previewer.
-Better sync output frame numbers by timestamp.
r19-mod-6.5
-Use same vapoursynth library as used for script evaluation for plugin list.
r19-mod-6.4
-BUGFIX: Filter logs are not shown before script is evaluated.
-BUGFIX: VS messages sent from core are duplicated.
-BUGFIX: Each frame from script is requested twice (no influence in performance).
-BUGFIX: Loading vsscript library from VS R66 portable directory fails.
-BUGFIX: output nodes #10-#19 are not properly cleared.
Add audio playback (Windows only).
Add options to set output syncing mode.
Add core cache usage data in status bar.
2020_CL option is removed from preview advanced settings.
r19-mod-6.3
-BUGFIX: On Linux the previewer refuses to quit.
-In Windows 10 and later console window can show colored text (with ANSI escape sequences).
-Add option to hide (VS and Qt) debug messages.
-Add option to set dither type.
-Show _AbsoluteTime frame props on title of preview panel.
-Do not load chapter for VFR clips.
-Add hotkey in preview panel for jumping to frame by frame number.
r19-mod-6.2
-BUGFIX: Encoding CLI won't start in Linux.
-BUGFIX: Script is not loaded when file path encoding is not UTF-8.
-VSEditor is a GUI app again with an option to toggle console window.
-Adapt to Windows dark theme.
-Offer qdarkstyle theme for all platforms.
r19-mod-6.1
-BUGFIX: Memory leak when closing preview window (regression from mod-6).
-Support switching to output indices 10-19.
-Add a standalone preview panel launcher, i.e. a script previewer.
r19-mod-6
-Drop Qt 5 support.
-Switch to VapourSynth API4 (won't work with API3 VSScript libraries).
-Add support for previewing video nodes with variational format or dimensions.
r19-mod-5.6
-BUGFIX: Chroma location parameter ignored when resampling to RGB for preview.
-A panel is added for displaying frame properties.
r19-mod-5.5
-BUGFIX: Wrong dimensions in cropping when there are multiple video outputs.
-Binaries are now working as console applications (instead of GUI apps) in Windows.
-Binaries print version in Windows if the console is not automatically hidden on start.
-A shortcut launching VSEditor in CMD is added to the installer.
-Unused doc path options are removed.
-Added an option to prefer loading VS libs from settings (other than Windows registry or sys PATH).
r19-mod-5.4
-BUGFIX: Reject problematic output nodes with invalid format.
-Binaries print version and exit with -v or --version.
r19-mod-5.3
-BUGFIX: Flickering in playback due to a regression introduced with the dark theme.
-BUGFIX: Image doesn't align to the top-left corner of the preview window in dark theme.
-BUGFIX: Bright and dark themes were using the same setting groups.
-BUGFIX: Image distortion with large zoom ratio.
-Any change of switching between bright and dark themes will only take effect on program relaunching.
-Modified zoom ratio step lengths when using fixed ratio.
r19-mod-5.2
-BUGFIX: VapourSynth lib searching not working in Qt6 on Windows. (SaltyChiang)
-BUGFIX: Certain UI fonts look horrible in Qt6 on Windows with kerning enabled.
-BUGFIX: Cursor pixelation in color panel in HIDPI.
-BUGFIX: Wrong pipette info when cropping.
-BUGFIX: Drop file template panel crashing when empty.
-BUGFIX: Incorrect scroll navigator ratio in HIDPI.
-Add dark theme (Windows only).
-Introduce snapshot template with a silent mode (in preview advanced settings).
-Slightly enlarged timeline bar.
-Show "Name" and "SceneName" frame properties on window title.
-Show Qt version in About menu.
-Color and font settings will be saved only when differing from default values.
r19-mod-5
-BUGFIX: Building fails in Ubuntu LTS with older Qt versions.
-BUGFIX: A blank .config file may be mistakenly created.
-BUGFIX: Benchmark window doesn't normally stop and exit when pressing Escape.
-Adapt to internal resizer changes since VS R58.
-Support building with Qt 6 (with certain progress bar features disabled).
-Enable HIDPI support (only with Qt 6).
-Let playback rate respect frame durations (i.e. VFR).
-Let inno installer work with Windows 7 SP1 and later.
-Add .vpy file association in the inno installer.
-Rename chroma location options by their position names and remove DV.
-Set default chroma subsampling method to Bicubic b=0 c=0.5.
-Let GRAY clip with RGB matrix be previewed as usual.
-Edit program descriptions.
-Don't search Program Files by path for finding vsscript.
-Default hotkeys for zoom modes changed from 1/2/3 to Alt + 1/2/3.
-When previewing, switch output nodes 0-9 by hotkeys 0-9.
r19-mod-4:
-BUGFIX: Encode preset header not correctly loaded.
-BUGFIX: Loading chapters for VFR video results in division by zero.
-BUGFIX: Failure when building in a recent version of MacOS.
-BUGFIX: Program crashes when launching from second screen in MacOS with Qt 5.12.
-BUGFIX: Only the main screen's bit depth is reported.
-BUGFIX: Settings are lost in current session when switching to portable mode while config file is not writable.
-Add Inno build script for a Windows installer (by rlaphoenix).
-Add a setting entry for reloading script from disk before execution.
-Improve open-box experience of the text editor: using spaces as tabs, 12pt font size, adjusted colors for dark themes.
-Raise minimum VapourSynth version requirement to R47 (API 3.6).
-Remove a number of obsolete Qt methods (raising Qt version requirement to 5.8).
-Frame numbers computed from chapter timestamps are rounded instead of ceiling.
-"Shell commands" in job server won't be executed with cmd /c or sh -c prefix anymore.
r19-mod-3:
-BUGFIX: Crash on file drop setting menu.
-BUGFIX: Black screen for 10-bit preview.
-Add back support for YCOCG and COMPAT colorspaces.
-Show cursur position and on screen RGB values with color panel.
-Add a setting entry for snapshot compression level.
r19-mod-2:
-Improve performance for RGB format packing (thanks to DJATOM and sekrit-twc).
r19-mod-1:
-Drop support for YCOCG and COMPAT colorspaces.
-Work with VapourSynth v4 API (built with v3).
-Dither to RGB for preview output.
-Preview in 10-bit color depth in Unix when allowed.
-Compress PNG file size when saving snapshots.
-Replace legacy get_core() from the template.
r19:
-BUGFIX: Rapid settings updating on windows geometry change.
-BUGFIX: Theme settings corruption when using job server.
-Color picker update with a still mouse cursor in play mode.
-Benchmark dialog remembers first and last frame for current script.
r18:
-BUGFIX: Crash on encode dialog initialization error.
-BUGFIX: No error in log on encode dialog initialization error.
-Import chapter files as preview bookmarks (by brainvlad@gmail.com).
r17:
-BUGFIX: Blank preview on variable size video with fixed zoom ratio.
-BUGFIX: Saving new script.
-BUGFIX: Invalid context menu for editor.
-BUGFIX: Context menu behavior in preview.
-New multi-app architecture: editor, job server, server watcher.
r16:
-BUGFIX: Default hotkey forced when trying to save an empty hotkey.
-BUGFIX: Inactive actions in the log context menu.
-Jobs queue with dependencies tracking.
-Adjustable jobs table.
-Pausable CLI encoding jobs.
-Pausable process run jobs.
-Shell command execute jobs.
-Removed framebuffer monitoring.
-Move text block up action.
-Move text block down action.
-Toggle comment action.
-Fixed VS API version requested for internal plugins polling.
-Larger settings dialog to remove the warning.
r15:
-BUGFIX: crash on colour picking while refreshing preview.
-BUGFIX: random junk instead of black frame on preview refresh.
-BUGFIX: wrong hours displayed in estimated finish time for benchmark and encoding.
-Buildable with Qt version lower than 5.4.
-Float formats support in yuv4mpeg video header for encoding.
r14:
-BUGFIX: Encoding logic.
-Core buffer usage display.
-Relative paths are resolved from the application directory, not CWD.
-Benchmark and encoding progress in window title.
-MS Windows: taskbar button progress for benchmark and encoding.
-Script dialogs status bar reorganized.
-WebP snapshots support.
r13:
-yuv4mpeg header for video encoding.
r12:
-Improved log.
-Crash log is saved as HTML from the main log.
r11:
-BUGFIX: Default file drop template.
-BUGFIX: Preview non-YUV clips.
-An option to keep the currently previewed frame number on previewing different script.
r10:
-BUGFIX: Colour picking.
-BUGFIX: VapourSynth messages handling.
-BUGFIX: Frame processing errors handling in different modes.
-BUGFIX: Pasting crop snippet into the last script line.
-BUGFIX: Benchmark and encode dialogs forward initialization error to main window log and hide on error if open.
-Crashlog on VapourSynth fatal errors.
-Keep preview scrolling and frame number on refreshing the same script.
Reset on previewing new script. Unsaved script preview is always reset.
-Editor: selected text/current line duplication action.
-Editor: comment/uncomment selected lines actions.
-Editor: multiline tab and backtab.
-Options to use spaces as Tab and set Tab size.
-Editor: Replace Tab characters with spaces action.
-Editor: smart Home key behaviour.
-An option to remember and restore the last previewed frame between sessions.
-New script template setting.
-Code snippets.
-File drop templates.
-Option to highlight selection matches in script editor.
-Timeline bookmarks with auto-saving/loading bookmarks file along the script file.
-Remember timeline panel visibility.
-Most timeline colours are bound to OS theme.
-Changes in default standard hotkeys. Many default hotkeys are now OS-dependent. CTRL + arrows in preview window now move between bookmarks and CTRL + SHIFT + arrows jump time intervals.
-Frames number and subsampling string tokens in encoder.
-Estimated finish time output in benchmark and encoder.
-Encoder argument tokens format changed into more readable one.
-Colour picker moved into status bar.
-Paste shown frame number into script action.
r⑨:
-Asynchronous frames processing. More responsive GUI.
-Preview video playback.
-Script processing benchmarking.
-Encoding video with CLI tools.
r8:
-BUGFIX: Preview stride.
r7:
-BUGFIX: Bt.601 YUV to RGB conversion matrix. Not sure if it works correctly, but it works.
-BUGFIX: Massive memory leak.
-Late linking to vsscript library. Can start with no VapourSynth installed.
-Better detection of VapourSynth installation on Windows.
-Experimental colour picker. Shows values under cursor in preview window. Not thoroughly tested.
r6:
-Added some theme settings.
-Switched preview to use the internal resizer instead of zimg. Requires VapourSynth R29+.
-Support for building under MacOS X (not tested).
r5:
Fix release.
-Fixed compatibility with VapourSynth r27. Patch by Myrsloik.
-Fixed "Copy frame to clipboard" action.
r4:
-Custom font is embedded.
-Internal format conversion for preview. All VapourSynth video formats are now supported.
r3:
-Fixed zoom ratio changed to real number.
-New line autoindentation.
r2:
-File paths are changed to canonical before adding to recent files list to eliminate doubling records.
-Change window title when script path changes.
-Always create new script on start before trying to open any.
================================================
FILE: LICENSE
================================================
Copyright (c) 2014 - 2017 Aleksey [Mystery Keeper] Lyashin
mystkeeper@gmail.com
Copyright (c) 2022 - 2026 YomikoR
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README
================================================
VapourSynth Editor r19-mod-6.10
By Aleksey [Mystery Keeper] Lyashin
mystkeeper@gmail.com
http://mysterykeeper.ru
Modified by YomikoR
This software is free and distributed under MIT license.
Software uses Qt framework by The Qt Company, distributed under LGPL license.
https://qt.io/
Software includes Silk icons v1.3 by Mark James,
distributed under Creative Commons Attribution 2.5 License.
http://www.famfamfam.com/lab/icons/silk/
Software includes FatCow free icons,
distributed under Creative Commons Attribution 3.0 License.
http://www.fatcow.com/free-icons
Software includes QDarkStyleSheet v3.0.3,
distributed under MIT License for code,
and Creative Commons Attribution 4.0 International License for images.
https://github.com/ColinDuquesnoy/QDarkStyleSheet
For additional information see LICENSE file.
================================================
FILE: TODO.txt
================================================
- search and replace text
- choose the default vsscript library load path
- insert formatted data from preview window into script
- functions autocompletion refinement
- python error parsing and script line highlighting
- multiple output nodes comparison
- reference and documentation
================================================
FILE: common-src/application_instance_file_guard/application_instance_file_guard.cpp
================================================
#include "application_instance_file_guard.h"
#include <QObject>
#include <QStandardPaths>
#ifndef Q_OS_WIN
#include <sys/file.h>
#endif
//==============================================================================
ApplicationInstanceFileGuard::ApplicationInstanceFileGuard(
const QString & a_fileName)
{
m_tempDir =
QStandardPaths::writableLocation(QStandardPaths::TempLocation);
if(!a_fileName.isEmpty())
lock(a_fileName);
}
//==============================================================================
ApplicationInstanceFileGuard::~ApplicationInstanceFileGuard()
{
if(m_file.isOpen())
unlock();
}
//==============================================================================
bool ApplicationInstanceFileGuard::lock(const QString & a_fileName)
{
if(m_file.isOpen())
{
if(a_fileName == m_fileName)
return true;
bool unlocked = unlock();
if(!unlocked)
return false;
}
QString filePath = m_tempDir + "/" + a_fileName;
#ifdef Q_OS_WIN
if(QFile::exists(filePath))
{
bool deleted = QFile::remove(filePath);
if(!deleted)
{
m_error = QObject::tr("Could not delete file %1")
.arg(filePath);
return false;
}
}
#endif
m_fileName = a_fileName;
m_file.setFileName(filePath);
bool opened = m_file.open(QIODevice::ReadWrite);
if(!opened)
{
m_error = QObject::tr("Could not open file %1").arg(filePath);
return false;
}
#ifndef Q_OS_WIN
int result = flock(m_file.handle(), LOCK_EX | LOCK_NB);
if(result != 0)
{
m_error = QObject::tr("Could not lock file %1").arg(filePath);
m_file.close();
return false;
}
#endif
return true;
}
//==============================================================================
bool ApplicationInstanceFileGuard::unlock()
{
if(m_file.isOpen())
{
#ifndef Q_OS_WIN
flock(m_file.handle(), LOCK_UN | LOCK_NB);
#endif
m_file.close();
}
QString filePath = m_file.fileName();
if(filePath.isEmpty())
{
m_error = QObject::tr("File name is empty.");
return false;
}
if(!QFile::exists(filePath))
return true;
bool deleted = QFile::remove(filePath);
if(!deleted)
m_error = QObject::tr("Could not delete file %1").arg(filePath);
return deleted;
}
//==============================================================================
bool ApplicationInstanceFileGuard::isLocked() const
{
return m_file.isOpen();
}
//==============================================================================
QString ApplicationInstanceFileGuard::error() const
{
return m_error;
}
//==============================================================================
================================================
FILE: common-src/application_instance_file_guard/application_instance_file_guard.h
================================================
#ifndef APPLICATION_INSTANCE_FILE_GUARD_H_INCLUDED
#define APPLICATION_INSTANCE_FILE_GUARD_H_INCLUDED
#include <QString>
#include <QFile>
class ApplicationInstanceFileGuard
{
public:
ApplicationInstanceFileGuard(const QString & a_fileName = QString());
virtual ~ApplicationInstanceFileGuard();
bool lock(const QString & a_fileName);
bool unlock();
bool isLocked() const;
QString error() const;
private:
QFile m_file;
QString m_error;
QString m_fileName;
QString m_tempDir;
};
#endif // APPLICATION_INSTANCE_FILE_GUARD_H_INCLUDED
================================================
FILE: common-src/chrono.h
================================================
#ifndef CHRONO_H_INCLUDED
#define CHRONO_H_INCLUDED
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point hr_time_point;
typedef std::chrono::high_resolution_clock hr_clock;
typedef std::chrono::duration<double, std::ratio<1, 1> > double_duration;
template <typename T> double duration_to_double(const T & a_duration)
{
return std::chrono::duration_cast<double_duration>(a_duration).count();
}
#endif // CHRONO_H_INCLUDED
================================================
FILE: common-src/frame_header_writers/frame_header_writer.cpp
================================================
#include "frame_header_writer.h"
//==============================================================================
FrameHeaderWriter::FrameHeaderWriter(const VSAPI * a_cpVSAPI,
const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent) :
QObject(a_pParent)
, m_cpVSAPI(a_cpVSAPI)
, m_cpVideoInfo(a_cpVideoInfo)
{
}
// END OF FrameHeaderWriter::FrameHeaderWriter(const VSAPI * a_cpVSAPI,
// const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent)
//==============================================================================
FrameHeaderWriter::~FrameHeaderWriter()
{
}
// END OF FrameHeaderWriter::~FrameHeaderWriter()
//==============================================================================
void FrameHeaderWriter::setVSAPI(const VSAPI * a_cpVSAPI)
{
m_cpVSAPI = a_cpVSAPI;
}
// END OF void FrameHeaderWriter::setVSAPI(const VSAPI * a_cpVSAPI)
//==============================================================================
void FrameHeaderWriter::setVideoInfo(const VSVideoInfo * a_cpVideoInfo)
{
m_cpVideoInfo = a_cpVideoInfo;
}
// END OF void FrameHeaderWriter::setVideoInfo(
// const VSVideoInfo * a_cpVideoInfo)
//==============================================================================
================================================
FILE: common-src/frame_header_writers/frame_header_writer.h
================================================
#ifndef FRAME_HEADER_WRITER_H_INCLUDED
#define FRAME_HEADER_WRITER_H_INCLUDED
#include <VapourSynth4.h>
#include <QObject>
class FrameHeaderWriter : public QObject
{
Q_OBJECT
public:
FrameHeaderWriter(const VSAPI * a_cpVSAPI = nullptr,
const VSVideoInfo * a_cpVideoInfo = nullptr,
QObject * a_pParent = nullptr);
virtual ~FrameHeaderWriter();
virtual void setVSAPI(const VSAPI * a_cpVSAPI);
virtual void setVideoInfo(const VSVideoInfo * a_cpVideoInfo);
virtual bool isCompatible() = 0;
virtual bool needVideoHeader() = 0;
virtual QByteArray videoHeader(int a_totalFrames = -1) = 0;
virtual bool needFramePrefix() = 0;
virtual QByteArray framePrefix(const VSFrame * a_cpFrame) = 0;
virtual bool needFramePostfix() = 0;
virtual QByteArray framePostfix(const VSFrame * a_cpFrame) = 0;
protected:
const VSAPI * m_cpVSAPI;
const VSVideoInfo * m_cpVideoInfo;
};
#endif // FRAME_HEADER_WRITER_H_INCLUDED
================================================
FILE: common-src/frame_header_writers/frame_header_writer_null.cpp
================================================
#include "frame_header_writer_null.h"
//==============================================================================
FrameHeaderWriterNull::FrameHeaderWriterNull(const VSAPI * a_cpVSAPI,
const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent) :
FrameHeaderWriter(a_cpVSAPI, a_cpVideoInfo, a_pParent)
{
}
// END OF FrameHeaderWriterNull::FrameHeaderWriterNull(const VSAPI * a_cpVSAPI,
// const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent)
//==============================================================================
bool FrameHeaderWriterNull::isCompatible()
{
Q_ASSERT(m_cpVideoInfo);
if(!m_cpVideoInfo)
return false;
return true;
}
// END OF bool FrameHeaderWriterNull::isCompatible()
//==============================================================================
bool FrameHeaderWriterNull::needVideoHeader()
{
return false;
}
// END OF bool FrameHeaderWriterNull::needVideoHeader()
//==============================================================================
QByteArray FrameHeaderWriterNull::videoHeader(int a_totalFrames)
{
(void)a_totalFrames;
return QByteArray();
}
// END OF QByteArray FrameHeaderWriterNull::videoHeader(int a_totalFrames)
//==============================================================================
bool FrameHeaderWriterNull::needFramePrefix()
{
return false;
}
// END OF bool FrameHeaderWriterNull::needFramePrefix()
//==============================================================================
QByteArray FrameHeaderWriterNull::framePrefix(const VSFrame * a_cpFrame)
{
(void)a_cpFrame;
return QByteArray();
}
// END OF QByteArray FrameHeaderWriterNull::framePrefix(
// const VSFrame * a_cpFrame)
//==============================================================================
bool FrameHeaderWriterNull::needFramePostfix()
{
return false;
}
// END OF bool FrameHeaderWriterNull::needFramePostfix()
//==============================================================================
QByteArray FrameHeaderWriterNull::framePostfix(const VSFrame * a_cpFrame)
{
(void)a_cpFrame;
return QByteArray();
}
// END OF QByteArray FrameHeaderWriterNull::framePostfix(
// const VSFrame * a_cpFrame)
//==============================================================================
================================================
FILE: common-src/frame_header_writers/frame_header_writer_null.h
================================================
#ifndef FRAME_HEADER_WRITER_NULL_H_INCLUDED
#define FRAME_HEADER_WRITER_NULL_H_INCLUDED
#include "frame_header_writer.h"
class FrameHeaderWriterNull : public FrameHeaderWriter
{
Q_OBJECT
public:
FrameHeaderWriterNull(const VSAPI * a_cpVSAPI = nullptr,
const VSVideoInfo * a_cpVideoInfo = nullptr,
QObject * a_pParent = nullptr);
virtual bool isCompatible() override;
virtual bool needVideoHeader() override;
virtual QByteArray videoHeader(int a_totalFrames = -1) override;
virtual bool needFramePrefix() override;
virtual QByteArray framePrefix(const VSFrame * a_cpFrame) override;
virtual bool needFramePostfix() override;
virtual QByteArray framePostfix(const VSFrame * a_cpFrame) override;
};
#endif // FRAME_HEADER_WRITER_NULL_H_INCLUDED
================================================
FILE: common-src/frame_header_writers/frame_header_writer_y4m.cpp
================================================
#include "frame_header_writer_y4m.h"
#include "../../../common-src/helpers.h"
#include <string>
#include <map>
//==============================================================================
FrameHeaderWriterY4M::FrameHeaderWriterY4M(const VSAPI * a_cpVSAPI,
const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent) :
FrameHeaderWriter(a_cpVSAPI, a_cpVideoInfo, a_pParent)
{
}
// END OF FrameHeaderWriterY4M::FrameHeaderWriterY4M(const VSAPI * a_cpVSAPI,
// const VSVideoInfo * a_cpVideoInfo, QObject * a_pParent)
//==============================================================================
bool FrameHeaderWriterY4M::isCompatible()
{
Q_ASSERT(m_cpVideoInfo);
if(!m_cpVideoInfo)
return false;
const VSVideoFormat * cpFormat = &m_cpVideoInfo->format;
int compatibleColorFamily[] = {cfGray, cfYUV};
if(!vsedit::contains(compatibleColorFamily, cpFormat->colorFamily))
return false;
if(cpFormat->sampleType == stFloat)
{
int acceptableBitDepths[] = {16, 32, 64};
if(!vsedit::contains(acceptableBitDepths, cpFormat->bitsPerSample))
return false;
}
std::pair<int, int> compatibleSubsampling[] =
{{0, 0}, {0, 1}, {1, 0}, {1, 1}, {2, 0}, {2, 2}};
std::pair<int, int> subsampling(cpFormat->subSamplingW,
cpFormat->subSamplingH);
if(!vsedit::contains(compatibleSubsampling, subsampling))
return false;
return true;
}
// END OF bool FrameHeaderWriterY4M::isCompatible()
//==============================================================================
bool FrameHeaderWriterY4M::needVideoHeader()
{
return true;
}
// END OF bool FrameHeaderWriterY4M::needVideoHeader()
//==============================================================================
QByteArray FrameHeaderWriterY4M::videoHeader(int a_totalFrames)
{
Q_ASSERT(m_cpVideoInfo);
Q_ASSERT(isCompatible());
const VSVideoFormat * cpFormat = &m_cpVideoInfo->format;
std::string header;
header += "YUV4MPEG2 C";
if(cpFormat->colorFamily == cfGray)
{
header += "mono";
if(cpFormat->bitsPerSample > 8)
header += std::to_string(cpFormat->bitsPerSample);
}
else if(cpFormat->colorFamily == cfYUV)
{
std::map<std::pair<int, int>, std::string> subsamplingStringMap =
{
{{0, 0}, "444"},
{{0, 1}, "440"},
{{1, 0}, "422"},
{{1, 1}, "420"},
{{2, 0}, "411"},
{{2, 2}, "410"},
};
std::pair<int, int> subsampling(cpFormat->subSamplingW,
cpFormat->subSamplingH);
header += subsamplingStringMap[subsampling];
if((cpFormat->bitsPerSample > 8) && (cpFormat->sampleType == stInteger))
header += "p" + std::to_string(cpFormat->bitsPerSample);
else if(cpFormat->sampleType == stFloat)
{
header += "p";
if(cpFormat->bitsPerSample == 16)
header += "h";
else if(cpFormat->bitsPerSample == 32)
header += "s";
else if(cpFormat->bitsPerSample == 64)
header += "d";
else
{
Q_ASSERT(false);
header += "u";
}
}
}
else
{
Q_ASSERT(false);
}
int totalFrames = (a_totalFrames < 0) ? m_cpVideoInfo->numFrames :
a_totalFrames;
header = header
+ " W" + std::to_string(m_cpVideoInfo->width)
+ " H" + std::to_string(m_cpVideoInfo->height)
+ " F" + std::to_string(m_cpVideoInfo->fpsNum)
+ ":" + std::to_string(m_cpVideoInfo->fpsDen)
+ " Ip A0:0"
+ " XLENGTH=" + std::to_string(totalFrames)
+ "\n";
QByteArray headerData(header.c_str());
return headerData;
}
// END OF QByteArray FrameHeaderWriterY4M::videoHeader(int a_totalFrames)
//==============================================================================
bool FrameHeaderWriterY4M::needFramePrefix()
{
return true;
}
// END OF bool FrameHeaderWriterY4M::needFramePrefix()
//==============================================================================
QByteArray FrameHeaderWriterY4M::framePrefix(const VSFrame * a_cpFrame)
{
(void)a_cpFrame;
std::string prefix = "FRAME\n";
QByteArray prefixData(prefix.c_str());
return prefixData;
}
// END OF QByteArray FrameHeaderWriterY4M::framePrefix(
// const VSFrame * a_cpFrame)
//==============================================================================
bool FrameHeaderWriterY4M::needFramePostfix()
{
return false;
}
// END OF bool FrameHeaderWriterY4M::needFramePostfix()
//==============================================================================
QByteArray FrameHeaderWriterY4M::framePostfix(const VSFrame * a_cpFrame)
{
(void)a_cpFrame;
return QByteArray();
}
// END OF QByteArray FrameHeaderWriterY4M::framePostfix(
// const VSFrame * a_cpFrame)
//==============================================================================
================================================
FILE: common-src/frame_header_writers/frame_header_writer_y4m.h
================================================
#ifndef FRAME_HEADER_WRITER_Y4M_H_INCLUDED
#define FRAME_HEADER_WRITER_Y4M_H_INCLUDED
#include "frame_header_writer.h"
class FrameHeaderWriterY4M : public FrameHeaderWriter
{
Q_OBJECT
public:
FrameHeaderWriterY4M(const VSAPI * a_cpVSAPI = nullptr,
const VSVideoInfo * a_cpVideoInfo = nullptr,
QObject * a_pParent = nullptr);
virtual bool isCompatible() override;
virtual bool needVideoHeader() override;
virtual QByteArray videoHeader(int a_totalFrames = -1) override;
virtual bool needFramePrefix() override;
virtual QByteArray framePrefix(const VSFrame * a_cpFrame) override;
virtual bool needFramePostfix() override;
virtual QByteArray framePostfix(const VSFrame * a_cpFrame) override;
};
#endif // FRAME_HEADER_WRITER_Y4M_H_INCLUDED
================================================
FILE: common-src/helpers.cpp
================================================
#include "helpers.h"
#include <QDir>
#include <QFileInfo>
#include <QCoreApplication>
#include <cmath>
#include <functional>
#include <vector>
/* https://www.ffmpeg.org/ffmpeg-utils.html#Channel-Layout */
static std::map<VSAudioChannels, QString> audioChannelToString =
{
{acFrontLeft, "FL"},
{acFrontRight, "FR"},
{acFrontCenter, "FC"},
{acLowFrequency, "LFE"},
{acBackLeft, "BL"},
{acBackRight, "BR"},
{acFrontLeftOFCenter, "FLC"},
{acFrontRightOFCenter, "FRC"},
{acBackCenter, "BC"},
{acSideLeft, "SL"},
{acSideRight, "SR"},
{acTopCenter, "TC"},
{acTopFrontLeft, "TFL"},
{acTopFrontCenter, "TFC"},
{acTopFrontRight, "TFR"},
{acTopBackLeft, "TBL"},
{acTopBackCenter, "TBC"},
{acTopBackRight, "TBR"},
{acStereoLeft, "DL"}, // "downmix left"
{acStereoRight, "DR"}, // "downmix right"
{acWideLeft, "WL"},
{acWideRight, "WR"},
{acSurroundDirectLeft, "SDL"},
{acSurroundDirectRight, "SDR"},
{acLowFrequency2, "LFE2"}
};
static uint64_t genAudioChannelFlag(std::vector<VSAudioChannels> channels)
{
uint64_t flag = 0;
for(VSAudioChannels c : channels)
{
flag |= (static_cast<uint64_t>(1) << c);
}
return flag;
}
#define gACF genAudioChannelFlag
static std::map<uint64_t, QString> audioChannelToPreset =
{
{gACF({acFrontCenter}), "mono"},
{gACF({acFrontLeft, acFrontRight}), "stereo"},
{gACF({acFrontLeft, acFrontRight, acLowFrequency}), "2.1"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter}), "3.0"},
{gACF({acFrontLeft, acFrontRight, acBackCenter}), "3.0(back)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackCenter}), "4.0"},
{gACF({acFrontLeft, acFrontRight, acBackLeft, acBackRight}), "quad"},
{gACF({acFrontLeft, acFrontRight, acSideLeft, acSideRight}), "quad(side)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency}), "3.1"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acSideLeft, acSideRight}), "5.0"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acBackCenter}), "4.1"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acBackLeft, acBackRight}), "5.1"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acSideLeft, acSideRight}), "5.1(side)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackCenter, acSideLeft, acSideRight}), "6.0"},
{gACF({acFrontLeft, acFrontRight, acFrontLeftOFCenter, acFrontRightOFCenter, acSideLeft, acSideRight}), "6.0(front)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackLeft, acBackRight, acBackCenter}), "hexagonal"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acBackLeft, acBackRight, acBackCenter}), "6.1"},
{gACF({acFrontLeft, acFrontRight, acLowFrequency, acFrontLeftOFCenter, acFrontRightOFCenter, acSideLeft, acSideRight}), "6.1(front)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackLeft, acBackRight, acSideLeft, acSideRight}), "7.0"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acFrontLeftOFCenter, acFrontRightOFCenter, acSideLeft, acSideRight}), "7.0(front)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acBackLeft, acBackRight, acSideLeft, acSideRight}), "7.1"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acBackLeft, acBackRight, acFrontLeftOFCenter, acFrontRightOFCenter}), "7.1(wide)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acLowFrequency, acFrontLeftOFCenter, acFrontRightOFCenter, acSideLeft, acSideRight}), "7.1(wide-side)"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackLeft, acBackRight, acBackCenter, acSideLeft, acSideRight}), "octagonal"},
{gACF({acFrontLeft, acFrontRight, acFrontCenter, acBackLeft, acBackRight, acBackCenter, acSideLeft, acSideRight, acWideLeft, acWideRight, acTopBackLeft, acTopBackRight, acTopBackCenter, acTopFrontCenter, acTopFrontLeft, acTopFrontRight}), "hexadecagonal"},
{gACF({acStereoLeft, acStereoRight}), "downmix"}
};
//==============================================================================
QString vsedit::timeToString(double a_seconds, bool a_fullFormat)
{
if(a_seconds <= 0.0)
return QString("0");
// Milliseconds cut-off
a_seconds = std::round(a_seconds * 1000.0) / 1000.0;
// Seconds
uint64_t integer = (uint64_t)a_seconds;
int seconds = integer % 60ll;
integer /= 60ll;
int minutes = integer % 60ll;
integer /= 60ll;
int hours = integer;
QString timeString;
if((hours > 0) || a_fullFormat)
{
timeString = QString("%1:%2:%3").arg(hours)
.arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
}
else
{
timeString = QString("%1:%2") .arg(minutes)
.arg(seconds, 2, 10, QChar('0'));
}
// Fraction
double fraction = a_seconds - std::floor(a_seconds);
if((fraction > 0.0) || a_fullFormat)
timeString += QString::number(fraction, 'f', 3).mid(1);
return timeString;
}
// END OF QString vsedit::timeToString(double a_seconds, bool a_fullFormat)
//==============================================================================
int vsedit::mod(int a_value)
{
int l_mod = 1 << 6;
while(a_value % l_mod != 0)
l_mod >>= 1;
return l_mod;
}
// END OF int vsedit::mod(int a_value)
//==============================================================================
QString vsedit::videoInfoString(const VSVideoInfo * a_cpVideoInfo,
const VSAPI * a_cpVSAPI)
{
double fps = 0.0;
double time = 0.0;
if(a_cpVideoInfo->fpsDen != 0)
{
fps = (double)a_cpVideoInfo->fpsNum / (double)a_cpVideoInfo->fpsDen;
time = (double)a_cpVideoInfo->numFrames *
(double)a_cpVideoInfo->fpsDen / (double)a_cpVideoInfo->fpsNum;
}
QString infoString = QString("Frames: %frames% | Time: %time% | Size: "
"%width%x%height% | FPS: %fpsnum%/%fpsden% = %fps% | Format: %format%");
infoString.replace("%frames%", QString::number(a_cpVideoInfo->numFrames));
infoString.replace("%time%", vsedit::timeToString(time, true));
infoString.replace("%width%", QString::number(a_cpVideoInfo->width));
infoString.replace("%height%", QString::number(a_cpVideoInfo->height));
infoString.replace("%fpsnum%", QString::number(a_cpVideoInfo->fpsNum));
infoString.replace("%fpsden%", QString::number(a_cpVideoInfo->fpsDen));
infoString.replace("%fps%", QString::number(fps));
char formatName[32];
a_cpVSAPI->getVideoFormatName(&a_cpVideoInfo->format, formatName);
infoString.replace("%format%", formatName);
return infoString;
}
// END OF QString vsedit::videoInfoString(const VSVideoInfo * a_cpVideoInfo)
//==============================================================================
QString vsedit::audioInfoString(const VSAudioInfo * a_cpAudioInfo,
const VSAPI * a_cpVSAPI)
{
QString infoString = QString("Frames: %frames% | Time: %time% | "
"Sample Rate: %srate% Hz | Samples: %ns% | "
"Channels: %channels%| Format: %format%");
infoString.replace("%frames%", QString::number(a_cpAudioInfo->numFrames));
infoString.replace("%time%", vsedit::timeToString(
double(a_cpAudioInfo->numSamples) / a_cpAudioInfo->sampleRate, true));
infoString.replace("%srate%", QString::number(a_cpAudioInfo->sampleRate));
infoString.replace("%ns%", QString::number(a_cpAudioInfo->numSamples));
QString channelsString("");
uint64_t channelLayoutFlag = a_cpAudioInfo->format.channelLayout;
auto found = audioChannelToPreset.find(channelLayoutFlag);
if(found != audioChannelToPreset.end())
{
channelsString += QString("[%1] ")
.arg(audioChannelToPreset.at(channelLayoutFlag));
}
for(auto it : audioChannelToString)
{
if((static_cast<uint64_t>(1) << it.first) & channelLayoutFlag)
{
channelsString += QString("%1 ").arg(it.second);
}
}
infoString.replace("%channels%", channelsString);
char formatName[32];
a_cpVSAPI->getAudioFormatName(&a_cpAudioInfo->format, formatName);
infoString.replace("%format%", formatName);
return infoString;
}
// END OF QString vsedit::audioInfoString(const VSAudioInfo * a_cpAudioInfo,
// const VSAPI * a_cpVSAPI)
//==============================================================================
QString vsedit::nodeInfoString(const VSNodeInfo & a_nodeInfo,
const VSAPI * a_cpVSAPI)
{
if(a_nodeInfo.isInvalid())
return QString("");
else if(a_nodeInfo.isAudio())
return vsedit::audioInfoString(a_nodeInfo.getAsAudio(),
a_cpVSAPI);
else
{
Q_ASSERT(a_cpVSAPI);
return vsedit::videoInfoString(a_nodeInfo.getAsVideo(),
a_cpVSAPI);
}
}
// END OF QString vsedit::nodeInfoString(const VSNodeInfo & a_nodeInfo,
// const VSAPI * a_cpVSAPI)
//==============================================================================
double vsedit::qtimeToSeconds(const QTime & a_qtime)
{
double seconds = (double)a_qtime.msec() / 1000.0;
seconds += (double)a_qtime.second();
seconds += (double)a_qtime.minute() * 60.0;
seconds += (double)a_qtime.hour() * 360.0;
return seconds;
}
// END OF double vsedit::qtimeToSeconds(const QTime & a_qtime)
//==============================================================================
QTime vsedit::secondsToQTime(double a_seconds)
{
QTime qtime;
if(a_seconds <= 0.0)
return qtime;
// Milliseconds cut-off
a_seconds = std::round(a_seconds * 1000.0) / 1000.0;
// Seconds
uint64_t integer = (uint64_t)a_seconds;
int seconds = integer % 60ll;
integer /= 60ll;
int minutes = integer % 60ll;
integer /= 60ll;
int hours = integer % 60ll;
int milliseconds = (int)(((a_seconds - std::round(a_seconds)) * 1000.0));
qtime.setHMS(hours, minutes, seconds, milliseconds);
return qtime;
}
// END OF QTime vsedit::secondsToQTime(double a_seconds)
//==============================================================================
void vsedit::wait(int a_msec)
{
if(a_msec <= 0)
return;
QTime mark = QTime::currentTime().addMSecs(a_msec);
while(QTime::currentTime() < mark)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
// END OF void vsedit::wait(int a_msec)
//==============================================================================
QString vsedit::subsamplingString(int a_subsamplingW, int a_subsamplingH)
{
if((a_subsamplingW == 0) && (a_subsamplingH == 0))
return QString("444");
if((a_subsamplingW == 0) && (a_subsamplingH == 1))
return QString("440");
if((a_subsamplingW == 1) && (a_subsamplingH == 0))
return QString("422");
if((a_subsamplingW == 1) && (a_subsamplingH == 1))
return QString("420");
if((a_subsamplingW == 2) && (a_subsamplingH == 0))
return QString("411");
if((a_subsamplingW == 2) && (a_subsamplingH == 2))
return QString("410");
return QString();
}
// END OF QString vsedit::subsamplingString(int a_subsamplingW,
// int a_subsamplingH)
//==============================================================================
QString vsedit::subsamplingString(const VSVideoFormat * a_cpFormat)
{
if(!a_cpFormat)
return QString();
return subsamplingString(a_cpFormat->subSamplingW,
a_cpFormat->subSamplingH);
}
// END OF QString vsedit::subsamplingString(const VSVideoFormat * a_cpFormat)
//==============================================================================
QString vsedit::resolvePathFromApplication(const QString & a_relativePath)
{
// Remember the working directory and change it to application directory.
QString cwd = QDir::currentPath();
QString applicationDirPath = QCoreApplication::applicationDirPath();
QDir::setCurrent(applicationDirPath);
QFileInfo fileInfo(a_relativePath);
// If no parent directory is specified - leave the path as it is.
if(fileInfo.path() == ".")
return(a_relativePath);
QString absolutePath = fileInfo.absoluteFilePath();
// Restore the working directory.
QDir::setCurrent(cwd);
return absolutePath;
}
// END OF QString vsedit::resolvePathFromApplication(
// const QString & a_relativePath)
//==============================================================================
QByteArray vsedit::jsonMessage(const QString & a_command,
const QJsonObject & a_jsonObject)
{
return vsedit::jsonMessage(a_command, QJsonDocument(a_jsonObject));
}
// END OF QByteArray vsedit::jsonMessage(const QString & a_command,
// const QJsonObject & a_jsonObject)
//==============================================================================
QByteArray vsedit::jsonMessage(const QString & a_command,
const QJsonArray & a_jsonArray)
{
return vsedit::jsonMessage(a_command, QJsonDocument(a_jsonArray));
}
// END OF QByteArray vsedit::jsonMessage(const QString & a_command,
// const QJsonArray & a_jsonArray)
//==============================================================================
QByteArray vsedit::jsonMessage(const QString & a_command,
const QJsonDocument & a_jsonDocument)
{
return a_command.toUtf8() + ' ' + a_jsonDocument.toJson();
}
// END OF QByteArray vsedit::jsonMessage(const QString & a_command,
// const QJsonDocument & a_jsonDocument)
//==============================================================================
vsedit::FP32 vsedit::halfToSingle(vsedit::FP16 a_half)
{
FP32 o = { 0 };
// From ISPC ref code
if (a_half.parts.Exponent == 0 && a_half.parts.Mantissa == 0)
// (Signed) zero
o.parts.Sign = a_half.parts.Sign;
else
{
if (a_half.parts.Exponent == 0) // Denormal (will convert to normalized)
{
// Adjust mantissa so it's normalized (and keep track of exp adjust)
int e = -1;
unsigned int m = a_half.parts.Mantissa;
do
{
e++;
m <<= 1;
} while ((m & 0x400) == 0);
o.parts.Mantissa = (m & 0x3ff) << 13;
o.parts.Exponent = 127 - 15 - e;
o.parts.Sign = a_half.parts.Sign;
}
else if (a_half.parts.Exponent == 0x1f) // Inf/NaN
{
// NOTE: It's safe to treat both with the same code path
// by just truncating lower Mantissa bits in NaNs (this is valid).
o.parts.Mantissa = a_half.parts.Mantissa << 13;
o.parts.Exponent = 255;
o.parts.Sign = a_half.parts.Sign;
}
else // Normalized number
{
o.parts.Mantissa = a_half.parts.Mantissa << 13;
o.parts.Exponent = 127 - 15 + a_half.parts.Exponent;
o.parts.Sign = a_half.parts.Sign;
}
}
return o;
}
// END OF vsedit::FP32 vsedit::halfToSingle(vsedit::FP16 a_half)
//==============================================================================
================================================
FILE: common-src/helpers.h
================================================
#ifndef HELPERS_H_INCLUDED
#define HELPERS_H_INCLUDED
#include <VapourSynth4.h>
#include "helpers_vs.h"
#include <QString>
#include <QTime>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QByteArray>
#include <QDataStream>
#include <QIODevice>
#include <QFont>
#include <algorithm>
#include <functional>
namespace vsedit
{
struct VariableToken
{
QString token;
QString description;
std::function<QString()> evaluate;
};
QString timeToString(double a_seconds, bool a_fullFormat = false);
int mod(int a_value);
QString videoInfoString(const VSVideoInfo * a_cpVideoInfo,
const VSAPI * a_cpVSAPI);
QString audioInfoString(const VSAudioInfo * a_cpAudioInfo,
const VSAPI * a_cpVSAPI);
QString nodeInfoString(const VSNodeInfo &a_nodeInfo,
const VSAPI * a_cpVSAPI);
double qtimeToSeconds(const QTime & a_qtime);
QTime secondsToQTime(double a_seconds);
void wait(int a_msec);
QString subsamplingString(int a_subsamplingW, int a_subsamplingH);
QString subsamplingString(const VSVideoFormat * a_cpFormat);
QString resolvePathFromApplication(const QString & a_relativePath);
QByteArray jsonMessage(const QString & a_command,
const QJsonObject & a_jsonObject);
QByteArray jsonMessage(const QString & a_command,
const QJsonArray & a_jsonArray);
QByteArray jsonMessage(const QString & a_command,
const QJsonDocument & a_jsonDocument);
template<typename T1, typename T2, typename T3>
void clamp(T1& a_value, const T2& a_low, const T3& a_high)
{
Q_ASSERT(a_high > a_low);
if(a_value < a_low)
a_value = a_low;
else if(a_value > a_high)
a_value = a_high;
}
template<typename Container_T, typename Value_T>
bool contains(const Container_T & a_container, const Value_T & a_value)
{
return (std::find(std::begin(a_container), std::end(a_container),
a_value) != std::end(a_container));
}
template<typename T>
T roundUp(T a_number, T a_multiple)
{
if(a_multiple == 0)
return a_number;
T remainder = a_number % a_multiple;
if(remainder == 0)
return a_number;
return a_number + a_multiple - remainder;
}
template<typename T>
QByteArray toByteArray(const T & a_data)
{
QByteArray buf;
QDataStream stream(&buf, QIODevice::WriteOnly);
stream << a_data;
return buf;
}
template<typename T>
T fromByteArray(const QByteArray & a_array)
{
QDataStream stream(a_array);
T data;
stream >> data;
return data;
}
//------------------------------------------------------------------------------
// Half to single precision float conversion
// by Fabian "ryg" Giesen.
union FP32
{
uint32_t u;
float f;
struct
{
unsigned int Mantissa : 23;
unsigned int Exponent : 8;
unsigned int Sign : 1;
} parts;
};
union FP16
{
uint16_t u;
struct
{
unsigned int Mantissa : 10;
unsigned int Exponent : 5;
unsigned int Sign : 1;
} parts;
};
FP32 halfToSingle(FP16 a_half);
/* This is a patch for Qt 6 in Windows */
template<typename T>
void disableFontKerning(T * a_pWidget)
{
QFont font(a_pWidget->font());
font.setKerning(false);
a_pWidget->setFont(font);
}
//------------------------------------------------------------------------------
}
#endif // HELPERS_H_INCLUDED
================================================
FILE: common-src/helpers_vs.h
================================================
#ifndef HELPERS_VS_H_INCLUDED
#define HELPERS_VS_H_INCLUDED
#include <VapourSynth4.h>
#include <VSHelper4.h>
#include <utility>
enum class ProcessReason
{
Preview,
Check,
Benchmark,
Encode,
};
template <typename TV, typename TA>
class VSMediaTypePicker
{
protected:
const TV * m_pTV;
const TA * m_pTA;
int m_mediaType;
public:
VSMediaTypePicker()
: m_pTV(nullptr)
, m_pTA(nullptr)
, m_mediaType(-1)
{}
VSMediaTypePicker(const TV * a_pTV) : VSMediaTypePicker()
{
if(a_pTV)
{
m_pTV = a_pTV;
m_mediaType = mtVideo;
}
}
VSMediaTypePicker(const TA * a_pTA) : VSMediaTypePicker()
{
if(a_pTA)
{
m_pTA = a_pTA;
m_mediaType = mtAudio;
}
}
const void * get() const
{
switch (m_mediaType)
{
case mtAudio:
return reinterpret_cast<const void *>(m_pTA);
case mtVideo:
return reinterpret_cast<const void *>(m_pTV);
default:
return nullptr;
}
}
const TV * getAsVideo() const
{
return m_pTV;
}
const TA * getAsAudio() const
{
return m_pTA;
}
void set(const TV * a_pTV)
{
m_pTV = a_pTV;
m_pTA = nullptr;
m_mediaType = a_pTV ? mtVideo : -1;
}
void set(const TA * a_pTA)
{
m_pTV = nullptr;
m_pTA = a_pTA;
m_mediaType = a_pTA ? mtAudio : -1;
}
void setNull()
{
m_pTV = nullptr;
m_pTA = nullptr;
m_mediaType = -1;
}
bool isAudio() const
{
return m_mediaType == mtAudio;
}
bool isVideo() const
{
return m_mediaType == mtVideo;
}
bool isInvalid() const
{
return (!isVideo()) && (!isAudio());
}
int mediaType() const
{
return m_mediaType;
}
};
class VSNodeInfo : public VSMediaTypePicker<VSVideoInfo, VSAudioInfo>
{
public:
VSNodeInfo() : VSMediaTypePicker<VSVideoInfo, VSAudioInfo>() {}
VSNodeInfo(VSNode * a_pNode, const VSAPI * a_cpVSAPI)
{
int mediaType = a_cpVSAPI->getNodeType(a_pNode);
if(mediaType == mtAudio)
set(a_cpVSAPI->getAudioInfo(a_pNode));
else
set(a_cpVSAPI->getVideoInfo(a_pNode));
}
int numFrames() const
{
switch (m_mediaType)
{
case mtAudio:
return m_pTA->numFrames;
case mtVideo:
return m_pTV->numFrames;
default:
return -1;
}
}
std::pair<int64_t, int64_t> fpsPair() const
{
if (m_mediaType == mtAudio)
{
std::pair<int64_t, int64_t> res = {m_pTA->sampleRate, VS_AUDIO_FRAME_SAMPLES};
vsh::reduceRational(&res.first, &res.second);
return res;
}
else if (m_mediaType == mtVideo)
return {m_pTV->fpsNum, m_pTV->fpsDen};
else
return {0, 0};
}
};
class VSFrameFormat : public VSMediaTypePicker<VSVideoFormat, VSAudioFormat>
{
public:
VSFrameFormat() : VSMediaTypePicker<VSVideoFormat, VSAudioFormat>() {}
VSFrameFormat(const VSFrame * a_cpFrame, const VSAPI * a_cpVSAPI)
{
int mediaType = a_cpVSAPI->getFrameType(a_cpFrame);
if(mediaType == mtAudio)
set(a_cpVSAPI->getAudioFrameFormat(a_cpFrame));
else
set(a_cpVSAPI->getVideoFrameFormat(a_cpFrame));
}
};
inline bool isVariableSize(const VSVideoInfo *vi)
{
return vi->width == 0 && vi->height == 0;
}
inline bool isVariableFPS(const VSVideoInfo *vi)
{
return vi->fpsDen == 0 && vi->fpsNum == 0;
}
inline bool isVariableFormat(const VSVideoInfo *vi)
{
return vi->format.colorFamily == cfUndefined ||
vi->format.bitsPerSample == 0 ||
vi->format.bytesPerSample == 0 ||
vi->format.numPlanes == 0;
}
#endif
================================================
FILE: common-src/ipc_defines.h
================================================
#ifndef IPC_DEFINES_H_INCLUDED
#define IPC_DEFINES_H_INCLUDED
// Watcher <-> Job server communication
static const char JOB_SERVER_NAME[] = "vsedit_job_server";
static const uint16_t JOB_SERVER_PORT = 3370;
// Client messages
static const char MSG_GET_JOBS_INFO[] = "GJI";
static const char MSG_GET_LOG[] = "GL";
static const char MSG_SUBSCRIBE[] = "SS";
static const char MSG_UNSUBSCRIBE[] = "USS";
static const char MSG_CLOSE_SERVER[] = "CS";
static const char MSG_GET_TRUSTED_CLIENTS[] = "GTC";
static const char MSG_SET_TRUSTED_CLIENTS[] = "STC";
static const char MSG_CREATE_JOB[] = "CJ";
static const char MSG_CHANGE_JOB[] = "CHJ";
static const char MSG_SET_JOB_DEPENDENCIES[] = "SJD";
static const char MSG_SWAP_JOBS[] = "SJ";
static const char MSG_RESET_JOBS[] = "RJ";
static const char MSG_DELETE_JOBS[] = "DJ";
static const char MSG_START_ALL_WAITING_JOBS[] = "SAWJ";
static const char MSG_PAUSE_ACTIVE_JOBS[] = "PACJ";
static const char MSG_RESUME_PAUSED_JOBS[] = "RPJ";
static const char MSG_ABORT_ACTIVE_JOBS[] = "AACJ";
// Server messages
static const char SMSG_JOBS_INFO[] = "JI";
static const char SMSG_COMPLETE_LOG[] = "LOG";
static const char SMSG_LOG_MESSAGE[] = "LM";
static const char SMSG_JOB_CREATED[] = "JC";
static const char SMSG_JOB_UPDATE[] = "JU";
static const char SMSG_JOB_STATE_UPDATE[] = "JSU";
static const char SMSG_JOB_PROGRESS_UPDATE[] = "JPU";
static const char SMSG_JOB_START_TIME_UPDATE[] = "JSTU";
static const char SMSG_JOB_END_TIME_UPDATE[] = "JETU";
static const char SMSG_JOB_DEPENDENCIES_UPDATE[] = "JDU";
static const char SMSG_JOBS_SWAPPED[] = "JSW";
static const char SMSG_JOBS_DELETED[] = "JD";
static const char SMSG_REFUSE[] = "RF";
static const char SMSG_CLOSING_SERVER[] = "SCS";
static const char SMSG_TRUSTED_CLIENTS_INFO[] = "TCI";
// Editor <-> Watcher communication
static const char JOB_SERVER_WATCHER_LOCAL_SERVER_NAME[] =
"vsedit_job_server_watcher";
static const char WMSG_SHOW_WINDOW[] = "S";
static const char WMSG_CLI_ENCODE_JOB[] = "CEJ";
#endif // IPC_DEFINES_H_INCLUDED
================================================
FILE: common-src/jobs/job.cpp
================================================
#include "job.h"
#include "../../../common-src/helpers.h"
#include "../../../common-src/settings/settings_manager_core.h"
#include "../../../common-src/vapoursynth/vs_script_library.h"
#include "../../../common-src/vapoursynth/vapoursynth_script_processor.h"
#include "../frame_header_writers/frame_header_writer_null.h"
#include "../frame_header_writers/frame_header_writer_y4m.h"
#include "../../../common-src/jobs/job_variables.h"
#include <QFileInfo>
#include <QFile>
#include <algorithm>
#include <VSHelper4.h>
#ifdef Q_OS_WIN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#else
#include <signal.h>
#endif
//==============================================================================
vsedit::Job::Job(const JobProperties & a_properties,
SettingsManagerCore * a_pSettingsManager,
VSScriptLibrary * a_pVSScriptLibrary,
QObject * a_pParent) :
QObject(a_pParent)
, JobVariables()
, m_properties(a_properties)
, m_lastFrameProcessed(-1)
, m_lastFrameRequested(-1)
, m_encodingState(EncodingState::Idle)
, m_bytesToWrite(0u)
, m_bytesWritten(0u)
, m_pSettingsManager(a_pSettingsManager)
, m_pVSScriptLibrary(a_pVSScriptLibrary)
, m_pVapourSynthScriptProcessor(nullptr)
, m_cpVSAPI(nullptr)
, m_cpVideoInfo(nullptr)
, m_pFrameHeaderWriter(nullptr)
, m_cachedFramesLimit(100)
, m_framesInQueue(0)
, m_framesInProcess(0)
, m_maxThreads(0)
, m_memorizedEncodingTime(0.0)
{
fillVariables();
if(a_pVSScriptLibrary)
m_cpVSAPI = m_pVSScriptLibrary->getVSAPI();
connect(&m_process, SIGNAL(started()),
this, SLOT(slotProcessStarted()));
connect(&m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(slotProcessFinished(int, QProcess::ExitStatus)));
connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)),
this, SLOT(slotProcessError(QProcess::ProcessError)));
connect(&m_process, SIGNAL(readChannelFinished()),
this, SLOT(slotProcessReadChannelFinished()));
connect(&m_process, SIGNAL(bytesWritten(qint64)),
this, SLOT(slotProcessBytesWritten(qint64)));
connect(&m_process, SIGNAL(readyReadStandardError()),
this, SLOT(slotProcessReadyReadStandardError()));
}
// END OF vsedit::Job::Job(const JobProperties & a_properties,
// SettingsManagerCore * a_pSettingsManager,
// VSScriptLibrary * a_pVSScriptLibrary, QObject * a_pParent)
//==============================================================================
vsedit::Job::~Job()
{
}
// END OF vsedit::Job::~Job()
//==============================================================================
bool vsedit::Job::isActive() const
{
return vsedit::contains(ACTIVE_JOB_STATES, m_properties.jobState);
}
// END OF bool vsedit::Job::isActive() const
//==============================================================================
QUuid vsedit::Job::id() const
{
return m_properties.id;
}
// END OF QUuid vsedit::Job::id() const
//==============================================================================
bool vsedit::Job::setId(const QUuid & a_id)
{
if(isActive())
return false;
m_properties.id = a_id;
return true;
}
// END OF bool vsedit::Job::setId(const QUuid & a_id)
//==============================================================================
JobType vsedit::Job::type() const
{
return m_properties.type;
}
// END OF JobType vsedit::Job::type() const
//==============================================================================
bool vsedit::Job::setType(JobType a_type)
{
if(isActive())
return false;
m_properties.type = a_type;
return true;
}
// END OF bool vsedit::Job::setType(JobType a_type)
//==============================================================================
QString vsedit::Job::scriptName() const
{
return m_properties.scriptName;
}
// END OF QString vsedit::Job::scriptName() const
//==============================================================================
bool vsedit::Job::setScriptName(const QString & a_scriptName)
{
if(isActive())
return false;
m_properties.scriptName = a_scriptName;
return true;
}
// END OF bool vsedit::Job::setScriptName(const QString & a_scriptName)
//==============================================================================
QString vsedit::Job::scriptText() const
{
return m_properties.scriptText;
}
// END OF QString vsedit::Job::scriptText() const
//==============================================================================
bool vsedit::Job::setScriptText(const QString & a_scriptText)
{
if(isActive())
return false;
m_properties.scriptText = a_scriptText;
return true;
}
// END OF bool vsedit::Job::setScriptName(const QString & a_scriptText)
//==============================================================================
EncodingHeaderType vsedit::Job::encodingHeaderType() const
{
return m_properties.encodingHeaderType;
}
// END OF EncodingHeaderType vsedit::Job::encodingHeaderType() const
//==============================================================================
bool vsedit::Job::setEncodingHeaderType(EncodingHeaderType a_headerType)
{
m_properties.encodingHeaderType = a_headerType;
return true;
}
// END OF bool vsedit::Job::setEncodingHeaderType(
// EncodingHeaderType a_headerType)
//==============================================================================
QString vsedit::Job::executablePath() const
{
return m_properties.executablePath;
}
// END OF QString vsedit::Job::executablePath() const
//==============================================================================
bool vsedit::Job::setExecutablePath(const QString & a_path)
{
m_properties.executablePath = a_path;
return true;
}
// END OF bool vsedit::Job::setExecutablePath(const QString & a_path)
//==============================================================================
QString vsedit::Job::arguments() const
{
return m_properties.arguments;
}
// END OF QString vsedit::Job::arguments() const
//==============================================================================
bool vsedit::Job::setArguments(const QString & a_arguments)
{
if(isActive())
return false;
m_properties.arguments = a_arguments;
return true;
}
// END OF bool vsedit::Job::setArguments(const QString & a_arguments)
//==============================================================================
QString vsedit::Job::shellCommand() const
{
return m_properties.shellCommand;
}
// END OF QString vsedit::Job::shellCommand() const
//==============================================================================
bool vsedit::Job::setShellCommand(const QString & a_command)
{
if(isActive())
return false;
m_properties.shellCommand = a_command;
return true;
}
// END OF bool vsedit::Job::setShellCommand(const QString & a_command)
//==============================================================================
JobState vsedit::Job::state() const
{
return m_properties.jobState;
}
// END OF JobState vsedit::Job::state() const
//==============================================================================
bool vsedit::Job::setState(JobState a_state)
{
if(isActive())
return false;
changeStateAndNotify(a_state);
return true;
}
// END OF bool vsedit::Job::setState(JobState a_state)
//==============================================================================
std::vector<QUuid> vsedit::Job::dependsOnJobIds() const
{
return m_properties.dependsOnJobIds;
}
// END OF std::vector<QUuid> vsedit::Job::dependsOnJobIds() const
//==============================================================================
bool vsedit::Job::setDependsOnJobIds(const std::vector<QUuid> & a_ids)
{
if(isActive())
return false;
m_properties.dependsOnJobIds = a_ids;
return true;
}
// END OF bool vsedit::Job::setDependsOnJobIds(const std::vector<QUuid> & a_ids)
//==============================================================================
QString vsedit::Job::subject() const
{
QString subjectString;
if(m_properties.type == JobType::EncodeScriptCLI)
{
subjectString = QString("%sn%:\n\"%ep%\" %arg%");
subjectString = subjectString.replace("%sn%",
resolvePathFromApplication(m_properties.scriptName));
subjectString = subjectString.replace("%ep%",
resolvePathFromApplication(m_properties.executablePath));
subjectString = subjectString.replace("%arg%",
decodeArguments(m_properties.arguments));
}
else if(m_properties.type == JobType::RunProcess)
{
subjectString = QString("\"%ep%\" %arg%");
subjectString = subjectString.replace("%ep%",
resolvePathFromApplication(m_properties.executablePath));
subjectString = subjectString.replace("%arg%",
m_properties.arguments.simplified());
}
else if(m_properties.type == JobType::RunShellCommand)
subjectString = m_properties.shellCommand.simplified();
return subjectString;
}
// END OF QString vsedit::Job::subject() const
//==============================================================================
int vsedit::Job::firstFrame() const
{
if(m_properties.type != JobType::EncodeScriptCLI)
return -1;
if(m_properties.firstFrameReal >= 0)
return m_properties.firstFrameReal;
return m_properties.firstFrame;
}
// END OF int vsedit::Job::firstFrame() const
//==============================================================================
bool vsedit::Job::setFirstFrame(int a_frame)
{
if(isActive())
return false;
if(m_properties.type != JobType::EncodeScriptCLI)
return false;
if(a_frame < 0)
return false;
m_properties.firstFrame = a_frame;
if(m_pVapourSynthScriptProcessor->isInitialized())
{
Q_ASSERT(m_cpVideoInfo);
m_properties.firstFrameReal = std::min(m_properties.firstFrame,
m_cpVideoInfo->numFrames - 1);
}
else
m_properties.firstFrameReal = -1;
return true;
}
// END OF bool vsedit::Job::setFirstFrame(int a_frame)
//==============================================================================
int vsedit::Job::lastFrame() const
{
if(m_properties.type != JobType::EncodeScriptCLI)
return -1;
if(m_properties.lastFrameReal >= 0)
return m_properties.lastFrameReal;
return m_properties.lastFrame;
}
// END OF int vsedit::Job::lastFrame() const
//==============================================================================
bool vsedit::Job::setLastFrame(int a_frame)
{
if(isActive())
return false;
if(m_properties.type != JobType::EncodeScriptCLI)
return false;
if(a_frame < 0)
return false;
m_properties.lastFrame = a_frame;
if(m_pVapourSynthScriptProcessor->isInitialized())
{
Q_ASSERT(m_cpVideoInfo);
m_properties.lastFrameReal = std::min(m_properties.lastFrame,
m_cpVideoInfo->numFrames - 1);
}
else
m_properties.lastFrameReal = -1;
return true;
}
// END OF bool vsedit::Job::setFirstFrame(int a_frame)
//==============================================================================
int vsedit::Job::framesProcessed() const
{
if(m_properties.type == JobType::EncodeScriptCLI)
return m_properties.framesProcessed;
return 0;
}
// END OF int vsedit::Job::framesProcessed() const
//==============================================================================
int vsedit::Job::framesTotal() const
{
if(m_properties.type == JobType::EncodeScriptCLI)
return (m_properties.lastFrameReal - m_properties.firstFrameReal + 1);
return 0;
}
// END OF int vsedit::Job::framesTotal() const
//==============================================================================
double vsedit::Job::fps() const
{
return m_properties.fps;
}
// END OF double vsedit::Job::fps() const
//==============================================================================
double vsedit::Job::secondsToFinish() const
{
int framesLeft = framesTotal() - framesProcessed();
double seconds = (double)framesLeft / m_properties.fps;
return seconds;
}
// END OF double vsedit::Job::secondsToFinish() const
//==============================================================================
size_t vsedit::Job::framesInQueue() const
{
return m_framesInQueue;
}
// END OF size_t vsedit::Job::framesInQueue() const
//==============================================================================
size_t vsedit::Job::framesInProcess() const
{
return m_framesInProcess;
}
// END OF size_t vsedit::Job::framesInProcess() const
//==============================================================================
size_t vsedit::Job::maxThreads() const
{
return m_maxThreads;
}
// END OF size_t vsedit::Job::maxThreads() const
//==============================================================================
JobProperties vsedit::Job::properties() const
{
return m_properties;
}
// END OF JobProperties vsedit::Job::properties() const
//==============================================================================
bool vsedit::Job::setProperties(const JobProperties & a_properties)
{
if(isActive())
return false;
m_properties = a_properties;
return true;
}
// END OF bool vsedit::Job::setProperties(const JobProperties & a_properties)
//==============================================================================
const VSVideoInfo * vsedit::Job::videoInfo() const
{
if(m_properties.type != JobType::EncodeScriptCLI)
return nullptr;
if(!m_pVapourSynthScriptProcessor)
return nullptr;
return m_pVapourSynthScriptProcessor->nodeInfo().getAsVideo();
}
// END OF const VSVideoInfo * vsedit::Job::videoInfo() const
//==============================================================================
bool vsedit::Job::initialize()
{
if(m_properties.type != JobType::EncodeScriptCLI)
return false;
if(isActive() && (m_encodingState != EncodingState::Idle))
{
emit signalLogMessage(tr("Can not initialize an active job"),
LOG_STYLE_ERROR);
return false;
}
if(m_properties.scriptText.isEmpty())
{
QString absoluteScriptPath =
resolvePathFromApplication(m_properties.scriptName);
QFile scriptFile(absoluteScriptPath);
bool opened = scriptFile.open(QIODevice::ReadOnly);
if(!opened)
{
emit signalLogMessage(tr("Could not open script file \"%1\".")
.arg(m_properties.scriptName), LOG_STYLE_ERROR);
changeStateAndNotify(JobState::Failed);
return false;
}
m_properties.scriptText = QString::fromUtf8(scriptFile.readAll());
scriptFile.close();
}
if((!m_pVSScriptLibrary) || (!m_pSettingsManager))
{
emit signalLogMessage(tr("Job is not created properly."),
LOG_STYLE_ERROR);
changeStateAndNotify(JobState::Failed);
return false;
}
m_cpVSAPI = m_pVSScriptLibrary->getVSAPI();
Q_ASSERT(m_cpVSAPI);
if(!m_pVapourSynthScriptProcessor)
{
m_pVapourSynthScriptProcessor = new VapourSynthScriptProcessor(
m_pSettingsManager, m_pVSScriptLibrary, this);
connect(m_pVapourSynthScriptProcessor,
SIGNAL(signalWriteLogMessage(int, const QString &)),
this, SLOT(slotWriteLogMessage(int, const QString &)));
connect(m_pVapourSynthScriptProcessor,
SIGNAL(signalFrameQueueStateChanged(size_t, size_t, size_t, double)),
this, SLOT(slotFrameQueueStateChanged(size_t, size_t, size_t, double)));
connect(m_pVapourSynthScriptProcessor, SIGNAL(signalFinalized()),
this, SLOT(slotScriptProcessorFinalized()));
connect(m_pVapourSynthScriptProcessor,
SIGNAL(signalDistributeFrame(int, int, const VSFrame *,
const VSFrame *)),
this, SLOT(slotReceiveFrame(int, int, const VSFrame *,
const VSFrame *)));
connect(m_pVapourSynthScriptProcessor,
SIGNAL(signalFrameRequestDiscarded(int, int, const QString &)),
this, SLOT(slotFrameRequestDiscarded(int, int, const QString &)));
connect(m_pVapourSynthScriptProcessor,
SIGNAL(signalFrameQueueStateChanged(size_t, size_t, size_t, double)),
this, SLOT(slotFrameQueueStateChanged(size_t, size_t, size_t, double)));
}
if((!m_pVapourSynthScriptProcessor->isInitialized()) ||
(m_pVapourSynthScriptProcessor->scriptName() !=
m_properties.scriptName) || (m_pVapourSynthScriptProcessor->script() !=
m_properties.scriptText))
{
bool scriptProcessorInitialized =
m_pVapourSynthScriptProcessor->initialize(
m_properties.scriptText, m_properties.scriptName, 0,
ProcessReason::Encode);
if(!scriptProcessorInitialized)
{
emit signalLogMessage(tr("Failed to initialize script.\n%1")
.arg(m_pVapourSynthScriptProcessor->error()), LOG_STYLE_ERROR);
changeStateAndNotify(JobState::Failed);
return false;
}
}
VSNodeInfo info = m_pVapourSynthScriptProcessor->nodeInfo();
Q_ASSERT(!info.isInvalid());
if(info.isAudio())
{
emit signalLogMessage(tr("Audio encoding is not supported."));
changeStateAndNotify(JobState::Failed);
return false;
}
m_cpVideoInfo = info.getAsVideo();
m_properties.framesProcessed = 0;
m_properties.firstFrameReal = m_properties.firstFrame;
vsedit::clamp(m_properties.firstFrameReal, 0, m_cpVideoInfo->numFrames - 1);
m_properties.lastFrameReal = m_properties.lastFrame;
if((m_properties.lastFrameReal < m_properties.firstFrameReal) ||
(m_properties.lastFrameReal >= m_cpVideoInfo->numFrames))
m_properties.lastFrameReal = m_cpVideoInfo->numFrames - 1;
m_lastFrameRequested = m_properties.firstFrameReal - 1;
m_lastFrameProcessed = m_lastFrameRequested;
m_encodingState = EncodingState::Idle;
m_bytesToWrite = 0u;
m_bytesWritten = 0u;
return true;
}
// END OF bool vsedit::Job::initialize()
//==============================================================================
void vsedit::Job::cleanUpEncoding()
{
if(m_process.state() == QProcess::Running)
{
if(m_encodingState != EncodingState::Aborting)
m_encodingState = EncodingState::Finishing;
m_process.closeWriteChannel();
}
if(m_pVapourSynthScriptProcessor)
m_pVapourSynthScriptProcessor->finalize();
clearFramesCache();
m_framebuffer.clear();
m_cpVideoInfo = nullptr;
}
// END OF void vsedit::Job::cleanUpEncoding()
//==============================================================================
void vsedit::Job::start()
{
if(m_properties.jobState == JobState::Paused)
{
changeStateAndNotify(JobState::Running);
if(m_properties.type == JobType::EncodeScriptCLI)
processFramesQueue();
else if(m_properties.type == JobType::RunProcess)
{
#ifdef Q_OS_WIN
BOOL result = DebugActiveProcessStop((DWORD)m_process.processId());
if(result)
changeStateAndNotify(JobState::Running);
else
emit signalLogMessage(tr("Failed to resume process. "
"Error %1.").arg(GetLastError()), LOG_STYLE_ERROR);
#else
int error = kill((pid_t)m_process.processId(), SIGCONT);
if(!error)
changeStateAndNotify(JobState::Running);
else
emit signalLogMessage(tr("Failed to resume process. "
"Error %1.").arg(error), LOG_STYLE_ERROR);
#endif
}
}
else if(!isActive())
{
m_properties.timeStarted = QDateTime::currentDateTimeUtc();
changeStateAndNotify(JobState::Running);
emit signalStartTimeChanged();
if(m_properties.type == JobType::EncodeScriptCLI)
startEncodeScriptCLI();
else if(m_properties.type == JobType::RunProcess)
startRunProcess();
else if(m_properties.type == JobType::RunShellCommand)
startRunShellCommand();
}
}
// END OF void vsedit::Job::start()
//==============================================================================
void vsedit::Job::pause()
{
if(m_properties.jobState != JobState::Running)
return;
if(m_properties.type == JobType::EncodeScriptCLI)
{
EncodingState invalidEncodingStates[] = {EncodingState::Idle,
EncodingState::EncoderCrashed, EncodingState::Finishing,
EncodingState::Aborting};
if(vsedit::contains(invalidEncodingStates, m_encodingState))
return;
changeStateAndNotify(JobState::Pausing);
}
else if(m_properties.type == JobType::RunProcess)
{
#ifdef Q_OS_WIN
BOOL result = DebugActiveProcess((DWORD)m_process.processId());
if(result)
changeStateAndNotify(JobState::Paused);
else
emit signalLogMessage(tr("Failed to pause process. Error %1.")
.arg(GetLastError()), LOG_STYLE_ERROR);
#else
int error = kill((pid_t)m_process.processId(), SIGSTOP);
if(!error)
changeStateAndNotify(JobState::Paused);
else
emit signalLogMessage(tr("Failed to pause process. Error %1.")
.arg(error), LOG_STYLE_ERROR);
#endif
}
}
// END OF void vsedit::Job::pause()
//==============================================================================
void vsedit::Job::abort()
{
if(!isActive())
return;
if(m_process.state() != QProcess::Running){
cleanUpEncoding();
changeStateAndNotify(JobState::Aborted);
return;
}
changeStateAndNotify(JobState::Aborting);
if(m_properties.type == JobType::EncodeScriptCLI)
{
m_encodingState = EncodingState::Aborting;
cleanUpEncoding();
return;
}
else if(m_properties.type == JobType::RunProcess)
{
if(m_process.state() == QProcess::Running)
{
m_process.kill();
m_process.waitForFinished(-1);
}
}
changeStateAndNotify(JobState::Aborted);
}
// END OF void vsedit::Job::abort()
//==============================================================================
void vsedit::Job::slotProcessStarted()
{
if(m_encodingState == EncodingState::CheckingEncoderSanity)
return;
if(m_properties.type == JobType::EncodeScriptCLI)
{
emit signalLogMessage(tr("Encoder started. Beginning encoding."));
if(!m_process.isWritable())
{
m_encodingState = EncodingState::Aborting;
m_properties.jobState = JobState::Aborting;
emit signalLogMessage(tr("Can not write to encoder. Aborting."),
LOG_STYLE_ERROR);
cleanUpEncoding();
return;
}
Q_ASSERT(m_pFrameHeaderWriter);
if(m_pFrameHeaderWriter->needVideoHeader())
{
QByteArray videoHeader =
m_pFrameHeaderWriter->videoHeader(framesTotal());
if(m_properties.encodingHeaderType == EncodingHeaderType::Y4M)
emit signalLogMessage(tr("Y4M header: ") +
QString::fromLatin1(videoHeader), LOG_STYLE_DEBUG);
m_bytesToWrite = videoHeader.size();
if(m_bytesToWrite > 0)
{
m_bytesWritten = 0;
m_encodingState = EncodingState::WritingHeader;
qint64 bytesWritten = m_process.write(videoHeader);
if(bytesWritten < 0)
{
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
emit signalLogMessage(
tr("Error on writing header to encoder. Aborting."),
LOG_STYLE_ERROR);
cleanUpEncoding();
return;
}
return;
}
}
m_memorizedEncodingTime = 0.0;
m_encodeRangeStartTime = hr_clock::now();
m_encodingState = EncodingState::WaitingForFrames;
processFramesQueue();
}
}
// END OF void vsedit::Job::slotProcessStarted()
//==============================================================================
void vsedit::Job::slotProcessFinished(int a_exitCode,
QProcess::ExitStatus a_exitStatus)
{
if(m_properties.type == JobType::EncodeScriptCLI)
{
EncodingState workingStates[] = {EncodingState::WaitingForFrames,
EncodingState::WritingFrame, EncodingState::WritingHeader};
if(m_encodingState == EncodingState::CheckingEncoderSanity)
return;
else if(m_encodingState == EncodingState::Idle)
return;
else if(m_encodingState == EncodingState::Finishing)
changeStateAndNotify(JobState::CompletedCleanUp);
else if(vsedit::contains(workingStates, m_encodingState))
{
QString exitStatusString = (a_exitStatus == QProcess::CrashExit) ?
tr("crash") : tr("normal exit");
emit signalLogMessage(tr("Encoder has finished "
"unexpectedly.\nReason: %1; exit code: %2")
.arg(exitStatusString).arg(a_exitCode), LOG_STYLE_ERROR);
changeStateAndNotify(JobState::FailedCleanUp);
}
cleanUpEncoding();
finishEncodingCLI();
}
else if(m_properties.type == JobType::RunProcess)
{
QString message = tr("Process has finished.");
QString logStyle = LOG_STYLE_POSITIVE;
JobState nextState = JobState::Completed;
if(a_exitStatus == QProcess::CrashExit)
{
message = tr("Process has crashed.");
logStyle = LOG_STYLE_ERROR;
nextState = JobState::Failed;
}
else if(a_exitCode != 0)
logStyle = LOG_STYLE_WARNING;
emit signalLogMessage(tr("%1 Exit code: %2")
.arg(message).arg(a_exitCode), logStyle);
changeStateAndNotify(nextState);
}
}
// END OF void vsedit::Job::slotProcessFinished(int a_exitCode,
// QProcess::ExitStatus a_exitStatus)
//==============================================================================
void vsedit::Job::slotProcessError(QProcess::ProcessError a_error)
{
if(m_properties.type == JobType::EncodeScriptCLI)
{
if(m_encodingState == EncodingState::CheckingEncoderSanity)
return;
if(m_encodingState == EncodingState::Idle)
{
emit signalLogMessage(tr("Encoder has reported "
"an error while it shouldn't be running at all. Ignoring."),
LOG_STYLE_WARNING);
return;
}
switch(a_error)
{
case QProcess::FailedToStart:
emit signalLogMessage(tr("Encoder has failed to start. "
"Aborting."), LOG_STYLE_ERROR);
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
break;
case QProcess::Crashed:
emit signalLogMessage(tr("Encoder has crashed. "
"Aborting."), LOG_STYLE_ERROR);
m_encodingState = EncodingState::EncoderCrashed;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
break;
case QProcess::Timedout:
break;
case QProcess::WriteError:
if(m_encodingState == EncodingState::WritingFrame)
{
emit signalLogMessage(tr("Writing to encoder "
"failed. Aborting."), LOG_STYLE_ERROR);
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
}
else
{
emit signalLogMessage(tr("Encoder has returned a "
"writing error, but we were not writing. Ignoring."),
LOG_STYLE_WARNING);
}
break;
case QProcess::ReadError:
emit signalLogMessage(tr("Error on reading the "
"encoder feedback."), LOG_STYLE_WARNING);
break;
case QProcess::UnknownError:
emit signalLogMessage(tr("Unknown error in encoder."),
LOG_STYLE_WARNING);
break;
default:
Q_ASSERT(false);
}
}
else if(m_properties.type == JobType::RunProcess)
{
switch(a_error)
{
case QProcess::FailedToStart:
emit signalLogMessage(tr("Process has failed to start."),
LOG_STYLE_ERROR);
changeStateAndNotify(JobState::Failed);
break;
case QProcess::Crashed:
emit signalLogMessage(tr("Process has crashed."),
LOG_STYLE_ERROR);
changeStateAndNotify(JobState::Failed);
break;
default:
break;
}
}
}
// END OF void vsedit::Job::slotProcessError(QProcess::ProcessError a_error)
//==============================================================================
void vsedit::Job::slotProcessReadChannelFinished()
{
if(m_properties.type != JobType::EncodeScriptCLI)
return;
if(m_encodingState == EncodingState::CheckingEncoderSanity)
return;
if(m_encodingState == EncodingState::Idle)
{
emit signalLogMessage(tr("Encoder has suddenly stopped "
"accepting data while it shouldn't be running at all. Ignoring."),
LOG_STYLE_WARNING);
return;
}
if((m_encodingState != EncodingState::Finishing) &&
(m_encodingState != EncodingState::Aborting))
{
emit signalLogMessage(tr("Encoder has suddenly stopped "
"accepting data. Aborting."), LOG_STYLE_ERROR);
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
}
}
// END OF void vsedit::Job::slotProcessReadChannelFinished()
//==============================================================================
void vsedit::Job::slotProcessBytesWritten(qint64 a_bytes)
{
if(m_properties.type != JobType::EncodeScriptCLI)
return;
if(m_encodingState == EncodingState::CheckingEncoderSanity)
return;
if(m_encodingState == EncodingState::Idle)
{
emit signalLogMessage(tr("Encoder has reported written "
"data while it shouldn't be running at all. Ignoring."),
LOG_STYLE_WARNING);
return;
}
if((m_encodingState == EncodingState::Aborting) ||
(m_encodingState == EncodingState::Finishing))
return;
if((m_encodingState != EncodingState::WritingFrame) &&
(m_encodingState != EncodingState::WritingHeader))
{
emit signalLogMessage(tr("Encoder reports successful "
"write, but we were not writing anything.\nData written: "
"%1 bytes.").arg(a_bytes), LOG_STYLE_WARNING);
return;
}
if(a_bytes <= 0)
{
emit signalLogMessage(tr("Error on writing data to "
"encoder.\nExpected to write: %1 bytes. Data written: %2 bytes.\n"
"Aborting.").arg(m_bytesToWrite).arg(m_bytesWritten),
LOG_STYLE_ERROR);
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
return;
}
m_bytesWritten += a_bytes;
if((m_bytesWritten + m_process.bytesToWrite()) < m_bytesToWrite)
{
emit signalLogMessage(tr("Encoder has lost written "
"data. Aborting."), LOG_STYLE_ERROR);
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
return;
}
if(m_bytesWritten < m_bytesToWrite)
return;
Q_ASSERT(m_cpVSAPI);
if(m_encodingState == EncodingState::WritingHeader)
{
m_memorizedEncodingTime = 0.0;
m_encodeRangeStartTime = hr_clock::now();
}
else if(m_encodingState == EncodingState::WritingFrame)
{
Frame referenceFrame(m_lastFrameProcessed + 1, 0, nullptr);
std::list<Frame>::iterator it =
std::find(m_framesCache.begin(), m_framesCache.end(),
referenceFrame);
Q_ASSERT(it != m_framesCache.end());
m_cpVSAPI->freeFrame(it->cpOutputFrame);
m_framesCache.erase(it);
m_lastFrameProcessed++;
m_properties.framesProcessed++;
updateFPS();
emit signalProgressChanged();
}
m_encodingState = EncodingState::WaitingForFrames;
if((m_properties.jobState == JobState::Pausing) && (m_framesInProcess == 0))
{
changeStateAndNotify(JobState::Paused);
return;
}
processFramesQueue();
}
// END OF void vsedit::Job::slotProcessBytesWritten(qint64 a_bytes)
//==============================================================================
void vsedit::Job::slotProcessReadyReadStandardError()
{
QByteArray standardError = m_process.readAllStandardError();
QString standardErrorText = QString::fromUtf8(standardError);
standardErrorText = standardErrorText.trimmed();
if(!standardErrorText.isEmpty())
emit signalLogMessage(standardErrorText);
}
// END OF void vsedit::Job::slotProcessReadyReadStandardError()
//==============================================================================
void vsedit::Job::slotWriteLogMessage(int a_messageType,
const QString & a_message)
{
QString style = vsMessageTypeToStyleName(a_messageType);
emit signalLogMessage(a_message, style);
}
// END OF void vsedit::Job::slotWriteLogMessage(int a_messageType,
// const QString & a_message)
//==============================================================================
void vsedit::Job::slotFrameQueueStateChanged(size_t a_inQueue,
size_t a_inProcess, size_t a_maxThreads, double a_usedCacheRatio)
{
m_framesInQueue = a_inQueue;
m_framesInProcess = a_inProcess;
m_maxThreads = a_maxThreads;
}
// END OF void vsedit::Job::slotFrameQueueStateChanged(size_t a_inQueue,
// size_t a_inProcess, size_t a_maxThreads, double a_usedCacheRatio)
//==============================================================================
void vsedit::Job::slotScriptProcessorFinalized()
{
Q_ASSERT(m_properties.type == JobType::EncodeScriptCLI);
finishEncodingCLI();
}
// END OF void vsedit::Job::slotScriptProcessorFinalized()
//==============================================================================
void vsedit::Job::slotReceiveFrame(int a_frameNumber, int a_outputIndex,
const VSFrame * a_cpOutputFrame,
const VSFrame * a_cpPreviewFrameRef)
{
(void)a_cpPreviewFrameRef;
EncodingState validStates[] = {EncodingState::WaitingForFrames,
EncodingState::WritingHeader, EncodingState::WritingFrame};
if(!vsedit::contains(validStates, m_encodingState))
return;
if((a_frameNumber < m_properties.firstFrameReal) ||
(a_frameNumber > m_properties.lastFrameReal))
return;
Q_ASSERT(m_cpVSAPI);
const VSFrame * cpFrameRef =
m_cpVSAPI->addFrameRef(a_cpOutputFrame);
Frame newFrame(a_frameNumber, a_outputIndex, cpFrameRef);
m_framesCache.push_back(newFrame);
if(m_encodingState == EncodingState::WaitingForFrames)
processFramesQueue();
}
// END OF void vsedit::Job::slotReceiveFrame(int a_frameNumber,
// int a_outputIndex, const VSFrame * a_cpOutputFrame,
// const VSFrame * a_cpPreviewFrameRef)
//==============================================================================
void vsedit::Job::slotFrameRequestDiscarded(int a_frameNumber,
int a_outputIndex, const QString & a_reason)
{
(void)a_frameNumber;
(void)a_outputIndex;
(void)a_reason;
EncodingState validStates[] = {EncodingState::WaitingForFrames,
EncodingState::WritingHeader, EncodingState::WritingFrame};
if(!vsedit::contains(validStates, m_encodingState))
return;
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
}
// END OF void vsedit::Job::slotFrameRequestDiscarded(int a_frameNumber,
// int a_outputIndex, const QString & a_reason)
//==============================================================================
void vsedit::Job::fillVariables()
{
JobVariables::fillVariables();
struct JobVariableEvaluator
{
QString token;
std::function<QString()> evaluate;
};
JobVariableEvaluator evaluators[] =
{
{TOKEN_WIDTH,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_WIDTH;
return QString::number(m_cpVideoInfo->width);
}
},
{TOKEN_HEIGHT,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_HEIGHT;
return QString::number(m_cpVideoInfo->height);
}
},
{TOKEN_FPS_NUMERATOR,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_FPS_NUMERATOR;
return QString::number(m_cpVideoInfo->fpsNum);
}
},
{TOKEN_FPS_DENOMINATOR,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_FPS_DENOMINATOR;
return QString::number(m_cpVideoInfo->fpsDen);
}
},
{TOKEN_FPS,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_FPS;
double fps = (double)m_cpVideoInfo->fpsNum /
(double)m_cpVideoInfo->fpsDen;
return QString::number(fps, 'f', 10);
}
},
{TOKEN_BITDEPTH,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_BITDEPTH;
return QString::number(m_cpVideoInfo->format.bitsPerSample);
}
},
{TOKEN_SCRIPT_DIRECTORY,
[&]() -> QString
{
QFileInfo scriptFile(m_properties.scriptName);
return scriptFile.canonicalPath();
}
},
{TOKEN_SCRIPT_NAME,
[&]() -> QString
{
QFileInfo scriptFile(m_properties.scriptName);
return scriptFile.completeBaseName();
}
},
{TOKEN_FRAMES_NUMBER,
[&]() -> QString
{
return QString::number(framesTotal());
}
},
{TOKEN_SUBSAMPLING,
[&]() -> QString
{
if(!m_cpVideoInfo)
return TOKEN_SUBSAMPLING;
const VSVideoFormat * cpFormat = &m_cpVideoInfo->format;
return vsedit::subsamplingString(cpFormat->subSamplingW,
cpFormat->subSamplingH);
}
},
};
for(JobVariableEvaluator & evaluator : evaluators)
{
std::vector<vsedit::VariableToken>::iterator it =
std::find_if(m_variables.begin(), m_variables.end(),
[&](const vsedit::VariableToken & a_variable) -> bool
{
return (a_variable.token == evaluator.token);
});
it->evaluate = evaluator.evaluate;
}
}
// END OF void vsedit::Job::fillVariables()
//==============================================================================
void vsedit::Job::changeStateAndNotify(JobState a_state)
{
if(m_properties.jobState == a_state && a_state != JobState::Aborted)
return;
JobState oldState = m_properties.jobState;
m_properties.jobState = a_state;
if(oldState == JobState::Waiting)
m_properties.timeStarted = QDateTime::currentDateTimeUtc();
const JobState finishStates[] = {JobState::Aborted, JobState::Failed,
JobState::DependencyNotMet, JobState::Completed};
if(vsedit::contains(finishStates, a_state))
{
m_properties.timeEnded = QDateTime::currentDateTimeUtc();
memorizeEncodingTime();
emit signalEndTimeChanged();
}
if(a_state == JobState::Paused)
memorizeEncodingTime();
if((oldState == JobState::Paused) && (a_state == JobState::Running))
m_encodeRangeStartTime = hr_clock::now();
if(a_state == JobState::Waiting)
{
m_properties.timeStarted = QDateTime();
m_properties.timeEnded = QDateTime();
m_memorizedEncodingTime = 0.0;
m_properties.fps = 0.0;
m_properties.framesProcessed = 0;
}
emit signalStateChanged(m_properties.jobState, oldState);
}
// END OF void vsedit::Job::changeStateAndNotify(JobState a_state)
//==============================================================================
void vsedit::Job::startEncodeScriptCLI()
{
if(!initialize())
return;
emit signalPropertiesChanged();
if(m_pFrameHeaderWriter)
delete m_pFrameHeaderWriter;
if(m_properties.encodingHeaderType == EncodingHeaderType::Y4M)
m_pFrameHeaderWriter =
new FrameHeaderWriterY4M(m_cpVSAPI, m_cpVideoInfo, this);
else
m_pFrameHeaderWriter =
new FrameHeaderWriterNull(m_cpVSAPI, m_cpVideoInfo, this);
bool compatibleHeader = m_pFrameHeaderWriter->isCompatible();
if(!compatibleHeader)
{
emit signalLogMessage(tr("Video is not compatible "
"with the chosen header."), LOG_STYLE_ERROR);
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
return;
}
QString executable = vsedit::resolvePathFromApplication(
m_properties.executablePath);
QString decodedArguments =
decodeArguments(m_properties.arguments);
QString commandLine = QString("\"%1\" %2").arg(executable)
.arg(decodedArguments);
emit signalLogMessage(tr("Command line:"));
emit signalLogMessage(commandLine);
emit signalLogMessage(tr("Checking the encoder sanity."));
m_encodingState = EncodingState::CheckingEncoderSanity;
m_process.startCommand(commandLine);
if(!m_process.waitForStarted(3000))
{
emit signalLogMessage(tr("Encoder wouldn't start."),
LOG_STYLE_ERROR);
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
return;
}
m_process.closeWriteChannel();
if(!m_process.waitForFinished(3000))
{
emit signalLogMessage(tr("Program is not behaving "
"like a CLI encoder. Terminating."), LOG_STYLE_ERROR);
m_process.kill();
m_process.waitForFinished(-1);
changeStateAndNotify(JobState::FailedCleanUp);
cleanUpEncoding();
return;
}
emit signalLogMessage(tr("Encoder seems sane. Starting."));
m_encodingState = EncodingState::StartingEncoder;
m_process.startCommand(commandLine);
}
// END OF void vsedit::Job::startEncodeScriptCLI()
//==============================================================================
void vsedit::Job::startRunProcess()
{
changeStateAndNotify(JobState::Running);
QString executable = vsedit::resolvePathFromApplication(
m_properties.executablePath);
QString commandLine = QString("\"%1\" %2").arg(executable)
.arg(m_properties.arguments);
emit signalLogMessage(tr("Command line:"));
emit signalLogMessage(commandLine);
m_process.startCommand(commandLine);
}
// END OF void vsedit::Job::startRunProcess()
//==============================================================================
void vsedit::Job::startRunShellCommand()
{
changeStateAndNotify(JobState::Running);
QString command = "%1";
m_process.startDetached(m_properties.shellCommand, QStringList());
changeStateAndNotify(JobState::Completed);
}
// END OF void vsedit::Job::startRunShellCommand()
//==============================================================================
QString vsedit::Job::decodeArguments(const QString & a_arguments) const
{
QString decodedString = a_arguments.simplified();
for(const vsedit::VariableToken & variable : m_variables)
{
decodedString = decodedString.replace(variable.token,
variable.evaluate());
}
return decodedString;
}
// END OF QString vsedit::Job::decodeArguments(
// const QString & a_arguments) const
//==============================================================================
void vsedit::Job::clearFramesCache()
{
if(m_framesCache.empty())
return;
Q_ASSERT(m_cpVSAPI);
for(Frame & frame : m_framesCache)
{
m_cpVSAPI->freeFrame(frame.cpOutputFrame);
m_cpVSAPI->freeFrame(frame.cpPreviewFrame);
}
m_framesCache.clear();
}
// END OF void vsedit::Job::clearFramesCache()
//==============================================================================
void vsedit::Job::processFramesQueue()
{
if(m_encodingState != EncodingState::WaitingForFrames)
return;
if(m_properties.framesProcessed == framesTotal())
{
Q_ASSERT(m_framesCache.empty());
memorizeEncodingTime();
updateFPS();
changeStateAndNotify(JobState::CompletedCleanUp);
m_encodingState = EncodingState::Finishing;
cleanUpEncoding();
return;
}
while((m_lastFrameRequested < m_properties.lastFrameReal) &&
(m_framesInProcess < m_maxThreads) &&
(m_framesCache.size() < m_cachedFramesLimit) &&
(m_properties.jobState == JobState::Running))
{
m_pVapourSynthScriptProcessor->requestFrameAsync(
m_lastFrameRequested + 1);
m_lastFrameRequested++;
}
Frame frame(m_lastFrameProcessed + 1, 0, nullptr);
std::list<Frame>::iterator it = std::find(m_framesCache.begin(),
m_framesCache.end(), frame);
if(it == m_framesCache.end())
return;
frame.cpOutputFrame = it->cpOutputFrame;
// VapourSynth frames are padded so every line has aligned address.
// But encoder expects frames tightly packed. We pack frame lines
// into an intermediate buffer, because writing whole frame at once
// is faster than feeding it to encoder line by line.
size_t currentDataSize = 0;
Q_ASSERT(m_cpVideoInfo);
const VSVideoFormat * cpFormat = &m_cpVideoInfo->format;
if(m_pFrameHeaderWriter->needFramePrefix())
{
QByteArray framePrefix =
m_pFrameHeaderWriter->framePrefix(frame.cpOutputFrame);
int prefixSize = framePrefix.size();
if(prefixSize > 0)
{
if((size_t)prefixSize > m_framebuffer.size())
m_framebuffer.resize(prefixSize);
memcpy(m_framebuffer.data(), framePrefix.data(), prefixSize);
currentDataSize += prefixSize;
}
}
for(int i = 0; i < cpFormat->numPlanes; ++i)
{
const uint8_t * cpPlane =
m_cpVSAPI->getReadPtr(frame.cpOutputFrame, i);
int stride = m_cpVSAPI->getStride(frame.cpOutputFrame, i);
int width = m_cpVSAPI->getFrameWidth(frame.cpOutputFrame, i);
int height = m_cpVSAPI->getFrameHeight(frame.cpOutputFrame, i);
int bytes = cpFormat->bytesPerSample;
size_t planeSize = width * bytes * height;
size_t neededFramebufferSize = currentDataSize + planeSize;
if(neededFramebufferSize > m_framebuffer.size())
m_framebuffer.resize(neededFramebufferSize);
int framebufferStride = width * bytes;
vsh::bitblt(m_framebuffer.data() + currentDataSize, framebufferStride,
cpPlane, stride, framebufferStride, height);
currentDataSize += planeSize;
}
if(m_pFrameHeaderWriter->needFramePostfix())
{
QByteArray framePostfix =
m_pFrameHeaderWriter->framePostfix(frame.cpOutputFrame);
int postfixSize = framePostfix.size();
if(postfixSize > 0)
{
size_t neededFramebufferSize = currentDataSize + postfixSize;
if(neededFramebufferSize > m_framebuffer.size())
m_framebuffer.resize(neededFramebufferSize);
memcpy(m_framebuffer.data() + currentDataSize,
framePostfix.data(), postfixSize);
currentDataSize += postfixSize;
}
}
m_encodingState = EncodingState::WritingFrame;
m_bytesToWrite = currentDataSize;
m_bytesWritten = 0;
qint64 bytesWritten =
m_process.write(m_framebuffer.data(), (qint64)m_bytesToWrite);
if(bytesWritten < 0)
{
m_encodingState = EncodingState::Aborting;
changeStateAndNotify(JobState::FailedCleanUp);
emit signalLogMessage(tr("Error on writing data to encoder. "
"Aborting."), LOG_STYLE_ERROR);
cleanUpEncoding();
return;
}
// Wait until encoder reads the frame.
// Then this function will be called again.
}
// END OF void vsedit::Job::processFramesQueue()
//==============================================================================
void vsedit::Job::finishEncodingCLI()
{
if((m_process.state() == QProcess::Running) ||
m_pVapourSynthScriptProcessor->isInitialized())
return;
if(m_encodingState == EncodingState::Finishing)
{
emit signalLogMessage(tr("Finished encoding."), LOG_STYLE_POSITIVE);
changeStateAndNotify(JobState::CompletedCleanUp);
}
else if(m_encodingState == EncodingState::Aborting)
{
emit signalLogMessage(tr("Aborted encoding."), LOG_STYLE_WARNING);
}
m_encodingState = EncodingState::Idle;
const std::map<JobState, JobState> stateToSwitch =
{
{JobState::Aborting, JobState::Aborted},
{JobState::FailedCleanUp, JobState::Failed},
{JobState::CompletedCleanUp, JobState::Completed},
};
std::map<JobState, JobState>::const_iterator it =
stateToSwitch.find(m_properties.jobState);
if(it != stateToSwitch.cend())
changeStateAndNotify(it->second);
}
// END OF void vsedit::Job::finishEncodingCLI()
//==============================================================================
void vsedit::Job::memorizeEncodingTime()
{
if(m_properties.type != JobType::EncodeScriptCLI)
return;
m_memorizedEncodingTime += currentEncodingRangeTime();
m_encodeRangeStartTime = hr_clock::now();
}
// END OF void vsedit::Job::memorizeEncodingTime()
//==============================================================================
void vsedit::Job::updateFPS()
{
if(m_properties.type != JobType::EncodeScriptCLI)
return;
double totalTime = m_memorizedEncodingTime;
const JobState validStates[] = {JobState::Running, JobState::Pausing};
if(vsedit::contains(validStates, m_properties.jobState))
totalTime += currentEncodingRangeTime();
m_properties.fps = (double)m_properties.framesProcessed / totalTime;
}
// END OF void vsedit::Job::updateFPS()
//==============================================================================
double vsedit::Job::currentEncodingRangeTime() const
{
if(m_properties.type != JobType::EncodeScriptCLI)
return 0.0;
hr_time_point now = hr_clock::now();
double rangeTime = duration_to_double(now - m_encodeRangeStartTime);
return rangeTime;
}
// END OF double vsedit::Job::currentEncodingRangeTime() const
//==============================================================================
================================================
FILE: common-src/jobs/job.h
================================================
#ifndef JOB_H_INCLUDED
#define JOB_H_INCLUDED
#include "../../../common-src/settings/settings_definitions_core.h"
#include "../../../common-src/chrono.h"
#include "../../../common-src/helpers.h"
#include "../../../common-src/log/styled_log_view_core.h"
#include "../../../common-src/log/vs_editor_log_definitions.h"
#include "../../../common-src/vapoursynth/vs_script_processor_structures.h"
#include "../../../common-src/jobs/job_variables.h"
#include <QObject>
#include <QUuid>
#include <QDateTime>
#include <QProcess>
#include <vector>
class SettingsManagerCore;
class VSScriptLibrary;
class VapourSynthScriptProcessor;
class FrameHeaderWriter;
namespace vsedit
{
class Job : public QObject, public JobVariables
{
Q_OBJECT
public:
Job(const JobProperties & a_properties = JobProperties(),
SettingsManagerCore * a_pSettingsManager = nullptr,
VSScriptLibrary * a_pVSScriptLibrary = nullptr,
QObject * a_pParent = nullptr);
virtual ~Job();
enum class EncodingState
{
Idle,
CheckingEncoderSanity,
StartingEncoder,
WritingHeader,
WaitingForFrames,
WritingFrame,
EncoderCrashed,
Finishing,
Aborting,
};
virtual bool isActive() const;
virtual QUuid id() const;
virtual bool setId(const QUuid & a_id);
virtual JobType type() const;
virtual bool setType(JobType a_type);
virtual QString scriptName() const;
virtual bool setScriptName(const QString & a_scriptName);
virtual QString scriptText() const;
virtual bool setScriptText(const QString & a_scriptText);
virtual EncodingHeaderType encodingHeaderType() const;
virtual bool setEncodingHeaderType(EncodingHeaderType a_headerType);
virtual QString executablePath() const;
virtual bool setExecutablePath(const QString & a_path);
virtual QString arguments() const;
virtual bool setArguments(const QString & a_arguments);
virtual QString shellCommand() const;
virtual bool setShellCommand(const QString & a_command);
virtual JobState state() const;
virtual bool setState(JobState a_state);
virtual std::vector<QUuid> dependsOnJobIds() const;
virtual bool setDependsOnJobIds(const std::vector<QUuid> & a_ids);
virtual QString subject() const;
virtual int firstFrame() const;
virtual bool setFirstFrame(int a_frame);
virtual int lastFrame() const;
virtual bool setLastFrame(int a_frame);
virtual int framesProcessed() const;
virtual int framesTotal() const;
virtual double fps() const;
virtual double secondsToFinish() const;
virtual size_t framesInQueue() const;
virtual size_t framesInProcess() const;
virtual size_t maxThreads() const;
virtual JobProperties properties() const;
virtual bool setProperties(const JobProperties & a_properties);
virtual const VSVideoInfo * videoInfo() const;
virtual bool initialize();
virtual void cleanUpEncoding();
public slots:
virtual void start();
virtual void pause();
virtual void abort();
signals:
void signalPropertiesChanged();
void signalStateChanged(JobState a_newState, JobState a_oldState);
void signalProgressChanged();
void signalStartTimeChanged();
void signalEndTimeChanged();
void signalLogMessage(const QString & a_message,
const QString & a_style = LOG_STYLE_DEFAULT);
protected slots:
virtual void slotProcessStarted();
virtual void slotProcessFinished(int a_exitCode,
QProcess::ExitStatus a_exitStatus);
virtual void slotProcessError(QProcess::ProcessError a_error);
virtual void slotProcessReadChannelFinished();
virtual void slotProcessBytesWritten(qint64 a_bytes);
virtual void slotProcessReadyReadStandardError();
virtual void slotWriteLogMessage(int a_messageType,
const QString & a_message);
virtual void slotFrameQueueStateChanged(size_t a_inQueue,
size_t a_inProcess, size_t a_maxThreads, double a_usedCacheRatio);
virtual void slotScriptProcessorFinalized();
virtual void slotReceiveFrame(int a_frameNumber, int a_outputIndex,
const VSFrame * a_cpOutputFrame,
const VSFrame * a_cpPreviewFrame);
virtual void slotFrameRequestDiscarded(int a_frameNumber,
int a_outputIndex, const QString & a_reason);
protected:
virtual void fillVariables() override;
virtual void changeStateAndNotify(JobState a_state);
virtual void startEncodeScriptCLI();
virtual void startRunProcess();
virtual void startRunShellCommand();
virtual QString decodeArguments(const QString & a_arguments) const;
virtual void clearFramesCache();
virtual void processFramesQueue();
virtual void finishEncodingCLI();
virtual void memorizeEncodingTime();
virtual void updateFPS();
virtual double currentEncodingRangeTime() const;
JobProperties m_properties;
QProcess m_process;
std::vector<char> m_framebuffer;
int m_lastFrameProcessed;
int m_lastFrameRequested;
EncodingState m_encodingState;
size_t m_bytesToWrite;
size_t m_bytesWritten;
SettingsManagerCore * m_pSettingsManager;
VSScriptLibrary * m_pVSScriptLibrary;
VapourSynthScriptProcessor * m_pVapourSynthScriptProcessor;
const VSAPI * m_cpVSAPI;
const VSVideoInfo * m_cpVideoInfo;
FrameHeaderWriter * m_pFrameHeaderWriter;
std::list<Frame> m_framesCache;
size_t m_cachedFramesLimit;
size_t m_framesInQueue;
size_t m_framesInProcess;
size_t m_maxThreads;
hr_time_point m_encodeRangeStartTime;
double m_memorizedEncodingTime;
};
}
#endif // JOB_H_INCLUDED
================================================
FILE: common-src/jobs/job_variables.cpp
================================================
#include "job_variables.h"
#include <QObject>
//==============================================================================
const QString JobVariables::TOKEN_WIDTH = "{w}";
const QString JobVariables::TOKEN_HEIGHT = "{h}";
const QString JobVariables::TOKEN_FPS_NUMERATOR = "{fpsn}";
const QString JobVariables::TOKEN_FPS_DENOMINATOR = "{fpsd}";
const QString JobVariables::TOKEN_FPS = "{fps}";
const QString JobVariables::TOKEN_BITDEPTH = "{bits}";
const QString JobVariables::TOKEN_SCRIPT_DIRECTORY = "{sd}";
const QString JobVariables::TOKEN_SCRIPT_NAME = "{sn}";
const QString JobVariables::TOKEN_FRAMES_NUMBER = "{f}";
const QString JobVariables::TOKEN_SUBSAMPLING = "{ss}";
//==============================================================================
JobVariables::JobVariables()
{
fillVariables();
}
// END OF JobVariables::JobVariables()
//==============================================================================
std::vector<vsedit::VariableToken> JobVariables::variables() const
{
std::vector<vsedit::VariableToken> cutVariables;
for(const vsedit::VariableToken & variable : m_variables)
{
vsedit::VariableToken cutVariable =
{variable.token, variable.description, std::function<QString()>()};
cutVariables.push_back(cutVariable);
}
return cutVariables;
}
// END OF std::vector<vsedit::VariableToken> JobVariables::variables() const
//==============================================================================
void JobVariables::fillVariables()
{
m_variables =
{
{TOKEN_WIDTH, QObject::tr("video width"),
std::function<QString()>()},
{TOKEN_HEIGHT, QObject::tr("video height"),
std::function<QString()>()},
{TOKEN_FPS_NUMERATOR, QObject::tr("video framerate numerator"),
std::function<QString()>()},
{TOKEN_FPS_DENOMINATOR, QObject::tr("video framerate denominator"),
std::function<QString()>()},
{TOKEN_FPS, QObject::tr("video framerate as fraction"),
std::function<QString()>()},
{TOKEN_BITDEPTH, QObject::tr("video colour bitdepth"),
std::function<QString()>()},
{TOKEN_SCRIPT_DIRECTORY, QObject::tr("script directory"),
std::function<QString()>()},
{TOKEN_SCRIPT_NAME, QObject::tr("script name without extension"),
std::function<QString()>()},
{TOKEN_FRAMES_NUMBER, QObject::tr("total frames number"),
std::function<QString()>()},
{TOKEN_SUBSAMPLING, QObject::tr("subsampling string (like 420)"),
std::function<QString()>()},
};
std::sort(m_variables.begin(), m_variables.end(),
[&](const vsedit::VariableToken & a_first,
const vsedit::VariableToken & a_second) -> bool
{
return (a_first.token.length() > a_second.token.length());
});
}
// END OF void JobVariables::fillVariables()
//==============================================================================
================================================
FILE: common-src/jobs/job_variables.h
================================================
#ifndef JOB_VARIABLES_H_INCLUDED
#define JOB_VARIABLES_H_INCLUDED
#include "../helpers.h"
#include <functional>
#include <vector>
class JobVariables
{
public:
JobVariables();
virtual std::vector<vsedit::VariableToken> variables() const;
protected:
static const QString TOKEN_WIDTH;
static const QString TOKEN_HEIGHT;
static const QString TOKEN_FPS_NUMERATOR;
static const QString TOKEN_FPS_DENOMINATOR;
static const QString TOKEN_FPS;
static const QString TOKEN_BITDEPTH;
static const QString TOKEN_SCRIPT_DIRECTORY;
static const QString TOKEN_SCRIPT_NAME;
static const QString TOKEN_FRAMES_NUMBER;
static const QString TOKEN_SUBSAMPLING;
virtual void fillVariables();
std::vector<vsedit::VariableToken> m_variables;
};
#endif // JOB_VARIABLES_H_INCLUDED
================================================
FILE: common-src/libp2p/COPYING
================================================
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
================================================
FILE: common-src/libp2p/README.md
================================================
# libp2p
Pack/unpack pixels.
The "p2p" library implements conversion between packed and planar image
formats. A packed format is any memory layout that stores more than one image
component ("plane") in a single array. For example, the common ARGB format
stores pixels as an array of DWORDs holding all components for each pixel. In
contrast, a planar format stores each image component in its own array.
Building
------
libp2p is intended for embedding within other libraries and applications. The
header "p2p.h" contains a template library for generating packing and unpacking
routines, which can be used to instantiate functions for various pixel formats.
"v210.cpp" holds a special-case implementation for the Apple ProRes "v210"
format. "p2p_api.h" and "p2p_api.cpp" implement a "C" wrapper for a fixed set
of commonly encountered packed formats. If the "C" wrapper is used from another
library, a method to control symbol visibility should be used to prevent name
conflicts with other, potentially incompatible, instances of libp2p.
================================================
FILE: common-src/libp2p/p2p.h
================================================
#ifndef P2P_H_
#define P2P_H_
#include <cstddef>
#include <cstdint>
#include <climits>
#include <type_traits>
#ifdef P2P_SIMD
#include <typeinfo>
#endif
#ifdef _WIN32
#include <stdlib.h> // _byteswap_x
#endif
#ifdef P2P_USER_NAMESPACE
#define P2P_NAMESPACE P2P_USER_NAMESPACE
#else
#define P2P_NAMESPACE p2p
#endif
#ifdef _WIN32
#define P2P_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define P2P_BIG_ENDIAN
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define P2P_LITTLE_ENDIAN
#endif
#endif
static_assert(CHAR_BIT == 8, "8-bit char required");
namespace P2P_NAMESPACE {
// Tag types for endian.
struct little_endian_t {};
struct big_endian_t {};
#if defined(P2P_BIG_ENDIAN)
typedef big_endian_t native_endian_t;
#elif defined(P2P_LITTLE_ENDIAN)
typedef little_endian_t native_endian_t;
#else
#error wrong endian
#endif
#undef P2P_BIG_ENDIAN
#undef P2P_LITTLE_ENDIAN
namespace detail {
// Size of object in bits.
template <class T>
struct bit_size {
static const size_t value = sizeof(T) * CHAR_BIT;
};
// Make integers from bytes.
constexpr uint16_t make_u16(uint8_t a, uint8_t b)
{
return (a << 8) | b;
}
constexpr uint32_t make_u32(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
return (static_cast<uint32_t>(make_u16(a, b)) << 16) | make_u16(c, d);
}
constexpr uint64_t make_u64(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h)
{
return (static_cast<uint64_t>(make_u32(a, b, c, d)) << 32) | make_u32(e, f, g, h);
}
template <class T>
constexpr uint8_t get_u8(T x, unsigned i)
{
return static_cast<uint8_t>((x >> (bit_size<T>::value - 8 * i - 8)) & 0xFF);
}
// Fake 24 and 48-bit integers.
struct uint24 {
uint8_t x[3];
uint24() = default;
constexpr uint24(uint8_t a, uint8_t b, uint8_t c) : x{ a, b, c }
{
}
template <class T = native_endian_t>
explicit constexpr uint24(uint32_t val,
typename std::enable_if<std::is_same<T, big_endian_t>::value>::type * = 0) :
x{ get_u8(val, 1), get_u8(val, 2), get_u8(val, 3) }
{
}
template <class T = native_endian_t>
explicit constexpr uint24(uint32_t val,
typename std::enable_if<std::is_same<T, little_endian_t>::value>::type * = 0) :
x{ get_u8(val, 3), get_u8(val, 2), get_u8(val, 1) }
{
}
template <class T = native_endian_t,
typename std::enable_if<std::is_same<T, big_endian_t>::value>::type * = nullptr>
constexpr uint32_t to_u32() const
{
return make_u32(0, x[0], x[1], x[2]);
}
template <class T = native_endian_t,
typename std::enable_if<std::is_same<T, little_endian_t>::value>::type * = nullptr>
constexpr uint32_t to_u32() const
{
return make_u32(0, x[2], x[1], x[0]);
}
constexpr operator uint32_t() const { return to_u32(); }
};
struct uint48 {
uint8_t x[6];
uint48() = default;
constexpr uint48(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f) : x{ a, b, c, d, e, f }
{
}
template <class T = native_endian_t>
explicit constexpr uint48(uint64_t val,
typename std::enable_if<std::is_same<T, big_endian_t>::value>::type * = 0) :
x{ get_u8(val, 2), get_u8(val, 3), get_u8(val, 4), get_u8(val, 5), get_u8(val, 6), get_u8(val, 7) }
{
}
template <class T = native_endian_t>
explicit constexpr uint48(uint64_t val,
typename std::enable_if<std::is_same<T, little_endian_t>::value>::type * = 0) :
x{ get_u8(val, 7), get_u8(val, 6), get_u8(val, 5), get_u8(val, 4), get_u8(val, 3), get_u8(val, 2) }
{
}
template <class T = native_endian_t,
typename std::enable_if<std::is_same<T, big_endian_t>::value>::type * = nullptr>
constexpr uint64_t to_u64() const
{
return make_u64(0, 0, x[0], x[1], x[2], x[3], x[4], x[5]);
}
template <class T = native_endian_t,
typename std::enable_if<std::is_same<T, little_endian_t>::value>::type * = nullptr>
constexpr uint64_t to_u64() const
{
return make_u64(0, 0, x[5], x[4], x[3], x[2], x[1], x[0]);
}
constexpr operator uint64_t() const { return to_u64(); }
};
static_assert(std::is_pod<uint24>::value, "uint24 must be POD");
static_assert(std::is_pod<uint48>::value, "uint48 must be POD");
static_assert(sizeof(uint24) == 3, "uint24 must not have padding");
static_assert(sizeof(uint48) == 6, "uint48 must not have padding");
// Endian conversions.
template <class Endian, class T,
typename std::enable_if<std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
T endian_swap(T x)
{
return x;
}
template <class Endian,
typename std::enable_if<!std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
uint16_t endian_swap(uint16_t x)
{
#ifdef _WIN32
return _byteswap_ushort(x);
#else
return __builtin_bswap16(x);
#endif
}
template <class Endian,
typename std::enable_if<!std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
uint32_t endian_swap(uint32_t x)
{
#ifdef _WIN32
return _byteswap_ulong(x);
#else
return __builtin_bswap32(x);
#endif
}
template <class Endian,
typename std::enable_if<!std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
uint64_t endian_swap(uint64_t x)
{
#ifdef _WIN32
return _byteswap_uint64(x);
#else
return __builtin_bswap64(x);
#endif
}
template <class Endian,
typename std::enable_if<!std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
uint24 endian_swap(uint24 x)
{
return{ x.x[2], x.x[1], x.x[0] };
}
template <class Endian,
typename std::enable_if<!std::is_same<Endian, native_endian_t>::value>::type * = nullptr>
uint48 endian_swap(uint48 x)
{
return{ x.x[5], x.x[4], x.x[3], x.x[2], x.x[1], x.x[0] };
}
// Treat u32 as array of u8.
struct mask4 {
uint32_t x;
constexpr uint8_t operator[](unsigned i) const { return get_u8(x, i); }
constexpr bool contains(unsigned val) const
{
return (*this)[0] == val || (*this)[1] == val || (*this)[2] == val || (*this)[3] == val;
}
constexpr unsigned find(uint8_t val) const
{
return (*this)[0] == val ? 0 : (*this)[1] == val ? 1 : (*this)[2] == val ? 2 : (*this)[3] == val ? 3 : ~0U;
}
};
// Native integer type for arithmetic.
template <class T>
struct numeric_type {
typedef T type;
};
template <>
struct numeric_type<uint24> {
typedef uint32_t type;
};
template <>
struct numeric_type<uint48> {
typedef uint64_t type;
};
} // namespace detail
enum {
C_Y = 0,
C_U = 1,
C_V = 2,
C_R = 0,
C_G = 1,
C_B = 2,
C_A = 3,
C__ = 0xFF,
};
// Packed integer constants for template parameters.
constexpr uint32_t make_mask(uint8_t x)
{
return detail::make_u32(x, x, x, x);
}
constexpr uint32_t make_mask(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
return detail::make_u32(a, b, c, d);
}
// Select type by endian.
template <class Big, class Little>
struct endian_select {
typedef typename std::conditional<std::is_same<native_endian_t, big_endian_t>::value, Big, Little>::type type;
};
template <class Planar,
class Packed,
class Endian,
unsigned PelPerPack,
unsigned Subsampling,
uint32_t ComponentMask,
uint32_t ShiftMask,
uint32_t DepthMask>
struct pack_traits {
static_assert(std::is_pod<Planar>::value, "must be POD");
static_assert(std::is_pod<Packed>::value, "must be POD");
typedef Planar planar_type;
typedef Packed packed_type;
typedef Endian endian;
static const unsigned pel_per_pack = PelPerPack;
static const unsigned subsampling = Subsampling;
static constexpr detail::mask4 component_mask{ ComponentMask };
static constexpr detail::mask4 shift_mask{ ShiftMask };
static constexpr detail::mask4 depth_mask{ DepthMask };
};
template <class Planar, class Packed, class Endian, unsigned PelPerPack, unsigned Subsampling, uint32_t ComponentMask, uint32_t ShiftMask, uint32_t DepthMask>
constexpr detail::mask4 pack_traits<Planar, Packed, Endian, PelPerPack, Subsampling, ComponentMask, ShiftMask, DepthMask>::component_mask;
template <class Planar, class Packed, class Endian, unsigned PelPerPack, unsigned Subsampling, uint32_t ComponentMask, uint32_t ShiftMask, uint32_t DepthMask>
constexpr detail::mask4 pack_traits<Planar, Packed, Endian, PelPerPack, Subsampling, ComponentMask, ShiftMask, DepthMask>::shift_mask;
template <class Planar, class Packed, class Endian, unsigned PelPerPack, unsigned Subsampling, uint32_t ComponentMask, uint32_t ShiftMask, uint32_t DepthMask>
constexpr detail::mask4 pack_traits<Planar, Packed, Endian, PelPerPack, Subsampling, ComponentMask, ShiftMask, DepthMask>::depth_mask;
// Base template for 4:4:4 packings.
//
// Much literature treats 4:4:4 triplets as single machine words, implying a
// reversed component order on LE and BE.
//
// The _be and _le templates accept a component mask beginning from the MSB of
// the packed word to accomodate this.
template <class Planar, class Packed, uint32_t ComponentMask>
using byte_packed_444_be = pack_traits<
Planar, Packed, big_endian_t, 1, 0,
ComponentMask,
make_mask(3, 2, 1, 0) * detail::bit_size<Planar>::value,
make_mask(detail::bit_size<Planar>::value)>;
template <class Planar, class Packed, uint32_t ComponentMask>
using byte_packed_444_le = pack_traits<
Planar, Packed, little_endian_t, 1, 0,
ComponentMask,
make_mask(3, 2, 1, 0) * detail::bit_size<Planar>::value,
make_mask(detail::bit_size<Planar>::value)>;
// Common 444 packings.
using packed_rgb24_be = byte_packed_444_be<uint8_t, detail::uint24, make_mask(C__, C_R, C_G, C_B)>;
using packed_rgb24_le = byte_packed_444_le<uint8_t, detail::uint24, make_mask(C__, C_R, C_G, C_B)>;
using packed_rgb24 = endian_select<packed_rgb24_be, packed_rgb24_le>::type;
using packed_argb32_be = byte_packed_444_be<uint8_t, uint32_t, make_mask(C_A, C_R, C_G, C_B)>;
using packed_argb32_le = byte_packed_444_le<uint8_t, uint32_t, make_mask(C_A, C_R, C_G, C_B)>;
using packed_argb32 = endian_select<packed_argb32_be, packed_argb32_le>::type;
using packed_ayuv_be = packed_argb32_be;
using packed_ayuv_le = packed_argb32_le;
using packed_ayuv = packed_argb32;
using packed_rgb48_be = byte_packed_444_be<uint16_t, detail::uint48, make_mask(C__, C_R, C_G, C_B)>;
using packed_rgb48_le = byte_packed_444_le<uint16_t, detail::uint48, make_mask(C__, C_R, C_G, C_B)>;
using packed_rgb48 = endian_select<packed_rgb48_be, packed_rgb48_le>::type;
using packed_argb64_be = byte_packed_444_be<uint16_t, uint64_t, make_mask(C_A, C_R, C_G, C_B)>;
using packed_argb64_le = byte_packed_444_le<uint16_t, uint64_t, make_mask(C_A, C_R, C_G, C_B)>;
using packed_argb64 = endian_select<packed_argb64_be, packed_argb64_le>::type;
using packed_rgba32_be = byte_packed_444_be<uint8_t, uint32_t, make_mask(C_R, C_G, C_B, C_A)>;
using packed_rgba32_le = byte_packed_444_le<uint8_t, uint32_t, make_mask(C_R, C_G, C_B, C_A)>;
using packed_rgba32 = endian_select<packed_rgba32_be, packed_rgba32_le>::type;
using packed_rgba64_be = byte_packed_444_be<uint16_t, uint64_t, make_mask(C_R, C_G, C_B, C_A)>;
using packed_rgba64_le = byte_packed_444_le<uint16_t, uint64_t, make_mask(C_R, C_G, C_B, C_A)>;
using packed_rgba64 = endian_select<packed_rgba64_be, packed_rgba64_le>::type;
using packed_abgr64_be = byte_packed_444_be<uint16_t, uint64_t, make_mask(C_A, C_B, C_G, C_R)>;
using packed_abgr64_le = byte_packed_444_le<uint16_t, uint64_t, make_mask(C_A, C_B, C_G, C_R)>;
using packed_abgr64 = endian_select<packed_abgr64_be, packed_abgr64_le>::type;
using packed_bgr48_be = byte_packed_444_be<uint16_t, detail::uint48, make_mask(C__, C_B, C_G, C_R)>;
using packed_bgr48_le = byte_packed_444_le<uint16_t, detail::uint48, make_mask(C__, C_B, C_G, C_R)>;
using packed_bgr48 = endian_select<packed_bgr48_be, packed_bgr48_le>::type;
using packed_bgra64_be = byte_packed_444_be<uint16_t, uint64_t, make_mask(C_B, C_G, C_R, C_A)>;
using packed_bgra64_le = byte_packed_444_le<uint16_t, uint64_t, make_mask(C_B, C_G, C_R, C_A)>;
using packed_bgra64 = endian_select<packed_bgra64_be, packed_bgra64_le>::type;
// D3D A2R10G10B10.
using packed_rgb30_be = pack_traits<
uint16_t, uint32_t, big_endian_t, 1, 0,
make_mask(C_A, C_R, C_G, C_B),
make_mask(30, 20, 10, 0),
make_mask(2, 10, 10, 10)>;
using packed_rgb30_le = pack_traits<
uint16_t, uint32_t, little_endian_t, 1, 0,
make_mask(C_A, C_R, C_G, C_B),
make_mask(30, 20, 10, 0),
make_mask(2, 10, 10, 10)>;
using packed_rgb30 = endian_select<packed_rgb30_be, packed_rgb30_le>::type;
// MS Y410 and Y416 formats.
using packed_y410_be = pack_traits<
uint16_t, uint32_t, big_endian_t, 1, 0,
make_mask(C_A, C_V, C_Y, C_U),
make_mask(30, 20, 10, 0),
make_mask(2, 10, 10, 10)>;
using packed_y410_le = pack_traits<
uint16_t, uint32_t, little_endian_t, 1, 0,
make_mask(C_A, C_V, C_Y, C_U),
make_mask(30, 20, 10, 0),
make_mask(2, 10, 10, 10)>;
using packed_y410 = endian_select<packed_y410_be, packed_y410_le>::type;
using packed_y416_be = byte_packed_444_be<uint16_t, uint64_t, make_mask(C_A, C_V, C_Y, C_U)>;
using packed_y416_le = byte_packed_444_le<uint16_t, uint64_t, make_mask(C_A, C_V, C_Y, C_U)>;
using packed_y416 = endian_select<packed_y416_be, packed_y416_le>::type;
// Base template for YUY2-like 4:2:2 packings.
//
// The component order in both BE and LE is the same. Only the bytes of the
// individual component words are reversed.
//
// The _be and _le templates accept a component mask beginning from the low
// memory address of the packed word to accomodate this.
template <class Planar, class Packed, uint32_t ComponentMask, unsigned ExtraShift = 0>
using byte_packed_422_be = pack_traits<
Planar, Packed, big_endian_t, 2, 1,
ComponentMask,
make_mask(3, 2, 1, 0) * detail::bit_size<Planar>::value + make_mask(ExtraShift),
make_mask(detail::bit_size<Planar>::value) - make_mask(ExtraShift)>;
template <class Planar, class Packed, uint32_t ComponentMask, unsigned ExtraShift = 0>
using byte_packed_422_le = pack_traits<
Planar, Packed, little_endian_t, 2, 1,
ComponentMask,
make_mask(0, 1, 2, 3) * detail::bit_size<Planar>::value + make_mask(ExtraShift),
make_mask(detail::bit_size<Planar>::value) - make_mask(ExtraShift)>;
// YUY2.
using packed_yuy2 = byte_packed_422_be<uint8_t, uint32_t, make_mask(C_Y, C_U, C_Y, C_V)>;
using packed_uyvy = byte_packed_422_be<uint8_t, uint32_t, make_mask(C_U, C_Y, C_V, C_Y)>;
// MS Y210 and Y216 formats.
using packed_y210_be = byte_packed_422_be<uint16_t, uint64_t, make_mask(C_Y, C_U, C_Y, C_V), 6>;
using packed_y210_le = byte_packed_422_le<uint16_t, uint64_t, make_mask(C_Y, C_U, C_Y, C_V), 6>;
using packed_y210 = endian_select<packed_y210_be, packed_y210_le>::type;
using packed_y216_be = byte_packed_422_be<uint16_t, uint64_t, make_mask(C_Y, C_U, C_Y, C_V)>;
using packed_y216_le = byte_packed_422_le<uint16_t, uint64_t, make_mask(C_Y, C_U, C_Y, C_V)>;
using packed_y216 = endian_select<packed_y216_be, packed_y216_le>::type;
// Apple v210 format. Handled by special-case code. Only the LE ordering is found in Qt files.
struct packed_v210_be {};
struct packed_v210_le {};
using packed_v210 = endian_select<packed_v210_le, packed_v210_be>::type;
// Apple v216 format. Only the LE ordering is found in Qt files.
using packed_v216_be = byte_packed_422_be<uint16_t, uint64_t, make_mask(C_U, C_Y, C_V, C_Y)>;
using packed_v216_le = byte_packed_422_le<uint16_t, uint64_t, make_mask(C_U, C_Y, C_V, C_Y)>;
using packed_v216 = endian_select<packed_v216_le, packed_v216_be>::type;
// Base template for chroma-interleaved half packings.
//
// The literature treats UV pairs as single machine words, implying a reversed
// component order between BE and LE.
template <class Planar, class Packed, unsigned ExtraShift = 0>
using byte_packed_nv_be = pack_traits<
Planar, Packed, big_endian_t, 2, 1,
make_mask(C__, C__, C_V, C_U),
make_mask(0, 0, 1, 0) * detail::bit_size<Planar>::value + make_mask(ExtraShift),
make_mask(detail::bit_size<Planar>::value) - make_mask(ExtraShift)>;
template <class Planar, class Packed, unsigned ExtraShift = 0>
using byte_packed_nv_le = pack_traits<
Planar, Packed, little_endian_t, 2, 1,
make_mask(C__, C__, C_V, C_U),
make_mask(0, 0, 1, 0) * detail::bit_size<Planar>::value + make_mask(ExtraShift),
make_mask(detail::bit_size<Planar>::value) - make_mask(ExtraShift)>;
using packed_nv12_be = byte_packed_nv_be<uint8_t, uint16_t>; // AKA NV21.
using packed_nv12_le = byte_packed_nv_le<uint8_t, uint16_t>;
using packed_nv12 = endian_select<packed_nv12_be, packed_nv12_le>::type;
// MS P010, P016, P210, and P216 formats.
using packed_p010_be = byte_packed_nv_be<uint16_t, uint32_t, 6>;
using packed_p010_le = byte_packed_nv_le<uint16_t, uint32_t, 6>;
using packed_p010 = endian_select<packed_p010_be, packed_p010_le>::type;
using packed_p016_be = byte_packed_nv_be<uint16_t, uint32_t>;
using packed_p016_le = byte_packed_nv_le<uint16_t, uint32_t>;
using packed_p016 = endian_select<packed_p016_be, packed_p016_le>::type;
using packed_p210_be = packed_p010_be;
using packed_p210_le = packed_p010_le;
using packed_p210 = packed_p010;
using packed_p216_be = packed_p016_be;
using packed_p216_le = packed_p016_le;
using packed_p216 = packed_p016;
#ifdef P2P_SIMD
namespace detail {
// Runtime function dispatch.
typedef void (*unpack_func)(const void *, void * const *, unsigned, unsigned);
typedef void (*pack_func)(const void * const *, void *, unsigned, unsigned);
unpack_func search_unpack_func(const std::type_info &ti);
pack_func search_pack_func(const std::type_info &ti, bool alpha_one_fill);
template <class Traits>
unpack_func search_unpack_func(unpack_func default_func)
{
unpack_func func = search_unpack_func(typeid(Traits));
return func ? func : default_func;
}
template <class Traits, bool AlphaOneFill>
pack_func search_pack_func(pack_func default_func)
{
pack_func func = search_pack_func(typeid(Traits), AlphaOneFill);
return func ? func : default_func;
}
} // namespace detail
#endif // P2P_SIMD
// Conversions.
template <class Traits>
class packed_to_planar {
typedef typename Traits::planar_type planar_type;
typedef typename Traits::packed_type packed_type;
typedef typename detail::numeric_type<packed_type>::type numeric_type;
typedef typename Traits::endian endian;
#ifdef P2P_SIMD
static detail::unpack_func s_delegate;
#endif
static numeric_type get_mask(unsigned c)
{
return ~static_cast<numeric_type>(0) >> (detail::bit_size<numeric_type>::value - Traits::depth_mask[c]);
}
static planar_type get_component(numeric_type x, unsigned c)
{
return static_cast<planar_type>((x >> Traits::shift_mask[c]) & get_mask(c));
}
static void unpack_impl(const void *src, void * const dst[4], unsigned left, unsigned right)
{
const packed_type *src_p = static_cast<const packed_type *>(src);
planar_type *dst_p[4] = {
static_cast<planar_type *>(dst[0]), static_cast<planar_type *>(dst[1]),
static_cast<planar_type *>(dst[2]), static_cast<planar_type *>(dst[3]),
};
bool alpha_enabled = dst[C_A] != nullptr;
// Adjust pointers.
src_p += left / Traits::pel_per_pack;
dst_p[0] += Traits::component_mask.contains(0) ? left : 0;
dst_p[1] += Traits::component_mask.contains(1) ? (left >> Traits::subsampling) : 0;
dst_p[2] += Traits::component_mask.contains(2) ? (left >> Traits::subsampling) : 0;
dst_p[3] += Traits::component_mask.contains(3) ? left : 0;
#define P2P_COMPONENT_ENABLED(c) ((Traits::component_mask[c] != C__) && (Traits::component_mask[c] != C_A || alpha_enabled))
for (unsigned i = left; i < right; i += Traits::pel_per_pack) {
numeric_type x = detail::endian_swap<endian>(*src_p++);
if (P2P_COMPONENT_ENABLED(0))
*dst_p[Traits::component_mask[0]]++ = get_component(x, 0);
if (P2P_COMPONENT_ENABLED(1))
*dst_p[Traits::component_mask[1]]++ = get_component(x, 1);
if (P2P_COMPONENT_ENABLED(2))
*dst_p[Traits::component_mask[2]]++ = get_component(x, 2);
if (P2P_COMPONENT_ENABLED(3))
*dst_p[Traits::component_mask[3]]++ = get_component(x, 3);
}
#undef P2P_COMPONENT_ENABLED
}
public:
static void unpack(const void *src, void * const dst[4], unsigned left, unsigned right)
{
#ifdef P2P_SIMD
s_delegate(src, dst, left, right);
#else
unpack_impl(src, dst, left, right);
#endif
}
};
#ifdef P2P_SIMD
template <class Traits>
detail::unpack_func packed_to_planar<Traits>::s_delegate = detail::search_unpack_func<Traits>(packed_to_planar::unpack_impl);
#endif
template <class Traits, bool AlphaOneFill = false>
class planar_to_packed {
typedef typename Traits::planar_type planar_type;
typedef typename Traits::packed_type packed_type;
typedef typename detail::numeric_type<packed_type>::type numeric_type;
typedef typename Traits::endian endian;
#ifdef P2P_SIMD
static detail::pack_func s_delegate;
#endif
static numeric_type get_mask(unsigned c)
{
return ~static_cast<numeric_type>(0) >> (detail::bit_size<numeric_type>::value - Traits::depth_mask[c]);
}
static numeric_type get_component(planar_type x, unsigned c)
{
return (static_cast<numeric_type>(x) & get_mask(c)) << Traits::shift_mask[c];
}
static void pack_impl(const void * const src[4], void *dst, unsigned left, unsigned right)
{
const planar_type *src_p[4] = {
static_cast<const planar_type *>(src[0]), static_cast<const planar_type *>(src[1]),
static_cast<const planar_type *>(src[2]), static_cast<const planar_type *>(src[3]),
};
packed_type *dst_p = static_cast<packed_type *>(dst);
bool alpha_enabled = src[C_A] != nullptr;
// Adjust pointers.
src_p[0] += Traits::component_mask.contains(0) ? left : 0;
src_p[1] += Traits::component_mask.contains(1) ? (left >> Traits::subsampling) : 0;
src_p[2] += Traits::component_mask.contains(2) ? (left >> Traits::subsampling) : 0;
src_p[3] += Traits::component_mask.contains(3) ? left : 0;
dst_p += left / Traits::pel_per_pack;
#define P2P_COMPONENT_ENABLED(c) ((Traits::component_mask[c] != C__) && (Traits::component_mask[c] != C_A || alpha_enabled))
for (unsigned i = left; i < right; i += Traits::pel_per_pack) {
numeric_type x = 0;
if (AlphaOneFill && Traits::component_mask.contains(C_A) && !alpha_enabled)
x |= get_component(~static_cast<planar_type>(0), Traits::component_mask.find(C_A));
if (P2P_COMPONENT_ENABLED(0))
x |= get_component(*src_p[Traits::component_mask[0]]++, 0);
if (P2P_COMPONENT_ENABLED(1))
x |= get_component(*src_p[Traits::component_mask[1]]++, 1);
if (P2P_COMPONENT_ENABLED(2))
x |= get_component(*src_p[Traits::component_mask[2]]++, 2);
if (P2P_COMPONENT_ENABLED(3))
x |= get_component(*src_p[Traits::component_mask[3]]++, 3);
*dst_p++ = detail::endian_swap<endian>(static_cast<packed_type>(x));
}
#undef P2P_COMPONENT_ENABLED
}
public:
static void pack(const void * const src[4], void *dst, unsigned left, unsigned right)
{
#ifdef P2P_SIMD
s_delegate(src, dst, left, right);
#else
pack_impl(src, dst, left, right);
#endif
}
};
#ifdef P2P_SIMD
template <class Traits, bool AlphaOneFill>
detail::pack_func planar_to_packed<Traits, AlphaOneFill>::s_delegate = detail::search_pack_func<Traits, AlphaOneFill>(planar_to_packed::pack_impl);
#endif
// v210 specializations.
template <>
class packed_to_planar<packed_v210_be> {
public:
static void unpack(const void *src, void * const dst[4], unsigned left, unsigned right);
};
template <>
class packed_to_planar<packed_v210_le> {
public:
static void unpack(const void *src, void * const dst[4], unsigned left, unsigned right);
};
template <>
class planar_to_packed<packed_v210_be, false> {
public:
static void pack(const void * const src[4], void *dst, unsigned left, unsigned right);
};
template <>
class planar_to_packed<packed_v210_be, true> {
public:
static void pack(const void * const src[4], void *dst, unsigned left, unsigned right);
};
template <>
class planar_to_packed<packed_v210_le, false> {
public:
static void pack(const void * const src[4], void *dst, unsigned left, unsigned right);
};
template <>
class planar_to_packed<packed_v210_le, true> {
public:
static void pack(const void * const src[4], void *dst, unsigned left, unsigned right);
};
} // namespace p2p
#endif // P2P_H_
================================================
FILE: common-src/libp2p/p2p_api.cpp
================================================
#include <algorithm>
#include <cassert>
#include <cstring>
#include "p2p.h"
#include "p2p_api.h"
#ifdef P2P_USER_NAMESPACE
#error API build must not use custom namespace
#endif
namespace {
struct packing_traits {
enum p2p_packing packing;
p2p_unpack_func unpack;
p2p_pack_func pack;
p2p_pack_func pack_one_fill;
bool native_endian;
unsigned char subsample_w;
unsigned char subsample_h;
bool is_nv;
unsigned char bytes_per_sample; // Only used to copy luma plane for NV12.
unsigned char nv_shift; // Extra LSB to shift away for MS P010/P210, etc.
};
#define CASE(x, ...) \
{ p2p_##x, &p2p::packed_to_planar<p2p::packed_##x>::unpack, &p2p::planar_to_packed<p2p::packed_##x, false>::pack, &p2p::planar_to_packed<p2p::packed_##x, true>::pack, ##__VA_ARGS__ }
#define CASE2(x, ...) \
CASE(x##_be, std::is_same<p2p::native_endian_t, p2p::big_endian_t>::value, ##__VA_ARGS__), \
CASE(x##_le, std::is_same<p2p::native_endian_t, p2p::little_endian_t>::value, ##__VA_ARGS__), \
CASE(x, true, ##__VA_ARGS__)
const packing_traits traits_table[] = {
CASE2(rgb24, 0, 0),
CASE2(argb32, 0, 0),
CASE2(ayuv, 0, 0),
CASE2(rgb48, 0, 0),
CASE2(argb64, 0, 0),
CASE2(rgb30, 0, 0),
CASE2(y410, 0, 0),
CASE2(y416, 0, 0),
CASE(yuy2, true, 1, 0),
CASE(uyvy, true, 1, 0),
CASE2(y210, 1, 0),
CASE2(y216, 1, 0),
CASE2(v210, 1, 0),
CASE2(v216, 1, 0),
CASE2(nv12, 1, 1, true, 1),
CASE2(p010, 1, 1, true, 2, 6),
CASE2(p016, 1, 1, true, 2),
CASE2(p210, 1, 0, true, 2, 6),
CASE2(p216, 1, 0, true, 2),
CASE2(rgba32, 0, 0),
CASE2(rgba64, 0, 0),
CASE2(abgr64, 0, 0),
CASE2(bgr48, 0, 0),
CASE2(bgra64, 0, 0),
};
#undef CASE2
#undef CASE
const packing_traits &lookup_traits(enum p2p_packing packing)
{
assert(packing >= 0);
assert(packing < sizeof(traits_table) / sizeof(traits_table[0]));
const packing_traits &traits = traits_table[packing];
assert(traits.packing == packing);
assert(traits.subsample_h == 0 || traits.is_nv);
return traits;
}
template <class T>
T *increment_ptr(T *ptr, ptrdiff_t n)
{
return (T *)((const unsigned char *)ptr + n);
}
void copy_plane_fast(const void *src, void *dst, ptrdiff_t src_stride, ptrdiff_t dst_stride,
unsigned linesize, unsigned height)
{
for (unsigned i = 0; i < height; ++i) {
memcpy(dst, src, linesize);
src = increment_ptr(src, src_stride);
dst = increment_ptr(dst, dst_stride);
}
}
void unpack_nv16_plane(const void *src, void *dst, ptrdiff_t src_stride, ptrdiff_t dst_stride,
const packing_traits &traits, unsigned width, unsigned height)
{
assert(traits.bytes_per_sample == 2);
for (unsigned i = 0; i < height; ++i) {
std::transform(static_cast<const uint16_t *>(src), static_cast<const uint16_t *>(src) + width, static_cast<uint16_t *>(dst), [=](uint16_t x)
{
x = traits.native_endian ? x : (x >> 8) | (x << 8);
return x >> traits.nv_shift;
});
src = increment_ptr(src, src_stride);
dst = increment_ptr(dst, dst_stride);
}
}
void pack_nv16_plane(const void *src, void *dst, ptrdiff_t src_stride, ptrdiff_t dst_stride,
const packing_traits &traits, unsigned width, unsigned height)
{
assert(traits.bytes_per_sample == 2);
for (unsigned i = 0; i < height; ++i) {
std::transform(static_cast<const uint16_t *>(src), static_cast<const uint16_t *>(src) + width, static_cast<uint16_t *>(dst), [=](uint16_t x)
{
x = x << traits.nv_shift;
return traits.native_endian ? x : (x >> 8) | (x << 8);
});
src = increment_ptr(src, src_stride);
dst = increment_ptr(dst, dst_stride);
}
}
} // namespace
p2p_unpack_func p2p_select_unpack_func(enum p2p_packing packing)
{
return lookup_traits(packing).unpack;
}
p2p_pack_func p2p_select_pack_func(enum p2p_packing packing)
{
return p2p_select_pack_func_ex(packing, 0);
}
p2p_pack_func p2p_select_pack_func_ex(enum p2p_packing packing, int alpha_one_fill)
{
const packing_traits &traits = lookup_traits(packing);
return alpha_one_fill ? traits.pack_one_fill : traits.pack;
}
void p2p_unpack_frame(const struct p2p_buffer_param *param, unsigned long flags)
{
const packing_traits &traits = lookup_traits(param->packing);
// Process interleaved plane.
const void *src_p = traits.is_nv ? param->src[1] : param->src[0];
ptrdiff_t src_stride = traits.is_nv ? param->src_stride[1] : param->src_stride[0];
void *dst_p[4] = { param->dst[0], param->dst[1], param->dst[2], param->dst[3] };
for (unsigned i = 0; i < (param->height >> traits.subsample_h); ++i) {
traits.unpack(src_p, dst_p, 0, param->width);
src_p = increment_ptr(src_p, src_stride);
if (!traits.is_nv) {
dst_p[0] = increment_ptr(dst_p[0], param->dst_stride[0]);
dst_p[3] = increment_ptr(dst_p[3], param->dst_stride[3]);
}
dst_p[1] = increment_ptr(dst_p[1], param->dst_stride[1]);
dst_p[2] = increment_ptr(dst_p[2], param->dst_stride[2]);
}
if (traits.is_nv && !(flags & P2P_SKIP_UNPACKED_PLANES) && param->src[0] && param->dst[0]) {
if ((traits.bytes_per_sample == 1 || traits.native_endian) && !traits.nv_shift) {
copy_plane_fast(param->src[0], param->dst[0], param->src_stride[0], param->dst_stride[0],
traits.bytes_per_sample * param->width, param->height);
} else {
unpack_nv16_plane(param->src[0], param->dst[0], param->src_stride[0], param->dst_stride[0], traits, param->width, param->height);
}
}
}
void p2p_pack_frame(const struct p2p_buffer_param *param, unsigned long flags)
{
const packing_traits &traits = lookup_traits(param->packing);
p2p_pack_func pack_func = flags & P2P_ALPHA_SET_ONE ? traits.pack_one_fill : traits.pack;
// Process interleaved plane.
const void *src_p[4] = { param->src[0], param->src[1], param->src[2], param->src[3] };
void *dst_p = traits.is_nv ? param->dst[1] : param->dst[0];
ptrdiff_t dst_stride = traits.is_nv ? param->dst_stride[1] : param->dst_stride[0];
for (unsigned i = 0; i < (param->height >> traits.subsample_h); ++i) {
pack_func(src_p, dst_p, 0, param->width);
if (!traits.is_nv) {
src_p[0] = increment_ptr(src_p[0], param->src_stride[0]);
src_p[3] = increment_ptr(src_p[3], param->src_stride[3]);
}
src_p[1] = increment_ptr(src_p[1], param->src_stride[1]);
src_p[2] = increment_ptr(src_p[2], param->src_stride[2]);
dst_p = increment_ptr(dst_p, dst_stride);
}
if (traits.is_nv && !(flags & P2P_SKIP_UNPACKED_PLANES) && param->src[0] && param->dst[0]) {
if ((traits.bytes_per_sample == 1 || traits.native_endian) && !traits.nv_shift) {
copy_plane_fast(param->src[0], param->dst[0], param->src_stride[0], param->dst_stride[0],
traits.bytes_per_sample * param->width, param->height);
} else {
pack_nv16_plane(param->src[0], param->dst[0], param->src_stride[0], param->dst_stride[0], traits, param->width, param->height);
}
}
}
================================================
FILE: common-src/libp2p/p2p_api.h
================================================
#ifndef P2P_API_H_
#define P2P_API_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Notation: [Xa-Ya-Za]
*
* [] denotes a machine word of the specified endianness. Xa-Ya-Za denote
* component X, Y, and Z packed in the word, with bit depths a, b, c, in order
* from MSB to LSB. Padding bits are represented by the component '!'.
*/
enum p2p_packing {
/** [R8-G8-B8] */
p2p_rgb24_be, /* RGB */
p2p_rgb24_le, /* BGR */
p2p_rgb24,
/** [A8-R8-G8-B8] */
p2p_argb32_be, /* ARGB */
p2p_argb32_le, /* BGRA */
p2p_argb32,
/** [A8-Y8-U8-V8] */
p2p_ayuv_be, /* AYUV */
p2p_ayuv_le, /* VUYA */
p2p_ayuv,
/** [R16-G16-B16] */
p2p_rgb48_be, /* RGB, big-endian components */
p2p_rgb48_le, /* BGR, little-endian components */
p2p_rgb48,
/** [A16-R16-G16-B16] */
p2p_argb64_be, /* ARGB big-endian components */
p2p_argb64_le, /* BGRA little-endian components */
p2p_argb64,
/** [A2-R10-G10-B10] */
p2p_rgb30_be, /* ARGB packed in big-endian DWORD */
p2p_rgb30_le, /* ARGB packed in little-endian DWORD */
p2p_rgb30,
/** [A2-V10-Y10-U10] */
p2p_y410_be, /* AVYU packed in big-endian DWORD */
p2p_y410_le, /* AVYU packed in little-endian DWORD */
p2p_y410,
/** [A16-V16-Y16-U16] */
p2p_y416_be, /* AVYU, big-endian components */
p2p_y416_le, /* UYVA, little-endian components */
p2p_y416,
/** [Y8] [U8] [Y8] [V8] */
p2p_yuy2,
/** [U8] [Y8] [V8] [Y8] */
p2p_uyvy,
/** [Y10-!6] [U10-!6] [Y10-!6] [V10-!6] */
p2p_y210_be, /* YUYV, big-endian components, lower 6 bits zero */
p2p_y210_le, /* YUYV, little-endian components, lower 6 bits zero. Microsoft Y210. */
p2p_y210,
/** [Y16] [U16] [Y16] [V16] */
p2p_y216_be, /* YUYV, big-endian components */
p2p_y216_le, /* YUYV, little-endian components. Microsoft Y216. */
p2p_y216,
/** [!2-V10-Y10-U10] [!2-Y10-U10-Y10] [!2-U10-Y10-V10] [!2-Y10-V10-Y10] */
p2p_v210_be, /* v210 with big-endian DWORDs */
p2p_v210_le, /* Apple/QuickTime v210 */
p2p_v210,
/** [U16] [Y16] [V16] [Y16] */
p2p_v216_be, /* UYVY, big-endian components */
p2p_v216_le, /* UYVY, little-endian components. Apple/QuickTime v216. */
p2p_v216,
/** [U8-V8] */
p2p_nv12_be, /* aka NV21, V first */
p2p_nv12_le, /* NV12 */
p2p_nv12,
/** [U10-!6-V10-!6] */
p2p_p010_be, /* NV21, big-endian components, lower 6 bits zero */
p2p_p010_le, /* NV12, little-endian components, lower 6 bits zero. Microsoft P010. */
p2p_p010,
/** [U16-V16] */
p2p_p016_be, /* NV21, big-endian components */
p2p_p016_le, /* NV12, little-endian components. Microsoft P016. */
p2p_p016,
/** [U10-!6-V10-!6] */
p2p_p210_be, /* NV21, big-endian components, lower 6 bits zero */
p2p_p210_le, /* NV12, little-endian components, lower 6 bits zero. Microsoft P210. */
p2p_p210,
/** [U16-V16] */
p2p_p216_be, /* NV21, big-endian components */
p2p_p216_le, /* NV12, little-endian components. Microsoft P216. */
p2p_p216,
/** [R8-G8-B8-A8] */
p2p_rgba32_be, /* RGBA */
p2p_rgba32_le, /* ABGR */
p2p_rgba32,
/** [R16-G16-B16-A16] */
p2p_rgba64_be, /* RGBA, big-endian components */
p2p_rgba64_le, /* ABGR, little-endian components */
p2p_rgba64,
/** [A16-B16-G16-R16] */
p2p_abgr64_be, /* ABGR, big-endian components */
p2p_abgr64_le, /* RGBA, little-endian components */
p2p_abgr64,
/** [B16-G16-R16] */
p2p_bgr48_be, /* BGR, big-endian components */
p2p_bgr48_le, /* RGB, little-endian components */
p2p_bgr48,
/** [B16-G16-R16-A16] */
p2p_bgra64_be, /* BGRA, big-endian components */
p2p_bgra64_le, /* ARGB, little-endian components */
p2p_bgra64,
p2p_packing_max,
};
struct p2p_buffer_param {
/**
* Planar order: R-G-B-A or Y-U-V-A. Alpha is optional.
* Packed order: Y-UV if NV12/21, else single plane. Y optional for NV12/21.
*/
const void *src[4];
void *dst[4];
ptrdiff_t src_stride[4];
ptrdiff_t dst_stride[4];
unsigned width;
unsigned height;
enum p2p_packing packing;
};
/** Pack/unpack a range of pixels from a scanline. */
typedef void (*p2p_unpack_func)(const void *src, void * const dst[4], unsigned left, unsigned right);
typedef void (*p2p_pack_func)(const void * const src[4], void *dst, unsigned left, unsigned right);
/** Select a line pack/unpack function. */
p2p_unpack_func p2p_select_unpack_func(enum p2p_packing packing);
p2p_pack_func p2p_select_pack_func(enum p2p_packing packing);
p2p_pack_func p2p_select_pack_func_ex(enum p2p_packing packing, int alpha_one_fill);
/** When processing formats like NV12, ignore the unpacked plane. */
#define P2P_SKIP_UNPACKED_PLANES (1UL << 0)
/** When packing, store a bit pattern of all ones in the alpha channel instead of all zeros. */
#define P2P_ALPHA_SET_ONE (1UL << 1)
/** Helper function to pack/unpack between memory locations. */
void p2p_unpack_frame(const struct p2p_buffer_param *param, unsigned long flags);
void p2p_pack_frame(const struct p2p_buffer_param *param, unsigned long flags);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* P2P_API_H_ */
================================================
FILE: common-src/libp2p/simd/cpuinfo_x86.cpp
================================================
#ifdef P2P_SIMD
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
#if 0
#include <stdio.h>
#define TRACE(fmt, ...) fprintf(stderr, "[cpuinfo] " fmt, __VA_ARGS__)
#else
#define TRACE(fmt, ...) do {} while (0)
#endif
#if defined(_MSC_VER)
#include <intrin.h>
#elif defined(__GNUC__)
#include <cpuid.h>
#endif
#include "../p2p.h"
#include "cpuinfo_x86.h"
namespace P2P_NAMESPACE {
namespace simd {
namespace {
/**
* Execute the CPUID instruction.
*
* @param regs array to receive eax, ebx, ecx, edx
* @param eax argument to instruction
* @param ecx argument to instruction
*/
void do_cpuid(int regs[4], int eax, int ecx)
{
#if defined(_MSC_VER)
__cpuidex(regs, eax, ecx);
#elif defined(__GNUC__)
__cpuid_count(eax, ecx, regs[0], regs[1], regs[2], regs[3]);
#else
regs[0] = 0;
regs[1] = 0;
regs[2] = 0;
regs[3] = 0;
#endif
}
/**
* Execute the XGETBV instruction.
*
* @param ecx argument to instruction
* @return (edx << 32) | eax
*/
unsigned long long do_xgetbv(unsigned ecx)
{
#if defined(_MSC_VER)
return _xgetbv(ecx);
#elif defined(__GNUC__)
unsigned eax, edx;
__asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(ecx) : );
return (static_cast<unsigned long long>(edx) << 32) | eax;
#else
return 0;
#endif
}
X86Capabilities do_query_x86_capabilities() noexcept
{
X86Capabilities caps = { 0 };
unsigned long long xcr0 = 0;
int regs[4] = { 0 };
int xmmymm = 0;
int zmm = 0;
do_cpuid(regs, 1, 0);
caps.sse = !!(regs[3] & (1U << 25));
caps.sse2 = !!(regs[3] & (1U << 26));
caps.sse3 = !!(regs[2] & (1U << 0));
caps.ssse3 = !!(regs[2] & (1U << 9));
caps.fma = !!(regs[2] & (1U << 12));
caps.sse41 = !!(regs[2] & (1U << 19));
caps.sse42 = !!(regs[2] & (1U << 20));
// osxsave
if (regs[2] & (1U << 27)) {
xcr0 = do_xgetbv(0);
xmmymm = (xcr0 & 0x06) == 0x06;
zmm = (xcr0 & 0xE0) == 0xE0;
}
// XMM and YMM state.
if (xmmymm) {
caps.avx = !!(regs[2] & (1U << 28));
caps.f16c = !!(regs[2] & (1U << 29));
}
do_cpuid(regs, 7, 0);
if (xmmymm) {
caps.avx2 = !!(regs[1] & (1U << 5));
}
// ZMM state.
if (zmm) {
caps.avx512f = !!(regs[1] & (1U << 16));
caps.avx512dq = !!(regs[1] & (1U << 17));
caps.avx512ifma = !!(regs[1] & (1U << 21));
caps.avx512cd = !!(regs[1] & (1U << 28));
caps.avx512bw = !!(regs[1] & (1U << 30));
caps.avx512vl = !!(regs[1] & (1U << 31));
caps.avx512vbmi = !!(regs[2] & (1U << 1));
caps.avx512vbmi2 = !!(regs[2] & (1U << 6));
caps.avx512vnni = !!(regs[2] & (1U << 11));
caps.avx512bitalg = !!(regs[2] & (1U << 12));
caps.avx512vpopcntdq = !!(regs[2] & (1U << 14));
caps.avx512vp2intersect = !!(regs[3] & (1U << 8));
caps.avx512fp16 = !!(regs[3] & (1U << 23));
}
do_cpuid(regs, 7, 1);
if (zmm) {
caps.avx512bf16 = !!(regs[0] & (1U << 5));
}
// Extended processor info.
do_cpuid(regs, 0x80000001U, 0);
caps.xop = !!(regs[2] & (1U << 11));
// Zen1 vs Zen2.
do_cpuid(regs, 0, 1);
if (regs[1] == 0x68747541U && regs[3] == 0x69746E65U && regs[2] == 0x444D4163U /* AuthenticAMD */) {
unsigned model;
unsigned family;
do_cpuid(regs, 1, 0);
model = (regs[0] >> 4) & 0x0FU;
family = (regs[0] >> 8) & 0x0FU;
if (family == 15) {
family += ((regs[0] >> 20) & 0x0FU);
model += ((regs[0] >> 16) & 0x0FU) << 4;
}
caps.piledriver = family == 0x15 && model == 0x02;
caps.zen1 = family == 0x17 && model <= 0x2F;
caps.zen2 = family == 0x17 && model >= 0x30;
caps.zen3 = family == 0x19;
}
return caps;
}
// Query leaf 4h (Intel) or leaf 8000001Dh (AMD).
void do_query_x86_deterministic_cache_parameters(X86CacheHierarchy &cache, int leaf) noexcept
{
int regs[4];
for (int i = 0; i < 8; ++i) {
unsigned threads;
unsigned long line_size;
unsigned long partitions;
unsigned long ways;
unsigned long sets;
unsigned long cache_size;
int cache_type;
bool inclusive;
do_cpuid(regs, leaf, i);
cache_type = regs[0] & 0x1FU;
TRACE("L%u cache, type %d\n", (static_cast<unsigned>(regs[0]) >> 5) & 0x07U, cache_type);
// No more caches.
if (cache_type == 0)
break;
// Not data or unified cache.
if (cache_type != 1 && cache_type != 3)
continue;
threads = ((static_cast<unsigned>(regs[0]) >> 14) & 0x0FFFU) + 1;
line_size = ((static_cast<unsigned>(regs[1]) >> 0) & 0x0FFFU) + 1;
partitions = ((static_cast<unsigned>(regs[1]) >> 12) & 0x03FFU) + 1;
ways = ((static_cast<unsigned>(regs[1]) >> 22) & 0x03FFU) + 1;
sets = static_cast<unsigned>(regs[2]) + 1;
cache_size = line_size * partitions * ways * sets;
inclusive = regs[3] & (1U << 1);
TRACE("%u threads, %lu bytes, %s\n", threads, cache_size, inclusive ? "inclusive" : "non-inclusive");
// Cache level.
switch ((static_cast<unsigned>(regs[0]) >> 5) & 0x07U) {
case 1:
cache.l1d = cache_size;
cache.l1d_threads = threads;
break;
case 2:
cache.l2 = cache_size;
cache.l2_threads = threads;
cache.l2_inclusive = inclusive;
break;
case 3:
cache.l3 = cache_size;
cache.l3_threads = threads;
cache.l3_inclusive = inclusive;
break;
default:
break;
}
}
}
X86CacheHierarchy do_query_x86_cache_hierarchy_intel(int max_feature) noexcept
{
X86CacheHierarchy cache = { 0 };
int regs[4];
if (max_feature < 2)
return cache;
// Detect cache size of single-threaded CPU from flags.
if (max_feature >= 2 && max_feature < 4)
return cache;
// Detect cache hierarchy.
if (max_feature >= 4)
do_query_x86_deterministic_cache_parameters(cache, 4);
// Detect logical processor count on x2APIC systems.
if (max_feature >= 0x0B) {
unsigned l1d_threads = cache.l1d_threads;
unsigned l2_threads = cache.l2_threads;
unsigned l3_threads = cache.l3_threads;
for (int i = 0; i < 8; ++i) {
unsigned logical_processors;
do_cpuid(regs, 0x0B, i);
TRACE("APIC level %u\n", (static_cast<unsigned>(regs[2]) >> 8) & 0xFFU);
if (((regs[2] >> 8) & 0xFFU) == 0)
break;
logical_processors = regs[1] & 0xFFFFU;
TRACE("logical processors: %u\n", logical_processors);
l1d_threads = logical_processors <= cache.l1d_threads ? logical_processors : l1d_threads;
l2_threads = logical_processors <= cache.l2_threads ? logical_processors : l2_threads;
l3_threads = logical_processors <= cache.l3_threads ? logical_processors : l3_threads;
TRACE("updated cache sharing: %u %u %u\n", l1d_threads, l2_threads, l3_threads);
}
cache.l1d_threads = l1d_threads;
cache.l2_threads = l2_threads;
cache.l3_threads = l3_threads;
}
return cache;
}
X86CacheHierarchy do_query_x86_cache_hierarchy_amd(int max_feature) noexcept
{
X86CacheHierarchy cache = { 0 };
int regs[4];
unsigned max_extended_feature;
do_cpuid(regs, 0x80000000U, 0);
max_extended_feature = static_cast<unsigned>(regs[0]);
TRACE("max extended feature #: 0x%x\n", max_extended_feature);
if (max_extended_feature >= 0x80000005U) {
do_cpuid(regs, 0x80000005U, 0);
cache.l1d = ((static_cast<unsigned>(regs[2]) >> 24) & 0xFFU) * 1024U;
cache.l1d_threads = cache.l1d ? 1 : cache.l1d_threads;
TRACE("L1d: %lu\n", cache.l1d);
}
if (max_extended_feature >= 0x80000006U) {
do_cpuid(regs, 0x80000006U, 0);
cache.l2 = ((static_cast<unsigned>(regs[2]) >> 16) & 0xFFFFU) * 1024U;
cache.l3 = ((static_cast<unsigned>(regs[3]) >> 18) & 0x3FFFU) * 512U * 1024U;
cache.l2_threads = cache.l2 ? 1 : cache.l2_threads;
cache.l3_threads = cache.l3 ? 1 : cache.l3_threads;
TRACE("L2: %lu\n", cache.l2);
TRACE("L3: %lu\n", cache.l3);
}
if (max_extended_feature >= 0x80000008U) {
unsigned threads;
unsigned family;
do_cpuid(regs, 0x80000008U, 0);
threads = (regs[2] & 0xFFU) + 1;
cache.l3_threads = cache.l3 ? threads : cache.l3_threads;
TRACE("package threads: %u\n", threads);
do_cpuid(regs, 1, 0);
family = ((static_cast<unsigned>(regs[0]) >> 20) & 0xFFU) + ((static_cast<unsigned>(regs[0]) >> 8) & 0x0FU);
TRACE("family %xh\n", family);
if (family == 0x15)
cache.l2_threads = 2; // Bulldozer shared L2 cache.
else if (family == 0x16)
cache.l2_threads = threads; // Jaguar L2 LLC.
}
if (max_extended_feature >= 0x8000001DU)
do_query_x86_deterministic_cache_parameters(cache, 0x8000001DU);
return cache;
}
X86CacheHierarchy do_query_x86_cache_hierarchy() noexcept
{
enum { GENUINEINTEL, AUTHENTICAMD, OTHER } vendor;
X86CacheHierarchy cache = { 0 };
int regs[4] = { 0 };
int max_feature;
do_cpuid(regs, 0, 1);
max_feature = regs[0] & 0xFFU;
TRACE("max feature #: %d\n", max_feature);
if (regs[1] == 0x756E6547U && regs[3] == 0x49656E69U && regs[2] == 0x6C65746EU) {
vendor = GENUINEINTEL;
TRACE("%s\n", "GenuineIntel");
} else if (regs[1] == 0x68747541U && regs[3] == 0x69746E65U && regs[2] == 0x444D4163U) {
vendor = AUTHENTICAMD;
TRACE("%s\n", "AuthenticAMD");
} else {
vendor = OTHER;
TRACE("vendor %08x-%08x-%08x\n", regs[0], regs[2], regs[1]);
}
if (vendor == GENUINEINTEL)
cache = do_query_x86_cache_hierarchy_intel(max_feature);
else if (vendor == AUTHENTICAMD)
cache = do_query_x86_cache_hierarchy_amd(max_feature);
TRACE("final hierarchy: L1 %lu / %lu, L2: %lu / %lu, L3: %lu / %lu\n",
cache.l1d, cache.l1d_threads, cache.l2, cache.l2_threads, cache.l3, cache.l3_threads);
cache.valid = cache.l1d && cache.l1d_threads && !(cache.l2 && !cache.l2_threads) && !(cache.l3 && !cache.l3_threads);
return cache;
}
} // namespace
X86Capabilities query_x86_capabilities() noexcept
{
static const X86Capabilities caps = do_query_x86_capabilities();
return caps;
}
X86CacheHierarchy query_x86_cache_hierarchy() noexcept
{
static const X86CacheHierarchy cache = do_query_x86_cache_hierarchy();
return cache;
}
unsigned long cpu_cache_size_x86() noexcept
{
const X86CacheHierarchy cache = query_x86_cache_hierarchy();
if (!cache.valid)
return 0;
// Detect Skylake-SP cache hierarchy and report L2 size instead of L3.
if (cache.l3 && !cache.l3_inclusive && cache.l2 >= 1024 * 1024U && cache.l2_threads <= 2)
return cache.l2 / cache.l2_threads;
if (cache.l3)
return cache.l3 / cache.l3_threads;
else if (cache.l2)
return cache.l2 / cache.l2_threads;
else
return cache.l1d / cache.l1d_threads;
}
} // namespace simd
} // namespace p2p
#endif // x86
#endif // P2P_SIMD
================================================
FILE: common-src/libp2p/simd/cpuinfo_x86.h
================================================
#pragma once
#ifndef P2P_CPUINFO_X86_H_
#define P2P_CPUINFO_X86_H_
#ifdef P2P_SIMD
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
#include "../p2p.h"
namespace P2P_NAMESPACE {
namespace simd {
/**
* Bitfield of selected x86 feature flags.
*/
struct X86Capabilities {
unsigned sse : 1;
unsigned sse2 : 1;
unsigned sse3 : 1;
unsigned ssse3 : 1;
unsigned fma : 1;
unsigned sse41 : 1;
unsigned sse42 : 1;
unsigned avx : 1;
unsigned f16c : 1;
unsigned avx2 : 1;
unsigned avx512f : 1;
unsigned avx512dq : 1;
unsigned avx512ifma : 1;
unsigned avx512cd : 1;
unsigned avx512bw : 1;
unsigned avx512vl : 1;
unsigned avx512vbmi : 1;
unsigned avx512vbmi2 : 1;
unsigned avx512vnni : 1;
unsigned avx512bitalg : 1;
unsigned avx512vpopcntdq : 1;
unsigned avx512vp2intersect : 1;
unsigned avx512fp16 : 1;
unsigned avx512bf16 : 1;
/* AMD architectures needing workarounds. */
unsigned xop : 1;
unsigned piledriver : 1;
unsigned zen1 : 1;
unsigned zen2 : 1;
unsigned zen3 : 1;
};
/**
* Representation of processor cache topology.
*/
struct X86CacheHierarchy {
unsigned long l1d;
unsigned long l1d_threads;
unsigned long l2;
unsigned long l2_threads;
unsigned long l3;
unsigned long l3_threads;
bool l2_inclusive;
bool l3_inclusive;
bool valid;
};
/**
* Get the x86 feature flags on the current CPU.
*
* @return capabilities
*/
X86Capabilities query_x86_capabilities() noexcept;
/**
* Get the cache topology of the current CPU.
*
* On a multi-processor system, the returned topology corresponds to the first
* processor package on which the function is called. The behaviour is
* undefined if the platform contains non-identical processors.
*
* @return cache hierarchy
*/
X86CacheHierarchy query_x86_cache_hierarchy() noexcept;
unsigned long cpu_cache_size_x86() noexcept;
} // namespace simd
} // namespace p2p
#endif // x86
#endif // P2P_SIMD
#endif // P2P_CPUINFO_X86_H_
================================================
FILE: common-src/libp2p/simd/p2p_simd.cpp
================================================
#ifdef P2P_SIMD
#include <array>
#include <typeinfo>
#include <tuple>
#include <utility>
#include "../p2p.h"
#include "cpuinfo_x86.h"
#include "p2p_simd.h"
namespace P2P_NAMESPACE {
namespace detail {
namespace {
typedef std::pair<const std::type_info *, detail::unpack_func> unpack_table_entry;
typedef std::tuple<const std::type_info *, detail::pack_func, detail::pack_func> pack_table_entry;
auto populate_unpack_table()
{
std::array<unpack_table_entry, 100> table;
size_t idx = 0;
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
simd::X86Capabilities x86 = simd::query_x86_capabilities();
if (x86.sse41) {
#define ENTRY(format, cpu) table[idx++] = unpack_table_entry{ &typeid(packed_##format), simd::unpack_##format##_##cpu }
ENTRY(argb32_be, sse41);
ENTRY(argb32_le, sse41);
ENTRY(rgba32_be, sse41);
ENTRY(rgba32_le, sse41);
#undef ENTRY
}
#endif
return table;
}
auto populate_pack_table()
{
std::array<pack_table_entry, 100> table;
size_t idx = 0;
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
simd::X86Capabilities x86 = simd::query_x86_capabilities();
if (x86.sse41) {
#define ENTRY(format, cpu) table[idx++] = pack_table_entry{ &typeid(packed_##format), simd::pack_##format##_0_##cpu, simd::pack_##format##_1_##cpu }
ENTRY(argb32_be, sse41);
ENTRY(argb32_le, sse41);
ENTRY(rgba32_be, sse41);
ENTRY(rgba32_le, sse41);
#undef ENTRY
}
#endif
return table;
}
} // namespace
unpack_func search_unpack_func(const std::type_info &ti)
{
static const auto g_unpack_table = populate_unpack_table();
for (const auto &entry : g_unpack_table) {
if (entry.first == &ti)
return entry.second;
if (!entry.first)
break;
}
return nullptr;
}
pack_func search_pack_func(const std::type_info &ti, bool alpha_one_fill)
{
static const auto g_pack_table = populate_pack_table();
for (const auto &entry : g_pack_table) {
if (std::get<0>(entry) == &ti)
return alpha_one_fill ? std::get<2>(entry) : std::get<1>(entry);
if (!std::get<0>(entry))
break;
}
return nullptr;
}
} // namespace detail
} // namespace p2p
#endif // P2P_SIMD
================================================
FILE: common-src/libp2p/simd/p2p_simd.h
================================================
#pragma once
#ifndef P2P_SIMD_H_
#define P2P_SIMD_H_
#ifdef P2P_SIMD
#include "../p2p.h"
namespace P2P_NAMESPACE {
namespace simd {
#define UNPACK(format, cpu) void unpack_##format##_##cpu(const void *, void * const *, unsigned, unsigned);
#define PACK(format, cpu) \
void pack_##format##_0_##cpu(const void * const *, void *, unsigned, unsigned); \
void pack_##format##_1_##cpu(const void * const *, void *, unsigned, unsigned);
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
UNPACK(argb32_be, sse41)
UNPACK(argb32_le, sse41)
UNPACK(rgba32_be, sse41)
UNPACK(rgba32_le, sse41)
PACK(argb32_be, sse41)
PACK(argb32_le, sse41)
PACK(rgba32_be, sse41)
PACK(rgba32_le, sse41)
#endif // x86
#undef PACK
#undef UNPACK
} // namespace simd
} // namespace p2p
#endif // P2P_SIMD
#endif // P2P_SIMD_H_
================================================
FILE: common-src/libp2p/simd/p2p_sse41.cpp
================================================
#ifdef P2P_SIMD
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
#include <cstdint>
#include <smmintrin.h>
#include "../p2p.h"
namespace P2P_NAMESPACE {
namespace simd {
namespace {
template <unsigned Idx>
uint32_t extract_epi32(__m128i x)
{
return Idx == 0 ? _mm_cvtsi128_si32(x) : _mm_extract_epi32(x, Idx);
}
template <unsigned IdxR, unsigned IdxG, unsigned IdxB, unsigned IdxA>
void unpack_rgb32_sse41(const void *src, void * const * dst, unsigned left, unsigned right)
{
const __m128i shuffle = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);
const uint32_t *src_p = static_cast<const uint32_t *>(src);
uint8_t *dst_r = static_cast<uint8_t *>(dst[0]);
uint8_t *dst_g = static_cast<uint8_t *>(dst[1]);
uint8_t *dst_b = static_cast<uint8_t *>(dst[2]);
uint8_t *dst_a = static_cast<uint8_t *>(dst[3]);
if (!dst_a)
dst_a = dst_r; // Write alpha to some other channel if disabled.
size_t vec4_left = (left + 3) & ~3U;
size_t vec16_left = (left + 15) & ~15U;
size_t vec16_right = right & ~15U;
size_t vec4_right = right & ~3U;
// Must always write alpha component first!
auto scalar_iter = [&](size_t i)
{
uint32_t x = src_p[i];
dst_a[i] = static_cast<uint8_t>((x >> (IdxA * 8)) & 0xFFU);
dst_r[i] = static_cast<uint8_t>((x >> (IdxR * 8)) & 0xFFU);
dst_g[i] = static_cast<uint8_t>((x >> (IdxG * 8)) & 0xFFU);
dst_b[i] = static_cast<uint8_t>((x >> (IdxB * 8)) & 0xFFU);
};
auto vec4_iter = [&](size_t i)
{
__m128i x = _mm_loadu_si128((const __m128i *)(src_p + i));
x = _mm_shuffle_epi8(x, shuffle);
*reinterpret_cast<uint32_t *>(dst_a + i) = extract_epi32<IdxA>(x);
*reinterpret_cast<uint32_t *>(dst_r + i) = extract_epi32<IdxR>(x);
*reinterpret_cast<uint32_t *>(dst_g + i) = extract_epi32<IdxG>(x);
*reinterpret_cast<uint32_t *>(dst_b + i) = extract_epi32<IdxB>(x);
};
auto vec16_iter = [&](size_t i)
{
__m128i x0 = _mm_loadu_si128((const __m128i *)(src_p + i));
__m128i x1 = _mm_loadu_si128((const __m128i *)(src_p + i + 4));
__m128i x2 = _mm_loadu_si128((const __m128i *)(src_p + i + 8));
__m128i x3 = _mm_loadu_si128((const __m128i *)(src_p + i + 12));
x0 = _mm_shuffle_epi8(x0, shuffle);
x1 = _mm_shuffle_epi8(x1, shuffle);
x2 = _mm_shuffle_epi8(x2, shuffle);
x3 = _mm_shuffle_epi8(x3, shuffle);
__m128 x0s = _mm_castsi128_ps(x0), x1s = _mm_castsi128_ps(x1), x2s = _mm_castsi128_ps(x2), x3s = _mm_castsi128_ps(x3);
_MM_TRANSPOSE4_PS(x0s, x1s, x2s, x3s);
x0 = _mm_castps_si128(x0s); x1 = _mm_castps_si128(x1s); x2 = _mm_castps_si128(x2s); x3 = _mm_castps_si128(x3s);
__m128i regs[4] = { x0, x1, x2, x3 };
_mm_storeu_si128((__m128i *)(dst_a + i), regs[IdxA]);
_mm_storeu_si128((__m128i *)(dst_r + i), regs[IdxR]);
_mm_storeu_si128((__m128i *)(dst_g + i), regs[IdxG]);
_mm_storeu_si128((__m128i *)(dst_b + i), regs[IdxB]);
};
for (size_t i = left; i < vec4_left; ++i)
scalar_iter(i);
for (size_t i = vec4_left; i < vec16_left; i += 4)
vec4_iter(i);
for (size_t i = vec16_left; i < vec16_right; i += 16)
vec16_iter(i);
for (size_t i = vec16_right; i < vec4_right; i += 4)
vec4_iter(i);
for (size_t i = vec4_right; i < right; ++i)
scalar_iter(i);
}
template <unsigned IdxR, unsigned IdxG, unsigned IdxB, unsigned IdxA, bool AlphaOneFill>
void pack_rgb32_sse41(const void * const *src, void *dst, unsigned left, unsigned right)
{
#define X (AlphaOneFill ? 0xFF : 0)
alignas(16) static constexpr uint8_t alpha_fill[16] = { X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X };
#undef X
const __m128i shuffle = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);
const uint8_t *src_r = static_cast<const uint8_t *>(src[0]);
const uint8_t *src_g = static_cast<const uint8_t *>(src[1]);
const uint8_t *src_b = static_cast<const uint8_t *>(src[2]);
const uint8_t *src_a = static_cast<const uint8_t *>(src[3]);
size_t alpha_addr_mask = ~static_cast<size_t>(0);
uint32_t *dst_p = static_cast<uint32_t *>(dst);
size_t vec4_left = (left + 3) & ~3U;
size_t vec16_left = (left + 15) & ~15U;
size_t vec16_right = right & ~15U;
size_t vec4_right = right & ~3U;
if (!src_a) {
src_a = alpha_fill;
alpha_addr_mask = 15;
}
auto scalar_iter = [&](size_t i)
{
uint8_t r = src_r[i];
uint8_t g = src_g[i];
uint8_t b = src_b[i];
uint8_t a = src_a[i & alpha_addr_mask];
uint32_t val = (static_cast<uint32_t>(r) << (IdxR * 8)) |
(static_cast<uint32_t>(g) << (IdxG * 8)) |
(static_cast<uint32_t>(b) << (IdxB * 8)) |
(static_cast<uint32_t>(a) << (IdxA * 8));
dst_p[i] = val;
};
auto vec4_iter = [&](size_t i)
{
uint32_t r = *reinterpret_cast<const uint32_t *>(src_r + i);
uint32_t g = *reinterpret_cast<const uint32_t *>(src_g + i);
uint32_t b = *reinterpret_cast<const uint32_t *>(src_b + i);
uint32_t a = *reinterpret_cast<const uint32_t *>(src_a + (i & alpha_addr_mask));
__m128i x = IdxR == 0 ? _mm_cvtsi32_si128(r) :
IdxG == 0 ? _mm_cvtsi32_si128(g) :
IdxB == 0 ? _mm_cvtsi32_si128(b) :
IdxA == 0 ? _mm_cvtsi32_si128(a) :
throw 1;
x = IdxR == 0 ? x : _mm_insert_epi32(x, r, IdxR);
x = IdxG == 0 ? x : _mm_insert_epi32(x, g, IdxG);
x = IdxB == 0 ? x : _mm_insert_epi32(x, b, IdxB);
x = IdxA == 0 ? x : _mm_insert_epi32(x, a, IdxA);
x = _mm_shuffle_epi8(x, shuffle);
_mm_storeu_si128((__m128i *)(dst_p + i), x);
};
auto vec16_iter = [&](size_t i)
{
__m128i r = _mm_loadu_si128((const __m128i *)(src_r + i));
__m128i g = _mm_loadu_si128((const __m128i *)(src_g + i));
__m128i b = _mm_loadu_si128((const __m128i *)(src_b + i));
__m128i a = _mm_loadu_si128((const __m128i *)(src_a + (i & alpha_addr_mask)));
__m128 regs[4];
regs[IdxR] = _mm_castsi128_ps(r);
regs[IdxG] = _mm_castsi128_ps(g);
regs[IdxB] = _mm_castsi128_ps(b);
regs[IdxA] = _mm_castsi128_ps(a);
_MM_TRANSPOSE4_PS(regs[0], regs[1], regs[2], regs[3]);
__m128i x0 = _mm_castps_si128(regs[0]), x1 = _mm_castps_si128(regs[1]), x2 = _mm_castps_si128(regs[2]), x3 = _mm_castps_si128(regs[3]);
x0 = _mm_shuffle_epi8(x0, shuffle);
x1 = _mm_shuffle_epi8(x1, shuffle);
x2 = _mm_shuffle_epi8(x2, shuffle);
x3 = _mm_shuffle_epi8(x3, shuffle);
_mm_storeu_si128((__m128i *)(dst_p + i + 0), x0);
_mm_storeu_si128((__m128i *)(dst_p + i + 4), x1);
_mm_storeu_si128((__m128i *)(dst_p + i + 8), x2);
_mm_storeu_si128((__m128i *)(dst_p + i + 12), x3);
};
for (size_t i = left; i < vec4_left; ++i)
scalar_iter(i);
for (size_t i = vec4_left; i < vec16_left; i += 4)
vec4_iter(i);
for (size_t i = vec16_left; i < vec16_right; i += 16)
vec16_iter(i);
for (size_t i = vec16_right; i < vec4_right; i += 4)
vec4_iter(i);
for (size_t i = vec4_right; i < right; ++i)
scalar_iter(i);
}
} // namespace
#define RGB32_SSE41(format, a, b, c, d) \
void unpack_##format##_sse41(const void *src, void * const * dst, unsigned left, unsigned right) \
{ \
unpack_rgb32_sse41<a, b, c, d>(src, dst, left, right); \
} \
void pack_##format##_0_sse41(const void * const *src, void *dst, unsigned left, unsigned right) \
{ \
pack_rgb32_sse41<a, b, c, d, 0>(src, dst, left, right); \
} \
void pack_##format##_1_sse41(const void * const *src, void *dst, unsigned left, unsigned right) \
{ \
pack_rgb32_sse41<a, b, c, d, 1>(src, dst, left, right); \
}
RGB32_SSE41(argb32_be, 1, 2, 3, 0)
RGB32_SSE41(argb32_le, 2, 1, 0, 3)
RGB32_SSE41(rgba32_be, 0, 1, 2, 3)
RGB32_SSE41(rgba32_le, 3, 2, 1, 0)
} // namespace simd
} // namespace p2p
#endif // x86
#endif // P2P_SIMD
================================================
FILE: common-src/libp2p/v210.cpp
================================================
#include "p2p.h"
namespace P2P_NAMESPACE {
namespace {
template <class Endian>
void unpack_v210(const void *src, void * const dst[4], unsigned left, unsigned right)
{
const unsigned lsb_10b = 0x3FF;
const uint32_t *src_p = static_cast<const uint32_t *>(src);
uint16_t *dst_p[3] = { static_cast<uint16_t *>(dst[0]), static_cast<uint16_t *>(dst[1]), static_cast<uint16_t *>(dst[2]) };
// v210 packs 6 pixels in 4 DWORDs.
left = left - (left % 6);
// Adjust pointers.
src_p += left * 4 / 6;
dst_p[C_Y] += left;
dst_p[C_U] += left / 2;
dst_p[C_V] += left / 2;
for (unsigned i = left; i < right - right % 6; i += 6) {
uint32_t w0 = detail::endian_swap<Endian>(*src_p++);
uint32_t w1 = detail::endian_swap<Endian>(*src_p++);
uint32_t w2 = detail::endian_swap<Endian>(*src_p++);
uint32_t w3 = detail::endian_swap<Endian>(*src_p++);
*dst_p[C_U]++ = static_cast<uint16_t>((w0 >> 0) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w0 >> 10) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w0 >> 20) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w1 >> 0) & lsb_10b);
*dst_p[C_U]++ = static_cast<uint16_t>((w1 >> 10) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w1 >> 20) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w2 >> 0) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w2 >> 10) & lsb_10b);
*dst_p[C_U]++ = static_cast<uint16_t>((w2 >> 20) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w3 >> 0) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w3 >> 10) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w3 >> 20) & lsb_10b);
}
if (right % 6) {
// No check needed as v210 is 128-byte aligned.
uint32_t w0 = detail::endian_swap<Endian>(*src_p++);
uint32_t w1 = detail::endian_swap<Endian>(*src_p++);
uint32_t w2 = detail::endian_swap<Endian>(*src_p++);
uint32_t w3 = detail::endian_swap<Endian>(*src_p++);
{
*dst_p[C_U]++ = static_cast<uint16_t>((w0 >> 0) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w0 >> 10) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w0 >> 20) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w1 >> 0) & lsb_10b);
}
if (right % 6 > 2) {
*dst_p[C_U]++ = static_cast<uint16_t>((w1 >> 10) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w1 >> 20) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w2 >> 0) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w2 >> 10) & lsb_10b);
}
if (right % 6 > 4) {
*dst_p[C_U]++ = static_cast<uint16_t>((w2 >> 20) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w3 >> 0) & lsb_10b);
*dst_p[C_V]++ = static_cast<uint16_t>((w3 >> 10) & lsb_10b);
*dst_p[C_Y]++ = static_cast<uint16_t>((w3 >> 20) & lsb_10b);
}
}
}
template <class Endian>
void pack_v210(const void * const src[4], void *dst, unsigned left, unsigned right)
{
const unsigned lsb_10b = 0x3FF;
const uint16_t *src_p[3] = { static_cast<const uint16_t *>(src[0]), static_cast<const uint16_t *>(src[1]), static_cast<const uint16_t *>(src[2]) };
uint32_t *dst_p = static_cast<uint32_t *>(dst);
// v210 packs 6 pixels in 4 DWORDs.
left = left - (left % 6);
// Adjust pointers.
src_p[C_Y] += left;
src_p[C_U] += left / 2;
src_p[C_V] += left / 2;
dst_p += left * 4 / 6;
for (unsigned i = left; i < right - right % 6; i += 6) {
uint32_t w0 = 0;
uint32_t w1 = 0;
uint32_t w2 = 0;
uint32_t w3 = 0;
w0 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 0;
w0 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 10;
w0 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 20;
w1 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 0;
w1 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 10;
w1 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 20;
w2 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 0;
w2 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 10;
w2 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 20;
w3 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 0;
w3 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 10;
w3 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 20;
*dst_p++ = detail::endian_swap<Endian>(w0);
*dst_p++ = detail::endian_swap<Endian>(w1);
*dst_p++ = detail::endian_swap<Endian>(w2);
*dst_p++ = detail::endian_swap<Endian>(w3);
}
if (right % 6) {
uint32_t w0 = 0;
uint32_t w1 = 0;
uint32_t w2 = 0;
uint32_t w3 = 0;
{
w0 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 0;
w0 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 10;
w0 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 20;
w1 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 0;
}
if (right % 6 > 2) {
w1 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 10;
w1 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 20;
w2 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 0;
w2 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 10;
}
if (right % 6 > 4) {
w2 |= static_cast<uint32_t>(*src_p[C_U]++ & lsb_10b) << 20;
w3 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 0;
w3 |= static_cast<uint32_t>(*src_p[C_V]++ & lsb_10b) << 10;
w3 |= static_cast<uint32_t>(*src_p[C_Y]++ & lsb_10b) << 20;
}
// No check needed as v210 is 128-byte aligned.
*dst_p++ = detail::endian_swap<Endian>(w0);
*dst_p++ = detail::endian_swap<Endian>(w1);
*dst_p++ = detail::endian_swap<Endian>(w2);
*dst_p++ = detail::endian_swap<Endian>(w3);
}
}
} // namespace
void packed_to_planar<packed_v210_be>::unpack(const void *src, void * const dst[4], unsigned left, unsigned right)
{
unpack_v210<big_endian_t>(src, dst, left, right);
}
void packed_to_planar<packed_v210_le>::unpack(const void *src, void * const dst[4], unsigned left, unsigned right)
{
unpack_v210<little_endian_t>(src, dst, left, right);
}
void planar_to_packed<packed_v210_be, false>::pack(const void * const src[4], void *dst, unsigned left, unsigned right)
{
pack_v210<big_endian_t>(src, dst, left, right);
}
void planar_to_packed<packed_v210_be, true>::pack(const void * const src[4], void *dst, unsigned left, unsigned right)
{
pack_v210<big_endian_t>(src, dst, left, right);
}
void planar_to_packed<packed_v210_le, false>::pack(const void * const src[4], void *dst, unsigned left, unsigned right)
{
pack_v210<little_endian_t>(src, dst, left, right);
}
void planar_to_packed<packed_v210_le, true>::pack(const void * const src[4], void *dst, unsigned left, unsigned right)
{
pack_v210<little_endian_t>(src, dst, left, right);
}
} // namespace p2p
================================================
FILE: common-src/log/log_styles_model.cpp
================================================
#include "log_styles_model.h"
//==============================================================================
LogStylesModel::LogStylesModel(QObject * a_pParent) :
QAbstractItemModel(a_pParent)
{
}
// END OF LogStylesModel::LogStylesModel(QObject * a_pParent)
//==============================================================================
LogStylesModel::~LogStylesModel()
{
}
// END OF LogStylesModel::~LogStylesModel()
//==============================================================================
QModelIndex LogStylesModel::index(int a_row, int a_column,
const QModelIndex & a_parent) const
{
(void)a_parent;
return createIndex(a_row, a_column);
}
// END OF QModelIndex LogStylesModel::index(int a_row, int a_column,
// const QModelIndex & a_parent) const
//==============================================================================
QModelIndex LogStylesModel::parent(const QModelIndex & a_child) const
{
(void)a_child;
return QModelIndex();
}
// END OF QModelIndex LogStylesModel::parent(const QModelIndex & a_child)
// const
//==============================================================================
Qt::ItemFlags LogStylesModel::flags(const QModelIndex & a_index) const
{
if (!a_index.isValid())
{
return Qt::NoItemFlags;
}
Qt::ItemFlags cellFlags = Qt::NoItemFlags
| Qt::ItemIsEnabled
| Qt::ItemIsSelectable
| Qt::ItemIsUserCheckable
;
return cellFlags;
}
// END OF Qt::ItemFlags LogStylesModel::flags(const QModelIndex & a_index)
// const
//==============================================================================
QVariant LogStylesModel::data(const QModelIndex & a_index, int a_role) const
{
if(!a_index.isValid())
return QVariant();
int row = a_index.row();
int column = a_index.column();
if((row >= (int)m_styles.size()) || (column >= 1))
return QVariant();
if((a_role == Qt::DisplayRole) || (a_role == Qt::ToolTipRole))
return m_styles[row].title;
else if(a_role == Qt::UserRole)
return m_styles[row].name;
else if(a_role == Qt::CheckStateRole)
return m_styles[row].isVisible ? Qt::Checked : Qt::Unchecked;
return QVariant();
}
// END OF QVariant LogStylesModel::data(const QModelIndex & a_index,
// int a_role) const
//==============================================================================
int LogStylesModel::rowCount(const QModelIndex & a_parent) const
{
(void)a_parent;
return (int)m_styles.size();
}
// END OF int LogStylesModel::rowCount(const QModelIndex & a_parent) const
//==============================================================================
int LogStylesModel::columnCount(const QModelIndex & a_parent) const
{
(void)a_parent;
return 1;
}
// END OF int LogStylesModel::columnCount(const QModelIndex & a_parent)
// const
//==============================================================================
bool LogStylesModel::setData(const QModelIndex & a_index,
const QVariant & a_value, int a_role)
{
if(!a_index.isValid())
return false;
int row = a_index.row();
int column = a_index.column();
if((row >= (int)m_styles.size()) || (column >= 1))
return false;
if(a_role == Qt::CheckStateRole)
{
m_styles[row].isVisible = (a_value == Qt::Checked) ? true : false;
return true;
}
return false;
}
// END OF bool LogStylesModel::setData(const QModelIndex & a_index,
// const QVariant & a_value, int a_role)
//==============================================================================
std::vector<TextBlockStyle> LogStylesModel::styles() const
{
return m_styles;
}
// END OF std::vector<TextBlockStyle> LogStylesModel::styles() const
//==============================================================================
void LogStylesModel::setStyles(const std::vector<TextBlockStyle> & a_styles)
{
beginResetModel();
m_styles = a_styles;
endResetModel();
}
// END OF void LogStylesModel::setStyles(
// const std::vector<TextBlockStyle> & a_styles)
//==============================================================================
TextBlockStyle LogStylesModel::style(int a_index) const
{
Q_ASSERT(styleIndexValid(a_index));
return m_styles[a_index];
}
// END OF TextBlockStyle LogStylesModel::style(int a_index) const
//==============================================================================
TextBlockStyle LogStylesModel::style(const QModelIndex & a_index) const
{
return style(a_index.row());
}
// END OF TextBlockStyle LogStylesModel::style(const QModelIndex & a_index)
// const
//==============================================================================
bool LogStylesModel::setStyleFont(int a_index, const QFont & a_font)
{
if(!styleIndexValid(a_index))
return false;
m_styles[a_index].textFormat.setFont(a_font);
return true;
}
// END OF bool LogStylesModel::setStyleFont(int a_index, const QFont & a_font)
//==============================================================================
bool LogStylesModel::setStyleTextColor(int a_index, const QColor & a_color)
{
if(!styleIndexValid(a_index))
return false;
m_styles[a_index].textFormat.setForeground(a_color);
return true;
}
// END OF bool LogStylesModel::setStyleTextColor(int a_index,
// const QColor & a_color)
//==============================================================================
bool LogStylesModel::setStyleBackgroundColor(int a_index,
const QColor & a_color)
{
if(!styleIndexValid(a_index))
return false;
m_styles[a_index].textFormat.setBackground(a_color);
return true;
}
// END OF bool LogStylesModel::setStyleBackgroundColor(int a_index,
// const QColor & a_color)
//==============================================================================
bool LogStylesModel::styleIndexValid(int a_index) const
{
return ((a_index >= 0) && (a_index < (int)m_styles.size()));
}
// END OF bool LogStylesModel::styleIndexValid(int a_index) const
//==============================================================================
================================================
FILE: common-src/log/log_styles_model.h
================================================
#ifndef LOG_STYLES_MODEL_H_INCLUDED
#define LOG_STYLES_MODEL_H_INCLUDED
#include "styled_log_view_structures.h"
#include <QAbstractItemModel>
class LogStylesModel : public QAbstractItemModel
{
Q_OBJECT
public:
LogStylesModel(QObject * a_pParent = nullptr);
virtual ~LogStylesModel();
virtual QModelIndex index(int a_row, int a_column,
const QModelIndex & a_parent = QModelIndex()) const override;
virtual QModelIndex parent(const QModelIndex & a_child) const override;
virtual Qt::ItemFlags flags(const QModelIndex & a_index) const override;
virtual QVariant data(const QModelIndex & a_index,
int a_role = Qt::DisplayRole) const override;
virtual int rowCount(const QModelIndex & a_parent = QModelIndex()) const
override;
virtual int columnCount(const QModelIndex & a_parent = QModelIndex()) const
override;
virtual bool setData(const QModelIndex & a_index, const QVariant & a_value,
int a_role = Qt::EditRole) override;
virtual std::vector<TextBlockStyle> styles() const;
virtual void setStyles(const std::vector<TextBlockStyle> & a_styles);
virtual TextBlockStyle style(int a_index) const;
virtual TextBlockStyle style(const QModelIndex & a_index) const;
virtual bool setStyleFont(int a_index, const QFont & a_font);
virtual bool setStyleTextColor(int a_index, const QColor & a_color);
virtual bool setStyleBackgroundColor(int a_index, const QColor & a_color);
protected:
virtual bool styleIndexValid(int a_index) const;
std::vector<TextBlockStyle> m_styles;
};
#endif // LOG_STYLES_MODEL_H_INCLUDED
================================================
FILE: common-src/log/styled_log_view.cpp
================================================
#include "styled_log_view.h"
#include "styled_log_view_settings_dialog.h"
#include <QMenu>
#include <QScrollBar>
#include <QDir>
#include <QFileDialog>
#include <QFile>
//==============================================================================
const size_t StyledLogView::DEFAULT_MAX_ENTRIES_TO_SHOW = 200;
//==============================================================================
StyledLogView::StyledLogView(QWidget * a_pParent) :
QTextEdit(a_pParent)
, m_millisecondsToDivideBlocks(2000)
, m_pContextMenu(nullptr)
, m_pSettingsDialog(nullptr)
, m_maxEntriesToShow(DEFAULT_MAX_ENTRIES_TO_SHOW)
{
setReadOnly(true);
setContextMenuPolicy(Qt::CustomContextMenu);
addStyle(TextBlockStyle(LOG_STYLE_DEFAULT));
createActionsAndMenus();
m_pSettingsDialog = new StyledLogViewSettingsDialog();
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(slotShowCustomMenu(const QPoint &)));
connect(m_pSettingsDialog, SIGNAL(signalSettingsChanged()),
this, SLOT(slotLogSettingsChanged()));
}
// END OF StyledLogView::StyledLogView(QWidget * a_pParent)
//==============================================================================
StyledLogView::~StyledLogView()
{
delete m_pSettingsDialog;
}
// END OF StyledLogView::~StyledLogView()
//==============================================================================
TextBlockStyle StyledLogView::getStyle(const QString & a_styleName) const
{
TextBlockStyle style(a_styleName);
QString styleName = a_styleName;
QStringList foundAliasesList;
std::vector<TextBlockStyle>::const_iterator it = m_styles.end();
while(true)
{
it = std::find_if(m_styles.begin(), m_styles.end(),
[&](const TextBlockStyle & a_style) -> bool
{
return (a_style.name == styleName);
});
if(it == m_styles.end())
return style;
// Alias retains its own visibility and title
if(it->name == a_styleName)
{
style.isVisible = it->isVisible;
style.title = it->title;
}
if(!it->isAlias)
{
style.textFormat = it->textFormat;
return style;
}
foundAliasesList += it->name;
// Check for aliasing loop
if(foundAliasesList.contains(it->originalStyleName))
return style;
styleName = it->originalStyleName;
}
return style;
}
// END OF TextBlockStyle StyledLogView::getStyle(
// const QString & a_styleName) const
//==============================================================================
void StyledLogView::addStyle(const TextBlockStyle & a_style,
bool a_updateExisting)
{
TextBlockStyle newStyle(a_style);
// Resolve original style for alias to prevent alias loop
if(newStyle.isAlias)
{
TextBlockStyle originalStyle = getStyle(newStyle.originalStyleName);
newStyle.originalStyleName = originalStyle.name;
}
std::vector<TextBlockStyle>::iterator it = std::find_if(m_styles.begin(),
m_styles.end(), [&](const TextBlockStyle & la_style) -> bool
{
return (la_style.name == newStyle.name);
});
if(it == m_styles.end())
m_styles.push_back(newStyle);
else if(a_updateExisting)
*it = newStyle;
}
// END OF void StyledLogView::addStyle(const TextBlockStyle & a_style,
// bool a_updateExisting)
//==============================================================================
void StyledLogView::addStyle(const QString & a_aliasName,
const QString & a_title, const QString & a_originalStyleName)
{
// no aliasing default style name
if(a_aliasName == LOG_STYLE_DEFAULT)
return;
addStyle(TextBlockStyle(a_aliasName, a_title, a_originalStyleName));
}
// END OF void StyledLogView::addStyle(const QString & a_aliasName,
// const QString & a_title, const QString & a_originalStyleName)
//==============================================================================
void StyledLogView::startNewBlock()
{
if(m_entries.empty())
return;
if(m_entries.back().isDivider)
return;
m_entries.push_back(LogEntry::divider());
}
// END OF void StyledLogView::startNewBlock()
//==============================================================================
qint64 StyledLogView::millisecondsToDivideBlocks() const
{
return m_millisecondsToDivideBlocks;
}
// END OF qint64 StyledLogView::millisecondsToDivideBlocks() const
//==============================================================================
bool StyledLogView::setMillisecondsToDivideBlocks(qint64 a_value)
{
if(a_value < 0)
return false;
m_millisecondsToDivideBlocks = a_value;
updateHtml();
return true;
}
// END OF bool StyledLogView::setMillisecondsToDivideBlocks(qint64 a_value)
//==============================================================================
QStringList StyledLogView::styles(bool a_excludeAliases) const
{
QStringList stylesList;
for(const TextBlockStyle & style : m_styles)
if(!(a_excludeAliases && style.isAlias))
stylesList += style.name;
return stylesList;
}
// END OF QStringList StyledLogView::styles(bool a_excludeAliases) const
//==============================================================================
bool StyledLogView::saveHtml(const QString & a_filePath,
bool a_excludeFiltered)
{
if(a_filePath.isEmpty())
return false;
QFile file(a_filePath);
bool result = file.open(QIODevice::WriteOnly);
if(!result)
return false;
QByteArray htmlData = realHtml(a_excludeFiltered).toUtf8();
qint64 bytesWritten = file.write(htmlData);
file.close();
if(bytesWritten != htmlData.size())
return false;
return true;
}
// END OF bool StyledLogView::saveHtml(const QString & a_filePath,
// bool a_excludeFiltered)
//==============================================================================
bool StyledLogView::saveHtml(bool a_excludeFiltered)
{
QString timeString =
QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss-zzz");
QString fileName = tr("vapoursynth_editor_log_{time}.html")
.replace("{time}", timeString);
QString currentDir = QDir(".").absolutePath();
QString filePath = currentDir + QString("/") + fileName;
filePath = QFileDialog::getSaveFileName(this, tr("Save log"),
filePath, tr("HTML files (*.html);;All files (*.*)"));
return saveHtml(filePath, a_excludeFiltered);
}
// END OF bool StyledLogView::saveHtml(bool a_excludeFiltered)
//==============================================================================
void StyledLogView::addEntry(const QString & a_text, const QString & a_style)
{
m_entries.push_back(LogEntry(a_text, a_style));
updateHtml();
}
// END OF void StyledLogView::addEntry(const QString & a_text,
// const QString & a_style)
//==============================================================================
void StyledLogView::addEntry(const LogEntry & a_entry)
{
m_entries.push_back(a_entry);
updateHtml();
}
// END OF void void StyledLogView::addEntry(const LogEntry & a_entry)
//==============================================================================
void StyledLogView::clear()
{
m_entries.clear();
QTextEdit::clear();
}
// END OF void StyledLogView::clear()
//==============================================================================
void StyledLogView::slotSaveHtml()
{
saveHtml();
}
// END OF void StyledLogView::slotSaveHtml()
//==============================================================================
void StyledLogView::slotSaveHtmlFiltered()
{
saveHtml(true);
}
// END OF void StyledLogView::slotSaveHtmlFiltered()
//==============================================================================
void StyledLogView::slotShowCustomMenu(const QPoint & a_position)
{
createActionsAndMenus();
QPoint globalPosition = mapToGlobal(a_position);
m_pContextMenu->popup(globalPosition);
}
// END OF void StyledLogView::slotShowCustomMenu(const QPoint & a_position)
//==============================================================================
void StyledLogView::slotLogSettings()
{
Q_ASSERT(m_pSettingsDialog);
m_pSettingsDialog->setStyles(m_styles);
m_pSettingsDialog->show();
}
// END OF void StyledLogView::slotLogSettings()
//==============================================================================
void StyledLogView::slotLogSettingsChanged()
{
m_styles = m_pSettingsDialog->styles();
updateHtml();
}
// END OF void StyledLogView::slotLogSettingsChanged()
//==============================================================================
void StyledLogView::updateHtml()
{
if(m_entries.empty())
{
QTextEdit::clear();
return;
}
QString borderColor = palette().color(QPalette::Dark).name();
QString html = QString(
"<body>\n"
"<style type=\"text/css\">\n"
"table {"
"border-width: 1px;"
"border-style: solid;"
"border-color: {table-border-color};"
"}\n"
"div {"
"margin-left: 2px;"
"margin-top: 2px;"
"margin-right: 2px;"
"margin-bottom: 2px;"
"}\n"
"</style>\n"
"<table width=\"100%\" cellspacing=\"-1\">\n"
).replace("{table-border-color}", borderColor);
bool openBlock = false;
QDateTime lastTime;
QString lastStyle;
size_t firstEntryToShow = 0;
if(m_entries.size() > m_maxEntriesToShow)
{
firstEntryToShow = m_entries.size() - m_maxEntriesToShow;
html += tr("<tr><td align=\"center\">%1 entries not shown. "
"Save the log to read.</td></tr>\n").arg(firstEntryToShow);
}
for(size_t i = firstEntryToShow; i < m_entries.size(); ++i)
{
const LogEntry & entry = m_entries[i];
TextBlockStyle style = getStyle(entry.style);
if(!style.isVisible)
continue;
if(openBlock)
{
if(entry.isDivider ||
(lastTime.msecsTo(entry.time) > m_millisecondsToDivideBlocks) ||
(entry.style != lastStyle))
{
html += QString("</td></tr>\n");
openBlock = false;
}
}
lastStyle = entry.style;
lastTime = entry.time;
if(entry.isDivider)
continue;
QTextCharFormat format = style.textFormat;
QFont styleFont = format.font();
if(!openBlock)
{
html += QString("<tr bgcolor=\"%1\"><td>")
.arg(format.background().color().name());
QString timeString = entry.time.toString("yyyy-MM-dd hh:mm:ss.zzz");
html += QString("<div><font size=\"-2\" "
"color=\"%1\">%2</font></div>")
.arg(format.foreground().color().name())
.arg(timeString);
openBlock = true;
}
QString entryHtml = entry.text;
entryHtml.replace("\n", "<br>");
if(styleFont.bold())
entryHtml = QString("<b>%1</b>").arg(entryHtml);
if(styleFont.italic())
entryHtml = QString("<i>%1</i>").arg(entryHtml);
if(styleFont.underline())
entryHtml = QString("<u>%1</u>").arg(entryHtml);
if(styleFont.strikeOut())
entryHtml = QString("<s>%1</s>").arg(entryHtml);
html += QString("<div><font face=\"%1\" "
"color=\"%2\">%3</font></div>")
.arg(styleFont.family())
.arg(format.foreground().color().name())
.arg(entryHtml);
}
if(openBlock)
html += QString("</td></tr>\n");
html += QString("</table>\n</body>");
setHtml(html);
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
// END OF void StyledLogView::updateHtml()
//==============================================================================
void StyledLogView::createActionsAndMenus()
{
if(m_pContextMenu)
delete m_pContextMenu;
m_pContextMenu = createStandardContextMenu();
struct ActionToCreate
{
QString title;
const char * slotToConnect;
bool isSeparator;
ActionToCreate(const QString & a_title, const char * a_slotToConnect) :
title(a_title), slotToConnect(a_slotToConnect), isSeparator(false)
{};
ActionToCreate() : title(), slotToConnect(nullptr), isSeparator(true)
{};
};
const ActionToCreate SEPARATOR;
ActionToCreate actionsToCreate[] = {
SEPARATOR,
{tr("Log settings"), SLOT(slotLogSettings())},
SEPARATOR,
{tr("Save"), SLOT(slotSaveHtml())},
{tr("Save filtered"), SLOT(slotSaveHtmlFiltered())},
{tr("Clear"), SLOT(clear())},
};
for(const ActionToCreate & action : actionsToCreate)
{
if(action.isSeparator)
m_pContextMenu->addSeparator();
else
m_pContextMenu->addAction(action.title, this, action.slotToConnect);
}
}
// END OF void StyledLogView::createActionsAndMenus()
//==============================================================================
QString StyledLogView::realHtml(bool a_exclu
gitextract_u1yk7l4b/
├── .gitignore
├── BUILDING
├── CHANGELOG
├── LICENSE
├── README
├── TODO.txt
├── common-src/
│ ├── application_instance_file_guard/
│ │ ├── application_instance_file_guard.cpp
│ │ └── application_instance_file_guard.h
│ ├── chrono.h
│ ├── frame_header_writers/
│ │ ├── frame_header_writer.cpp
│ │ ├── frame_header_writer.h
│ │ ├── frame_header_writer_null.cpp
│ │ ├── frame_header_writer_null.h
│ │ ├── frame_header_writer_y4m.cpp
│ │ └── frame_header_writer_y4m.h
│ ├── helpers.cpp
│ ├── helpers.h
│ ├── helpers_vs.h
│ ├── ipc_defines.h
│ ├── jobs/
│ │ ├── job.cpp
│ │ ├── job.h
│ │ ├── job_variables.cpp
│ │ └── job_variables.h
│ ├── libp2p/
│ │ ├── COPYING
│ │ ├── README.md
│ │ ├── p2p.h
│ │ ├── p2p_api.cpp
│ │ ├── p2p_api.h
│ │ ├── simd/
│ │ │ ├── cpuinfo_x86.cpp
│ │ │ ├── cpuinfo_x86.h
│ │ │ ├── p2p_simd.cpp
│ │ │ ├── p2p_simd.h
│ │ │ └── p2p_sse41.cpp
│ │ └── v210.cpp
│ ├── log/
│ │ ├── log_styles_model.cpp
│ │ ├── log_styles_model.h
│ │ ├── styled_log_view.cpp
│ │ ├── styled_log_view.h
│ │ ├── styled_log_view_core.cpp
│ │ ├── styled_log_view_core.h
│ │ ├── styled_log_view_settings_dialog.cpp
│ │ ├── styled_log_view_settings_dialog.h
│ │ ├── styled_log_view_settings_dialog.ui
│ │ ├── styled_log_view_structures.cpp
│ │ ├── styled_log_view_structures.h
│ │ ├── vs_editor_log.cpp
│ │ ├── vs_editor_log.h
│ │ ├── vs_editor_log_definitions.cpp
│ │ └── vs_editor_log_definitions.h
│ ├── settings/
│ │ ├── settings_definitions.cpp
│ │ ├── settings_definitions.h
│ │ ├── settings_definitions_core.cpp
│ │ ├── settings_definitions_core.h
│ │ ├── settings_manager.cpp
│ │ ├── settings_manager.h
│ │ ├── settings_manager_core.cpp
│ │ └── settings_manager_core.h
│ ├── timeline_slider/
│ │ ├── timeline_slider.cpp
│ │ └── timeline_slider.h
│ ├── vapoursynth/
│ │ ├── vapoursynth_script_processor.cpp
│ │ ├── vapoursynth_script_processor.h
│ │ ├── vs_pack_rgb.cpp
│ │ ├── vs_pack_rgb.h
│ │ ├── vs_script_library.cpp
│ │ ├── vs_script_library.h
│ │ ├── vs_script_processor_structures.cpp
│ │ ├── vs_script_processor_structures.h
│ │ ├── vs_set_matrix.cpp
│ │ └── vs_set_matrix.h
│ ├── version_info.cpp
│ ├── version_info.h
│ ├── win32_console.cpp
│ └── win32_console.h
├── msvc/
│ ├── VapourSynthEditor.sln
│ ├── VapourSynthEditor.vcxproj
│ ├── VapourSynthEditor.vcxproj.filters
│ ├── libp2p/
│ │ ├── libp2p.vcxproj
│ │ └── libp2p.vcxproj.filters
│ ├── vsedit/
│ │ ├── resource.h
│ │ ├── vsedit.rc
│ │ ├── vsedit.vcxproj
│ │ └── vsedit.vcxproj.filters
│ ├── vsedit-encode/
│ │ ├── resource.h
│ │ ├── vsedit-encode.rc
│ │ ├── vsedit-encode.vcxproj
│ │ └── vsedit-encode.vcxproj.filters
│ ├── vsedit-job-server/
│ │ ├── resource.h
│ │ ├── vsedit-job-server.rc
│ │ ├── vsedit-job-server.vcxproj
│ │ └── vsedit-job-server.vcxproj.filters
│ ├── vsedit-job-server-watcher/
│ │ ├── resource.h
│ │ ├── vsedit-job-server-watcher.rc
│ │ ├── vsedit-job-server-watcher.vcxproj
│ │ └── vsedit-job-server-watcher.vcxproj.filters
│ └── vsedit-previewer/
│ ├── resource.h
│ ├── vsedit-previewer.rc
│ ├── vsedit-previewer.vcxproj
│ └── vsedit-previewer.vcxproj.filters
├── pro/
│ ├── build-inno-setup.iss
│ ├── build-msvc.bat
│ ├── common.pri
│ ├── pro.pro
│ ├── vsedit/
│ │ └── vsedit.pro
│ ├── vsedit-encode/
│ │ └── vsedit-encode.pro
│ ├── vsedit-job-server/
│ │ └── vsedit-job-server.pro
│ ├── vsedit-job-server-watcher/
│ │ └── vsedit-job-server-watcher.pro
│ └── vsedit-previewer/
│ └── vsedit-previewer.pro
├── resources/
│ ├── dark/
│ │ ├── LICENSE.rst
│ │ ├── rc/
│ │ │ └── .keep
│ │ ├── style.qrc
│ │ └── style.qss
│ ├── vsedit-job-server-watcher.qrc
│ ├── vsedit.icns
│ └── vsedit.qrc
├── vsedit/
│ └── src/
│ ├── frame_consumers/
│ │ ├── benchmark_dialog.cpp
│ │ ├── benchmark_dialog.h
│ │ ├── benchmark_dialog.ui
│ │ ├── encode_dialog.cpp
│ │ ├── encode_dialog.h
│ │ └── encode_dialog.ui
│ ├── job_server_watcher_socket.cpp
│ ├── job_server_watcher_socket.h
│ ├── main.cpp
│ ├── main_window.cpp
│ ├── main_window.h
│ ├── main_window.ui
│ ├── preview/
│ │ ├── preview_advanced_settings_dialog.cpp
│ │ ├── preview_advanced_settings_dialog.h
│ │ ├── preview_advanced_settings_dialog.ui
│ │ ├── preview_area.cpp
│ │ ├── preview_area.h
│ │ ├── preview_dialog.cpp
│ │ ├── preview_dialog.h
│ │ ├── preview_dialog.ui
│ │ ├── scroll_navigator.cpp
│ │ ├── scroll_navigator.h
│ │ ├── zoom_ratio_spinbox.cpp
│ │ └── zoom_ratio_spinbox.h
│ ├── script_editor/
│ │ ├── number_matcher.cpp
│ │ ├── number_matcher.h
│ │ ├── script_completer.cpp
│ │ ├── script_completer.h
│ │ ├── script_completer_model.cpp
│ │ ├── script_completer_model.h
│ │ ├── script_editor.cpp
│ │ ├── script_editor.h
│ │ ├── syntax_highlighter.cpp
│ │ └── syntax_highlighter.h
│ ├── script_status_bar_widget/
│ │ ├── script_status_bar_widget.cpp
│ │ ├── script_status_bar_widget.h
│ │ └── script_status_bar_widget.ui
│ ├── script_templates/
│ │ ├── drop_file_category_model.cpp
│ │ ├── drop_file_category_model.h
│ │ ├── templates_dialog.cpp
│ │ ├── templates_dialog.h
│ │ └── templates_dialog.ui
│ ├── settings/
│ │ ├── actions_hotkey_edit_model.cpp
│ │ ├── actions_hotkey_edit_model.h
│ │ ├── clearable_key_sequence_editor.cpp
│ │ ├── clearable_key_sequence_editor.h
│ │ ├── item_delegate_for_hotkey.cpp
│ │ ├── item_delegate_for_hotkey.h
│ │ ├── settings_dialog.cpp
│ │ ├── settings_dialog.h
│ │ ├── settings_dialog.ui
│ │ ├── theme_elements_model.cpp
│ │ └── theme_elements_model.h
│ ├── vapoursynth/
│ │ ├── vapoursynth_plugins_manager.cpp
│ │ ├── vapoursynth_plugins_manager.h
│ │ ├── vs_plugin_data.cpp
│ │ ├── vs_plugin_data.h
│ │ ├── vs_script_processor_dialog.cpp
│ │ └── vs_script_processor_dialog.h
│ ├── vsedit_encode_main.cpp
│ └── vsedit_previewer_main.cpp
├── vsedit-job-server/
│ └── src/
│ ├── job_server.cpp
│ ├── job_server.h
│ ├── jobs/
│ │ ├── job_definitions.h
│ │ ├── jobs_manager.cpp
│ │ └── jobs_manager.h
│ └── main.cpp
└── vsedit-job-server-watcher/
└── src/
├── connect_to_server_dialog.cpp
├── connect_to_server_dialog.h
├── connect_to_server_dialog.ui
├── jobs/
│ ├── job_dependencies_delegate.cpp
│ ├── job_dependencies_delegate.h
│ ├── job_edit_dialog.cpp
│ ├── job_edit_dialog.h
│ ├── job_edit_dialog.ui
│ ├── job_state_delegate.cpp
│ ├── job_state_delegate.h
│ ├── jobs_model.cpp
│ └── jobs_model.h
├── main.cpp
├── main_window.cpp
├── main_window.h
├── main_window.ui
├── trusted_clients_addresses_dialog.cpp
├── trusted_clients_addresses_dialog.h
└── trusted_clients_addresses_dialog.ui
SYMBOL INDEX (344 symbols across 113 files)
FILE: common-src/application_instance_file_guard/application_instance_file_guard.cpp
function QString (line 118) | QString ApplicationInstanceFileGuard::error() const
FILE: common-src/application_instance_file_guard/application_instance_file_guard.h
function class (line 7) | class ApplicationInstanceFileGuard
FILE: common-src/chrono.h
type std (line 6) | typedef std::chrono::high_resolution_clock::time_point hr_time_point;
type std (line 7) | typedef std::chrono::high_resolution_clock hr_clock;
type std (line 8) | typedef std::chrono::duration<double, std::ratio<1, 1> > double_duration;
FILE: common-src/frame_header_writers/frame_header_writer.h
function class (line 8) | class FrameHeaderWriter : public QObject
FILE: common-src/frame_header_writers/frame_header_writer_null.cpp
function QByteArray (line 34) | QByteArray FrameHeaderWriterNull::videoHeader(int a_totalFrames)
function QByteArray (line 51) | QByteArray FrameHeaderWriterNull::framePrefix(const VSFrame * a_cpFrame)
function QByteArray (line 69) | QByteArray FrameHeaderWriterNull::framePostfix(const VSFrame * a_cpFrame)
FILE: common-src/frame_header_writers/frame_header_writer_null.h
function class (line 6) | class FrameHeaderWriterNull : public FrameHeaderWriter
FILE: common-src/frame_header_writers/frame_header_writer_y4m.cpp
function QByteArray (line 60) | QByteArray FrameHeaderWriterY4M::videoHeader(int a_totalFrames)
function QByteArray (line 141) | QByteArray FrameHeaderWriterY4M::framePrefix(const VSFrame * a_cpFrame)
function QByteArray (line 161) | QByteArray FrameHeaderWriterY4M::framePostfix(const VSFrame * a_cpFrame)
FILE: common-src/frame_header_writers/frame_header_writer_y4m.h
function class (line 6) | class FrameHeaderWriterY4M : public FrameHeaderWriter
FILE: common-src/helpers.cpp
function genAudioChannelFlag (line 40) | static uint64_t genAudioChannelFlag(std::vector<VSAudioChannels> channels)
function QString (line 84) | QString vsedit::timeToString(double a_seconds, bool a_fullFormat)
function QString (line 135) | QString vsedit::videoInfoString(const VSVideoInfo * a_cpVideoInfo,
function QString (line 166) | QString vsedit::audioInfoString(const VSAudioInfo * a_cpAudioInfo,
function QString (line 206) | QString vsedit::nodeInfoString(const VSNodeInfo & a_nodeInfo,
function QTime (line 238) | QTime vsedit::secondsToQTime(double a_seconds)
function QString (line 278) | QString vsedit::subsamplingString(int a_subsamplingW, int a_subsamplingH)
function QString (line 305) | QString vsedit::subsamplingString(const VSVideoFormat * a_cpFormat)
function QString (line 317) | QString vsedit::resolvePathFromApplication(const QString & a_relativePath)
function QByteArray (line 340) | QByteArray vsedit::jsonMessage(const QString & a_command,
function QByteArray (line 350) | QByteArray vsedit::jsonMessage(const QString & a_command,
function QByteArray (line 360) | QByteArray vsedit::jsonMessage(const QString & a_command,
FILE: common-src/helpers.h
function namespace (line 20) | namespace vsedit
FILE: common-src/helpers_vs.h
type class (line 9) | enum class
function VSMediaTypePicker (line 32) | VSMediaTypePicker(const TV * a_pTV) : VSMediaTypePicker()
function VSMediaTypePicker (line 41) | VSMediaTypePicker(const TA * a_pTA) : VSMediaTypePicker()
function TV (line 63) | const TV * getAsVideo() const
function TA (line 68) | const TA * getAsAudio() const
function set (line 73) | void set(const TV * a_pTV)
function set (line 80) | void set(const TA * a_pTA)
function setNull (line 87) | void setNull()
FILE: common-src/jobs/job.cpp
function QUuid (line 89) | QUuid vsedit::Job::id() const
function JobType (line 108) | JobType vsedit::Job::type() const
function QString (line 127) | QString vsedit::Job::scriptName() const
function QString (line 146) | QString vsedit::Job::scriptText() const
function EncodingHeaderType (line 165) | EncodingHeaderType vsedit::Job::encodingHeaderType() const
function QString (line 183) | QString vsedit::Job::executablePath() const
function QString (line 200) | QString vsedit::Job::arguments() const
function QString (line 219) | QString vsedit::Job::shellCommand() const
function JobState (line 238) | JobState vsedit::Job::state() const
function QString (line 276) | QString vsedit::Job::subject() const
function JobProperties (line 451) | JobProperties vsedit::Job::properties() const
function VSVideoInfo (line 470) | const VSVideoInfo * vsedit::Job::videoInfo() const
type JobVariableEvaluator (line 1156) | struct JobVariableEvaluator
function QString (line 1411) | QString vsedit::Job::decodeArguments(const QString & a_arguments) const
FILE: common-src/jobs/job.h
type class (line 38) | enum class
FILE: common-src/jobs/job_variables.h
function class (line 9) | class JobVariables
FILE: common-src/libp2p/p2p.h
function namespace (line 34) | namespace P2P_NAMESPACE {
type uint48 (line 124) | struct uint48 {
function contains (line 227) | struct mask4 {
function find (line 235) | constexpr unsigned find(uint8_t val) const
type T (line 245) | typedef T type;
function uint24 (line 249) | struct numeric_type<uint24> {
function uint48 (line 254) | struct numeric_type<uint48> {
function make_mask (line 274) | constexpr uint32_t make_mask(uint8_t x)
function make_mask (line 279) | constexpr uint32_t make_mask(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
type typename (line 288) | typedef typename std::conditional<std::is_same<native_endian_t, big_endi...
type Planar (line 304) | typedef Planar planar_type;
type Packed (line 305) | typedef Packed packed_type;
type Endian (line 306) | typedef Endian endian;
function detail (line 312) | static constexpr detail::mask4 shift_mask{ ShiftMask };
FILE: common-src/libp2p/p2p_api.cpp
type packing_traits (line 13) | struct packing_traits {
type p2p_packing (line 14) | enum p2p_packing
function packing_traits (line 61) | const packing_traits &lookup_traits(enum p2p_packing packing)
type p2p_packing (line 14) | enum p2p_packing
function T (line 73) | T *increment_ptr(T *ptr, ptrdiff_t n)
function copy_plane_fast (line 78) | void copy_plane_fast(const void *src, void *dst, ptrdiff_t src_stride, p...
function unpack_nv16_plane (line 89) | void unpack_nv16_plane(const void *src, void *dst, ptrdiff_t src_stride,...
function pack_nv16_plane (line 106) | void pack_nv16_plane(const void *src, void *dst, ptrdiff_t src_stride, p...
function p2p_unpack_func (line 126) | p2p_unpack_func p2p_select_unpack_func(enum p2p_packing packing)
function p2p_pack_func (line 131) | p2p_pack_func p2p_select_pack_func(enum p2p_packing packing)
function p2p_pack_func (line 136) | p2p_pack_func p2p_select_pack_func_ex(enum p2p_packing packing, int alph...
function p2p_unpack_frame (line 142) | void p2p_unpack_frame(const struct p2p_buffer_param *param, unsigned lon...
function p2p_pack_frame (line 175) | void p2p_pack_frame(const struct p2p_buffer_param *param, unsigned long ...
FILE: common-src/libp2p/p2p_api.h
type p2p_packing (line 17) | enum p2p_packing {
type p2p_buffer_param (line 114) | struct p2p_buffer_param {
type p2p_packing (line 133) | enum p2p_packing
type p2p_packing (line 134) | enum p2p_packing
type p2p_packing (line 135) | enum p2p_packing
type p2p_buffer_param (line 144) | struct p2p_buffer_param
type p2p_buffer_param (line 145) | struct p2p_buffer_param
FILE: common-src/libp2p/simd/cpuinfo_x86.cpp
type P2P_NAMESPACE (line 20) | namespace P2P_NAMESPACE {
type simd (line 21) | namespace simd {
function do_cpuid (line 32) | void do_cpuid(int regs[4], int eax, int ecx)
function do_xgetbv (line 52) | unsigned long long do_xgetbv(unsigned ecx)
function X86Capabilities (line 65) | X86Capabilities do_query_x86_capabilities() noexcept
function do_query_x86_deterministic_cache_parameters (line 151) | void do_query_x86_deterministic_cache_parameters(X86CacheHierarchy &...
function X86CacheHierarchy (line 209) | X86CacheHierarchy do_query_x86_cache_hierarchy_intel(int max_feature...
function X86CacheHierarchy (line 257) | X86CacheHierarchy do_query_x86_cache_hierarchy_amd(int max_feature) ...
function X86CacheHierarchy (line 309) | X86CacheHierarchy do_query_x86_cache_hierarchy() noexcept
function X86Capabilities (line 347) | X86Capabilities query_x86_capabilities() noexcept
function X86CacheHierarchy (line 353) | X86CacheHierarchy query_x86_cache_hierarchy() noexcept
function cpu_cache_size_x86 (line 359) | unsigned long cpu_cache_size_x86() noexcept
FILE: common-src/libp2p/simd/cpuinfo_x86.h
function namespace (line 11) | namespace P2P_NAMESPACE {
FILE: common-src/libp2p/simd/p2p_simd.cpp
type P2P_NAMESPACE (line 11) | namespace P2P_NAMESPACE {
type detail (line 12) | namespace detail {
function populate_unpack_table (line 19) | auto populate_unpack_table()
function populate_pack_table (line 40) | auto populate_pack_table()
function unpack_func (line 64) | unpack_func search_unpack_func(const std::type_info &ti)
function pack_func (line 77) | pack_func search_pack_func(const std::type_info &ti, bool alpha_one_...
FILE: common-src/libp2p/simd/p2p_simd.h
function namespace (line 10) | namespace P2P_NAMESPACE {
FILE: common-src/libp2p/simd/p2p_sse41.cpp
type P2P_NAMESPACE (line 8) | namespace P2P_NAMESPACE {
type simd (line 9) | namespace simd {
function extract_epi32 (line 14) | uint32_t extract_epi32(__m128i x)
function unpack_rgb32_sse41 (line 20) | void unpack_rgb32_sse41(const void *src, void * const * dst, unsigne...
function pack_rgb32_sse41 (line 93) | void pack_rgb32_sse41(const void * const *src, void *dst, unsigned l...
FILE: common-src/libp2p/v210.cpp
type P2P_NAMESPACE (line 3) | namespace P2P_NAMESPACE {
function unpack_v210 (line 8) | void unpack_v210(const void *src, void * const dst[4], unsigned left, ...
function pack_v210 (line 76) | void pack_v210(const void * const src[4], void *dst, unsigned left, un...
FILE: common-src/log/log_styles_model.cpp
function QModelIndex (line 20) | QModelIndex LogStylesModel::index(int a_row, int a_column,
function QModelIndex (line 31) | QModelIndex LogStylesModel::parent(const QModelIndex & a_child) const
function QVariant (line 61) | QVariant LogStylesModel::data(const QModelIndex & a_index, int a_role) c...
function TextBlockStyle (line 149) | TextBlockStyle LogStylesModel::style(int a_index) const
function TextBlockStyle (line 158) | TextBlockStyle LogStylesModel::style(const QModelIndex & a_index) const
FILE: common-src/log/log_styles_model.h
function class (line 8) | class LogStylesModel : public QAbstractItemModel
FILE: common-src/log/styled_log_view.cpp
function TextBlockStyle (line 48) | TextBlockStyle StyledLogView::getStyle(const QString & a_styleName) const
function qint64 (line 152) | qint64 StyledLogView::millisecondsToDivideBlocks() const
function QStringList (line 173) | QStringList StyledLogView::styles(bool a_excludeAliases) const
type ActionToCreate (line 427) | struct ActionToCreate
method ActionToCreate (line 433) | ActionToCreate(const QString & a_title, const char * a_slotToConnect) :
method ActionToCreate (line 437) | ActionToCreate() : title(), slotToConnect(nullptr), isSeparator(true)
function QString (line 464) | QString StyledLogView::realHtml(bool a_excludeFiltered) const
FILE: common-src/log/styled_log_view.h
function class (line 11) | class StyledLogView : public QTextEdit
FILE: common-src/log/styled_log_view_core.cpp
function LogEntry (line 41) | LogEntry LogEntry::divider()
function QJsonObject (line 49) | QJsonObject LogEntry::toJson() const
function LogEntry (line 64) | LogEntry LogEntry::fromJson(const QJsonObject & a_object)
FILE: common-src/log/styled_log_view_core.h
type LogEntry (line 20) | struct LogEntry
FILE: common-src/log/styled_log_view_settings_dialog.h
function class (line 10) | class StyledLogViewSettingsDialog : public QDialog
FILE: common-src/log/styled_log_view_structures.h
type TextBlockStyle (line 11) | struct TextBlockStyle
FILE: common-src/log/vs_editor_log.cpp
function QString (line 24) | QString VSEditorLog::name() const
FILE: common-src/log/vs_editor_log.h
function class (line 9) | class VSEditorLog : public StyledLogView
FILE: common-src/log/vs_editor_log_definitions.cpp
function QString (line 30) | QString vsMessageTypeToStyleName(int a_messageType)
FILE: common-src/settings/settings_definitions.h
type class (line 16) | enum class
type class (line 23) | enum class
type class (line 29) | enum class
type class (line 36) | enum class
type StandardAction (line 43) | struct StandardAction
type CodeSnippet (line 54) | struct CodeSnippet
type DropFileCategory (line 66) | struct DropFileCategory
FILE: common-src/settings/settings_definitions_core.cpp
function QString (line 53) | QString JobProperties::typeName(JobType a_type)
function QString (line 65) | QString JobProperties::stateName(JobState a_state)
function QString (line 85) | QString JobProperties::subject() const
function QJsonObject (line 135) | QJsonObject JobProperties::toJson() const
function JobProperties (line 165) | JobProperties JobProperties::fromJson(const QJsonObject & a_object)
FILE: common-src/settings/settings_definitions_core.h
type class (line 12) | enum class
type class (line 23) | enum class
type class (line 31) | enum class
type class (line 38) | enum class
type class (line 46) | enum class
type class (line 53) | enum class
type class (line 59) | enum class
type class (line 66) | enum class
type JobProperties (line 102) | struct JobProperties
type EncodingPreset (line 140) | struct EncodingPreset
FILE: common-src/settings/settings_manager.cpp
function QAction (line 290) | QAction * SettingsManager::createStandardAction(const QString & a_actionID,
function QKeySequence (line 312) | QKeySequence SettingsManager::getDefaultHotkey(const QString & a_actionI...
function QKeySequence (line 325) | QKeySequence SettingsManager::getHotkey(const QString & a_actionID) const
function QTextCharFormat (line 345) | QTextCharFormat SettingsManager::getDefaultTextFormat(
function QTextCharFormat (line 428) | QTextCharFormat SettingsManager::getTextFormat(const QString & a_textFor...
function QColor (line 451) | QColor SettingsManager::getDefaultColor(const QString & a_colorID) const
function QColor (line 491) | QColor SettingsManager::getColor(const QString & a_colorID) const
function QString (line 512) | QString SettingsManager::getLastUsedPath() const
function QByteArray (line 528) | QByteArray SettingsManager::getMainWindowGeometry() const
function QByteArray (line 554) | QByteArray SettingsManager::getPreviewDialogGeometry() const
function QPoint (line 578) | QPoint SettingsManager::getLastPreviewScrollBarPositions() const
function QByteArray (line 595) | QByteArray SettingsManager::getJobServerWatcherGeometry() const
function QByteArray (line 621) | QByteArray SettingsManager::getJobsHeaderState() const
function ZoomMode (line 658) | ZoomMode SettingsManager::getZoomMode() const
function CropMode (line 695) | CropMode SettingsManager::getCropMode() const
function QStringList (line 732) | QStringList SettingsManager::getRecentFilesList() const
function PlayFPSLimitMode (line 830) | PlayFPSLimitMode SettingsManager::getPlayFPSLimitMode() const
function QString (line 879) | QString SettingsManager::getTabText() const
function qlonglong (line 926) | qlonglong SettingsManager::getLastPreviewTimestamp(bool a_inPreviewer) c...
function SyncOutputNodesMode (line 942) | SyncOutputNodesMode SettingsManager::getSyncOutputMode() const
function QString (line 955) | QString SettingsManager::getDefaultNewScriptTemplate()
function QString (line 963) | QString SettingsManager::getNewScriptTemplate()
function CodeSnippet (line 994) | CodeSnippet SettingsManager::getCodeSnippet(const QString & a_name) const
function QString (line 1070) | QString SettingsManager::getDropFileTemplate(const QString & a_filePath)...
function QString (line 1222) | QString SettingsManager::getLastSnapshotExtension() const
function QString (line 1274) | QString SettingsManager::getSnapshotTemplate() const
FILE: common-src/settings/settings_manager.h
function class (line 14) | class SettingsManager : public SettingsManagerCore
FILE: common-src/settings/settings_manager_core.cpp
function QVariant (line 172) | QVariant SettingsManagerCore::valueInGroup(const QString & a_group,
function QVariant (line 204) | QVariant SettingsManagerCore::value(const QString & a_key,
function QStringList (line 218) | QStringList SettingsManagerCore::getVapourSynthLibraryPaths() const
function ResamplingFilter (line 233) | ResamplingFilter SettingsManagerCore::getChromaResamplingFilter() const
function YuvMatrixCoefficients (line 246) | YuvMatrixCoefficients SettingsManagerCore::getYuvMatrixCoefficients() const
function ChromaPlacement (line 260) | ChromaPlacement SettingsManagerCore::getChromaPlacement() const
function DitherType (line 309) | DitherType SettingsManagerCore::getDitherType() const
function EncodingPreset (line 354) | EncodingPreset SettingsManagerCore::getEncodingPreset(const QString & a_...
function QStringList (line 533) | QStringList SettingsManagerCore::getRecentJobServers() const
function QStringList (line 550) | QStringList SettingsManagerCore::getTrustedClientsAddresses() const
FILE: common-src/settings/settings_manager_core.h
function class (line 11) | class SettingsManagerCore : public QObject
FILE: common-src/timeline_slider/timeline_slider.cpp
function QRect (line 773) | QRect TimeLineSlider::slideLineRect() const
function QRect (line 787) | QRect TimeLineSlider::slideLineActiveRect() const
FILE: common-src/timeline_slider/timeline_slider.h
function class (line 12) | class TimeLineSlider : public QWidget
FILE: common-src/vapoursynth/vapoursynth_script_processor.cpp
function frameReady (line 21) | void VS_CC frameReady(void * a_pUserData,
function QString (line 234) | QString VapourSynthScriptProcessor::error() const
function VSNodeInfo (line 250) | VSNodeInfo VapourSynthScriptProcessor::nodeInfo(int a_outputIndex)
function QString (line 356) | const QString & VapourSynthScriptProcessor::script() const
function QString (line 364) | const QString & VapourSynthScriptProcessor::scriptName() const
function NodePair (line 868) | NodePair & VapourSynthScriptProcessor::getNodePair(int a_outputIndex,
function QString (line 910) | QString VapourSynthScriptProcessor::framePropsString(
FILE: common-src/vapoursynth/vapoursynth_script_processor.h
function class (line 19) | class VapourSynthScriptProcessor : public QObject
FILE: common-src/vapoursynth/vs_pack_rgb.cpp
type PackData (line 8) | struct PackData
function packFree (line 14) | void packFree(void *instanceData, [[maybe_unused]] VSCore *core, const V...
function VSFrame (line 24) | const VSFrame *packGetFrame(int n, int activationReason, void *instanceD...
function VSNode (line 65) | VSNode *packRGBFilter(VSNode *rgbNode, VSNode *outputNode, bool use10bit...
FILE: common-src/vapoursynth/vs_script_library.cpp
function vsMessageHandler (line 12) | void VS_CC vsMessageHandler(int a_msgType, const char * a_message,
function VSAPI (line 107) | const VSAPI * VSScriptLibrary::getVSAPI()
function VSScript (line 118) | VSScript * VSScriptLibrary::createScript(VSCore * a_pCore)
function VSCore (line 159) | VSCore *VSScriptLibrary::createCore(int a_flag)
function VSNode (line 199) | VSNode * VSScriptLibrary::getOutput(VSScript * a_pScript, int a_index)
function QString (line 236) | QString VSScriptLibrary::VSAPIInfo()
function QString (line 243) | QString VSScriptLibrary::VSSAPIInfo()
FILE: common-src/vapoursynth/vs_script_library.h
type VSSCRIPTAPI (line 16) | typedef const VSSCRIPTAPI * (VS_CC * FNP_getVSSAPI)(int);
function class (line 21) | class VSScriptLibrary : public QObject
FILE: common-src/vapoursynth/vs_script_processor_structures.h
type Frame (line 8) | struct Frame
type FrameTicket (line 23) | struct FrameTicket
type NodePair (line 43) | struct NodePair
FILE: common-src/vapoursynth/vs_set_matrix.cpp
type setMatrixData (line 9) | struct setMatrixData
function VSFrame (line 16) | const VSFrame * VS_CC setMatrixGetFrame(int n, int activationReason, voi...
function setMatrixFree (line 67) | void VS_CC setMatrixFree(void *instanceData, VSCore *core, const VSAPI *...
function setMatrixFilter (line 74) | void VS_CC setMatrixFilter(const VSMap *in, VSMap *out, VSCore *core, co...
FILE: common-src/version_info.cpp
function print_version (line 5) | void print_version()
function version_compare (line 10) | int version_compare(int major1, int minor1, int major2, int minor2)
FILE: common-src/win32_console.h
function class (line 11) | class AttachedConsole
FILE: vsedit-job-server-watcher/src/connect_to_server_dialog.h
function class (line 10) | class ConnectToServerDialog : public QDialog
FILE: vsedit-job-server-watcher/src/jobs/job_dependencies_delegate.cpp
function QWidget (line 28) | QWidget * JobDependenciesDelegate::createEditor(QWidget * a_pParent,
FILE: vsedit-job-server-watcher/src/jobs/job_dependencies_delegate.h
function class (line 6) | class JobDependenciesDelegate : public QStyledItemDelegate
FILE: vsedit-job-server-watcher/src/jobs/job_edit_dialog.cpp
function JobProperties (line 82) | JobProperties JobEditDialog::jobProperties() const
function QString (line 408) | QString JobEditDialog::chooseExecutable(const QString & a_dialogTitle,
FILE: vsedit-job-server-watcher/src/jobs/job_edit_dialog.h
function class (line 11) | class JobEditDialog : public QDialog
FILE: vsedit-job-server-watcher/src/jobs/job_state_delegate.cpp
function QColor (line 73) | QColor JobStateDelegate::jobStateColor(JobState a_state,
FILE: vsedit-job-server-watcher/src/jobs/job_state_delegate.h
function class (line 8) | class JobStateDelegate : public QStyledItemDelegate
FILE: vsedit-job-server-watcher/src/jobs/jobs_model.cpp
function QModelIndex (line 42) | QModelIndex JobsModel::index(int a_row, int a_column,
function QModelIndex (line 53) | QModelIndex JobsModel::parent(const QModelIndex & a_child) const
function QVariant (line 88) | QVariant JobsModel::headerData(int a_section, Qt::Orientation a_orientat...
function QVariant (line 126) | QVariant JobsModel::data(const QModelIndex & a_index, int a_role) const
function JobProperties (line 298) | JobProperties JobsModel::jobProperties(int a_index) const
FILE: vsedit-job-server-watcher/src/jobs/jobs_model.h
function class (line 13) | class JobsModel : public QAbstractItemModel
FILE: vsedit-job-server-watcher/src/main.cpp
function handleQtMessage (line 14) | void handleQtMessage(QtMsgType a_type, const QMessageLogContext & a_cont...
function main (line 65) | int main(int argc, char *argv[])
FILE: vsedit-job-server-watcher/src/main_window.cpp
type ActionToCreate (line 1174) | struct ActionToCreate
FILE: vsedit-job-server-watcher/src/main_window.h
type class (line 112) | enum class
FILE: vsedit-job-server-watcher/src/trusted_clients_addresses_dialog.cpp
function QStringList (line 50) | QStringList TrustedClientsAddressesDialog::addresses() const
FILE: vsedit-job-server-watcher/src/trusted_clients_addresses_dialog.h
function class (line 8) | class TrustedClientsAddressesDialog : public QDialog
FILE: vsedit-job-server/src/job_server.cpp
function QByteArray (line 447) | QByteArray JobServer::jobsInfoMessage() const
function QByteArray (line 459) | QByteArray JobServer::completeLogMessage() const
FILE: vsedit-job-server/src/job_server.h
function class (line 20) | class JobServer : public QObject
FILE: vsedit-job-server/src/jobs/job_definitions.h
type class (line 6) | enum class
type JobTicket (line 12) | struct JobTicket
FILE: vsedit-job-server/src/jobs/jobs_manager.h
type class (line 79) | enum class
FILE: vsedit-job-server/src/main.cpp
function main (line 13) | int main(int argc, char *argv[])
FILE: vsedit/src/frame_consumers/benchmark_dialog.h
function class (line 11) | class ScriptBenchmarkDialog : public VSScriptProcessorDialog
FILE: vsedit/src/frame_consumers/encode_dialog.h
function class (line 11) | class EncodeDialog : public QDialog
FILE: vsedit/src/job_server_watcher_socket.h
function class (line 6) | class JobServerWatcherSocket : public QObject
FILE: vsedit/src/main.cpp
function toggleAttachedConsole (line 20) | void toggleAttachedConsole()
function handleQtMessage (line 29) | void handleQtMessage(QtMsgType a_type, const QMessageLogContext & a_cont...
function main (line 80) | int main(int argc, char *argv[])
FILE: vsedit/src/main_window.cpp
type ActionToCreate (line 714) | struct ActionToCreate
FILE: vsedit/src/main_window.h
function class (line 20) | class MainWindow : public QMainWindow
FILE: vsedit/src/preview/preview_advanced_settings_dialog.h
function class (line 8) | class PreviewAdvancedSettingsDialog : public QDialog
FILE: vsedit/src/preview/preview_area.cpp
function QPointF (line 261) | QPointF PreviewArea::pixelPosition() const
function QPoint (line 269) | QPoint PreviewArea::getScrollBarPositions() const
FILE: vsedit/src/preview/preview_area.h
function class (line 15) | class PreviewArea : public QScrollArea
FILE: vsedit/src/preview/preview_dialog.cpp
function dither32to16 (line 47) | static inline uint16_t dither32to16(uint32_t a)
function dither32Fto16 (line 54) | static inline int16_t dither32Fto16(float a)
function QPoint (line 2008) | QPoint PreviewDialog::loadLastScrollBarPositions() const
function QByteArray (line 2075) | QByteArray PreviewDialog::readAudioFrame(const VSFrame *a_cpFrame)
type ActionToCreate (line 2372) | struct ActionToCreate
type ZoomModeAction (line 2522) | struct ZoomModeAction
type ScaleModeAction (line 2557) | struct ScaleModeAction
type TimeLineModeAction (line 2602) | struct TimeLineModeAction
type p2p_packing (line 3122) | enum p2p_packing
function QPixmap (line 3180) | QPixmap PreviewDialog::pixmapFromRGB(
function qlonglong (line 3257) | qlonglong PreviewDialog::frameToTimestamp(int a_frame)
FILE: vsedit/src/preview/preview_dialog.h
function class (line 37) | class PreviewDialog : public VSScriptProcessorDialog
function virtual (line 215) | virtual void stopAndCleanUp() override;
FILE: vsedit/src/preview/scroll_navigator.h
function class (line 8) | class ScrollNavigator : public QWidget
FILE: vsedit/src/preview/zoom_ratio_spinbox.h
function class (line 8) | class ZoomRatioSpinBox : public QDoubleSpinBox
FILE: vsedit/src/script_editor/number_matcher.h
function class (line 7) | class NumberMatcher
FILE: vsedit/src/script_editor/script_completer.cpp
function QString (line 20) | QString ScriptCompleter::pathFromIndex(const QModelIndex & a_index) const
function QStringList (line 39) | QStringList ScriptCompleter::splitPath(const QString & a_path) const
FILE: vsedit/src/script_editor/script_completer.h
function class (line 6) | class ScriptCompleter : public QCompleter
FILE: vsedit/src/script_editor/script_completer_model.h
function class (line 8) | class ScriptCompleterModel : public QStandardItemModel
FILE: vsedit/src/script_editor/script_editor.cpp
function QString (line 108) | QString ScriptEditor::text() const
function QPoint (line 116) | QPoint ScriptEditor::cursorPosition() const
type ActionToCreate (line 895) | struct ActionToCreate
function QString (line 939) | QString ScriptEditor::getVapourSynthCoreName() const
FILE: vsedit/src/script_editor/script_editor.h
function class (line 25) | class ScriptEditor : public QPlainTextEdit
FILE: vsedit/src/script_editor/syntax_highlighter.cpp
type BlockState (line 14) | enum class BlockState : int
type TokenType (line 22) | enum class TokenType
type Token (line 35) | struct Token
method Token (line 42) | Token(const QString & a_text, int a_start, int a_length, TokenType a_t...
FILE: vsedit/src/script_editor/syntax_highlighter.h
function class (line 12) | class SyntaxHighlighter : public QSyntaxHighlighter
FILE: vsedit/src/script_status_bar_widget/script_status_bar_widget.h
function class (line 11) | class ScriptStatusBarWidget: public QWidget
FILE: vsedit/src/script_templates/drop_file_category_model.cpp
function QModelIndex (line 33) | QModelIndex DropFileCategoryModel::index(int a_row, int a_column,
function QModelIndex (line 44) | QModelIndex DropFileCategoryModel::parent(const QModelIndex & a_child) c...
function QVariant (line 75) | QVariant DropFileCategoryModel::data(const QModelIndex & a_index, int a_...
function QVariant (line 101) | QVariant DropFileCategoryModel::headerData(int a_section,
function QString (line 243) | QString DropFileCategoryModel::sourceTemplate(int a_index) const
FILE: vsedit/src/script_templates/drop_file_category_model.h
function class (line 8) | class DropFileCategoryModel : public QAbstractItemModel
FILE: vsedit/src/script_templates/templates_dialog.h
function class (line 14) | class TemplatesDialog : public QDialog
FILE: vsedit/src/settings/actions_hotkey_edit_model.cpp
function QModelIndex (line 34) | QModelIndex ActionsHotkeyEditModel::index(int a_row, int a_column,
function QModelIndex (line 45) | QModelIndex ActionsHotkeyEditModel::parent(const QModelIndex & a_child) ...
function QVariant (line 77) | QVariant ActionsHotkeyEditModel::data(const QModelIndex & a_index, int a...
FILE: vsedit/src/settings/actions_hotkey_edit_model.h
function class (line 8) | class ActionsHotkeyEditModel : public QAbstractItemModel
FILE: vsedit/src/settings/clearable_key_sequence_editor.cpp
function QKeySequence (line 43) | QKeySequence ClearableKeySequenceEditor::keySequence() const
FILE: vsedit/src/settings/clearable_key_sequence_editor.h
function class (line 10) | class ClearableKeySequenceEditor : public QWidget
FILE: vsedit/src/settings/item_delegate_for_hotkey.cpp
function QWidget (line 22) | QWidget * ItemDelegateForHotkey::createEditor(QWidget * a_pParent,
FILE: vsedit/src/settings/item_delegate_for_hotkey.h
function class (line 6) | class ItemDelegateForHotkey : public QStyledItemDelegate
FILE: vsedit/src/settings/settings_dialog.h
function class (line 12) | class SettingsDialog : public QDialog
FILE: vsedit/src/settings/theme_elements_model.cpp
function QModelIndex (line 26) | QModelIndex ThemeElementsModel::index(int a_row, int a_column,
function QModelIndex (line 37) | QModelIndex ThemeElementsModel::parent(const QModelIndex & a_child) const
function QVariant (line 66) | QVariant ThemeElementsModel::data(const QModelIndex & a_index, int a_rol...
function ThemeElementData (line 192) | ThemeElementData ThemeElementsModel::getThemeElementData(const QString &...
FILE: vsedit/src/settings/theme_elements_model.h
type class (line 12) | enum class
type ThemeElementData (line 18) | struct ThemeElementData
type std (line 28) | typedef std::vector<ThemeElementData> ThemeElementsList;
function class (line 30) | class ThemeElementsModel : public QAbstractItemModel
FILE: vsedit/src/vapoursynth/vapoursynth_plugins_manager.cpp
function QStringList (line 94) | QStringList VapourSynthPluginsManager::functions() const
function VSPluginsList (line 110) | VSPluginsList VapourSynthPluginsManager::pluginsList() const
FILE: vsedit/src/vapoursynth/vapoursynth_plugins_manager.h
function class (line 13) | class VapourSynthPluginsManager : public QObject
FILE: vsedit/src/vapoursynth/vs_plugin_data.cpp
function QString (line 47) | QString VSData::FunctionArgument::toString() const
function QString (line 92) | QString VSData::Function::toString() const
FILE: vsedit/src/vapoursynth/vs_plugin_data.h
function namespace (line 9) | namespace VSData
type std (line 62) | typedef std::vector<VSData::Plugin> VSPluginsList;
FILE: vsedit/src/vapoursynth/vs_script_processor_dialog.cpp
function QString (line 140) | const QString & VSScriptProcessorDialog::script() const
function QString (line 148) | const QString & VSScriptProcessorDialog::scriptName() const
FILE: vsedit/src/vapoursynth/vs_script_processor_dialog.h
type VSAPI (line 22) | struct VSAPI
type VSVideoInfo (line 23) | struct VSVideoInfo
type VSFrame (line 24) | struct VSFrame
function class (line 26) | class VSScriptProcessorDialog : public QDialog
FILE: vsedit/src/vsedit_encode_main.cpp
function writeLogMessageByTypename (line 23) | void writeLogMessageByTypename(const QString & a_msg, const QString & a_...
function writeLogMessage (line 87) | void writeLogMessage(int a_msgType, const QString & a_msg)
function handleQtMessage (line 93) | void handleQtMessage(QtMsgType a_type,
function main (line 135) | int main(int argc, char *argv[])
FILE: vsedit/src/vsedit_previewer_main.cpp
function writeLogMessageByTypename (line 26) | void writeLogMessageByTypename(const QString & a_msg, const QString & a_...
function writeLogMessage (line 90) | void writeLogMessage(int a_msgType, const QString & a_msg)
function handleQtMessage (line 96) | void handleQtMessage(QtMsgType a_type,
function main (line 138) | int main(int argc, char *argv[])
Condensed preview — 200 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,401K chars).
[
{
"path": ".gitignore",
"chars": 842,
"preview": "!/.gitignore\n!*.pro\n!*.pri\n!*.bat\n!/common-src/\n!/vsedit/src/\n!/vsedit-job-server/src/\n!/vsedit-job-server-watcher/src/\n"
},
{
"path": "BUILDING",
"chars": 1535,
"preview": "THIS MANUAL IS A DRAFT. PLEASE REPORT ANY MISTAKES OR ADDITIONS AT https://github.com/YomikoR/VapourSynth-Editor/issues\n"
},
{
"path": "CHANGELOG",
"chars": 12417,
"preview": "r19-mod-6.10\n-BUGFIX: Cannot load old vsscript from list due to change on the file name.\n\nr19-mod-6.9\n-BUGFIX: Aborting "
},
{
"path": "LICENSE",
"chars": 1138,
"preview": "Copyright (c) 2014 - 2017 Aleksey [Mystery Keeper] Lyashin\nmystkeeper@gmail.com\nCopyright (c) 2022 - 2026 YomikoR\n\nPermi"
},
{
"path": "README",
"chars": 819,
"preview": "VapourSynth Editor r19-mod-6.10\n\nBy Aleksey [Mystery Keeper] Lyashin\nmystkeeper@gmail.com\nhttp://mysterykeeper.ru\n\nModif"
},
{
"path": "TODO.txt",
"chars": 285,
"preview": "- search and replace text\n- choose the default vsscript library load path\n- insert formatted data from preview window in"
},
{
"path": "common-src/application_instance_file_guard/application_instance_file_guard.cpp",
"chars": 2576,
"preview": "#include \"application_instance_file_guard.h\"\n\n#include <QObject>\n#include <QStandardPaths>\n\n#ifndef Q_OS_WIN\n\t#include <"
},
{
"path": "common-src/application_instance_file_guard/application_instance_file_guard.h",
"chars": 545,
"preview": "#ifndef APPLICATION_INSTANCE_FILE_GUARD_H_INCLUDED\n#define APPLICATION_INSTANCE_FILE_GUARD_H_INCLUDED\n\n#include <QString"
},
{
"path": "common-src/chrono.h",
"chars": 446,
"preview": "#ifndef CHRONO_H_INCLUDED\n#define CHRONO_H_INCLUDED\n\n#include <chrono>\n\ntypedef std::chrono::high_resolution_clock::time"
},
{
"path": "common-src/frame_header_writers/frame_header_writer.cpp",
"chars": 1225,
"preview": "#include \"frame_header_writer.h\"\n\n//==============================================================================\n\nFram"
},
{
"path": "common-src/frame_header_writers/frame_header_writer.h",
"chars": 928,
"preview": "#ifndef FRAME_HEADER_WRITER_H_INCLUDED\n#define FRAME_HEADER_WRITER_H_INCLUDED\n\n#include <VapourSynth4.h>\n\n#include <QObj"
},
{
"path": "common-src/frame_header_writers/frame_header_writer_null.cpp",
"chars": 2260,
"preview": "#include \"frame_header_writer_null.h\"\n\n//==============================================================================\n"
},
{
"path": "common-src/frame_header_writers/frame_header_writer_null.h",
"chars": 764,
"preview": "#ifndef FRAME_HEADER_WRITER_NULL_H_INCLUDED\n#define FRAME_HEADER_WRITER_NULL_H_INCLUDED\n\n#include \"frame_header_writer.h"
},
{
"path": "common-src/frame_header_writers/frame_header_writer_y4m.cpp",
"chars": 4579,
"preview": "#include \"frame_header_writer_y4m.h\"\n\n#include \"../../../common-src/helpers.h\"\n\n#include <string>\n#include <map>\n\n//===="
},
{
"path": "common-src/frame_header_writers/frame_header_writer_y4m.h",
"chars": 759,
"preview": "#ifndef FRAME_HEADER_WRITER_Y4M_H_INCLUDED\n#define FRAME_HEADER_WRITER_Y4M_H_INCLUDED\n\n#include \"frame_header_writer.h\"\n"
},
{
"path": "common-src/helpers.cpp",
"chars": 14075,
"preview": "#include \"helpers.h\"\n\n#include <QDir>\n#include <QFileInfo>\n#include <QCoreApplication>\n#include <cmath>\n#include <functi"
},
{
"path": "common-src/helpers.h",
"chars": 3141,
"preview": "#ifndef HELPERS_H_INCLUDED\n#define HELPERS_H_INCLUDED\n\n#include <VapourSynth4.h>\n\n#include \"helpers_vs.h\"\n\n#include <QSt"
},
{
"path": "common-src/helpers_vs.h",
"chars": 3292,
"preview": "#ifndef HELPERS_VS_H_INCLUDED\n#define HELPERS_VS_H_INCLUDED\n\n#include <VapourSynth4.h>\n#include <VSHelper4.h>\n\n#include "
},
{
"path": "common-src/ipc_defines.h",
"chars": 2050,
"preview": "#ifndef IPC_DEFINES_H_INCLUDED\n#define IPC_DEFINES_H_INCLUDED\n\n// Watcher <-> Job server communication\n\nstatic const cha"
},
{
"path": "common-src/jobs/job.cpp",
"chars": 46225,
"preview": "#include \"job.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/settings/settings_manager_core."
},
{
"path": "common-src/jobs/job.h",
"chars": 5278,
"preview": "#ifndef JOB_H_INCLUDED\n#define JOB_H_INCLUDED\n\n#include \"../../../common-src/settings/settings_definitions_core.h\"\n#incl"
},
{
"path": "common-src/jobs/job_variables.cpp",
"chars": 2782,
"preview": "#include \"job_variables.h\"\n\n#include <QObject>\n\n//======================================================================"
},
{
"path": "common-src/jobs/job_variables.h",
"chars": 779,
"preview": "#ifndef JOB_VARIABLES_H_INCLUDED\n#define JOB_VARIABLES_H_INCLUDED\n\n#include \"../helpers.h\"\n\n#include <functional>\n#inclu"
},
{
"path": "common-src/libp2p/COPYING",
"chars": 484,
"preview": " DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n Version 2, December 2004\n\n Copyright (C) 200"
},
{
"path": "common-src/libp2p/README.md",
"chars": 1040,
"preview": "# libp2p\nPack/unpack pixels.\n\nThe \"p2p\" library implements conversion between packed and planar image\nformats. A packed "
},
{
"path": "common-src/libp2p/p2p.h",
"chars": 24100,
"preview": "#ifndef P2P_H_\n#define P2P_H_\n\n#include <cstddef>\n#include <cstdint>\n#include <climits>\n#include <type_traits>\n#ifdef P2"
},
{
"path": "common-src/libp2p/p2p_api.cpp",
"chars": 6784,
"preview": "#include <algorithm>\n#include <cassert>\n#include <cstring>\n#include \"p2p.h\"\n#include \"p2p_api.h\"\n\n#ifdef P2P_USER_NAMESP"
},
{
"path": "common-src/libp2p/p2p_api.h",
"chars": 4931,
"preview": "#ifndef P2P_API_H_\n#define P2P_API_H_\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Notation: [Xa"
},
{
"path": "common-src/libp2p/simd/cpuinfo_x86.cpp",
"chars": 10182,
"preview": "#ifdef P2P_SIMD\n#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)\n\n#if 0\n #include <s"
},
{
"path": "common-src/libp2p/simd/cpuinfo_x86.h",
"chars": 1957,
"preview": "#pragma once\n\n#ifndef P2P_CPUINFO_X86_H_\n#define P2P_CPUINFO_X86_H_\n\n#ifdef P2P_SIMD\n#if defined(__x86_64__) || defined("
},
{
"path": "common-src/libp2p/simd/p2p_simd.cpp",
"chars": 2163,
"preview": "#ifdef P2P_SIMD\n\n#include <array>\n#include <typeinfo>\n#include <tuple>\n#include <utility>\n#include \"../p2p.h\"\n#include \""
},
{
"path": "common-src/libp2p/simd/p2p_simd.h",
"chars": 841,
"preview": "#pragma once\n\n#ifndef P2P_SIMD_H_\n#define P2P_SIMD_H_\n\n#ifdef P2P_SIMD\n\n#include \"../p2p.h\"\n\nnamespace P2P_NAMESPACE {\nn"
},
{
"path": "common-src/libp2p/simd/p2p_sse41.cpp",
"chars": 7508,
"preview": "#ifdef P2P_SIMD\n#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)\n\n#include <cstdint>\n"
},
{
"path": "common-src/libp2p/v210.cpp",
"chars": 6555,
"preview": "#include \"p2p.h\"\n\nnamespace P2P_NAMESPACE {\n\nnamespace {\n\ntemplate <class Endian>\nvoid unpack_v210(const void *src, void"
},
{
"path": "common-src/log/log_styles_model.cpp",
"chars": 5899,
"preview": "#include \"log_styles_model.h\"\n\n//==============================================================================\n\nLogStyl"
},
{
"path": "common-src/log/log_styles_model.h",
"chars": 1552,
"preview": "#ifndef LOG_STYLES_MODEL_H_INCLUDED\n#define LOG_STYLES_MODEL_H_INCLUDED\n\n#include \"styled_log_view_structures.h\"\n\n#inclu"
},
{
"path": "common-src/log/styled_log_view.cpp",
"chars": 14687,
"preview": "#include \"styled_log_view.h\"\n\n#include \"styled_log_view_settings_dialog.h\"\n\n#include <QMenu>\n#include <QScrollBar>\n#incl"
},
{
"path": "common-src/log/styled_log_view.h",
"chars": 1849,
"preview": "#ifndef STYLED_LOG_VIEW_H_INCLUDED\n#define STYLED_LOG_VIEW_H_INCLUDED\n\n#include \"styled_log_view_structures.h\"\n\n#include"
},
{
"path": "common-src/log/styled_log_view_core.cpp",
"chars": 2378,
"preview": "#include \"styled_log_view_core.h\"\n\n#include <QVariant>\n\n//=============================================================="
},
{
"path": "common-src/log/styled_log_view_core.h",
"chars": 1049,
"preview": "#ifndef STYLED_LOG_VIEW_CORE_H_INCLUDED\n#define STYLED_LOG_VIEW_CORE_H_INCLUDED\n\n#include <QString>\n#include <QDateTime>"
},
{
"path": "common-src/log/styled_log_view_settings_dialog.cpp",
"chars": 6336,
"preview": "#include \"styled_log_view_settings_dialog.h\"\n\n#include \"log_styles_model.h\"\n\n#include <QGuiApplication>\n#include <QFontD"
},
{
"path": "common-src/log/styled_log_view_settings_dialog.h",
"chars": 1043,
"preview": "#ifndef STYLED_LOG_VIEW_SETTINGS_DIALOG_H_INCLUDED\n#define STYLED_LOG_VIEW_SETTINGS_DIALOG_H_INCLUDED\n\n#include <ui_styl"
},
{
"path": "common-src/log/styled_log_view_settings_dialog.ui",
"chars": 3416,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>StyledLogViewSettingsDialog</class>\n <widget class=\"QD"
},
{
"path": "common-src/log/styled_log_view_structures.cpp",
"chars": 2152,
"preview": "#include \"styled_log_view_structures.h\"\n\n#include <QGuiApplication>\n#include <QPalette>\n\n//============================="
},
{
"path": "common-src/log/styled_log_view_structures.h",
"chars": 995,
"preview": "#ifndef STYLED_LOG_VIEW_STRUCTURES_H_INCLUDED\n#define STYLED_LOG_VIEW_STRUCTURES_H_INCLUDED\n\n#include \"styled_log_view_c"
},
{
"path": "common-src/log/vs_editor_log.cpp",
"chars": 3742,
"preview": "#include \"vs_editor_log.h\"\n\n#include \"../settings/settings_manager.h\"\n\n//==============================================="
},
{
"path": "common-src/log/vs_editor_log.h",
"chars": 719,
"preview": "#ifndef VS_EDITOR_LOG_H_INCLUDED\n#define VS_EDITOR_LOG_H_INCLUDED\n\n#include \"styled_log_view.h\"\n#include \"vs_editor_log_"
},
{
"path": "common-src/log/vs_editor_log_definitions.cpp",
"chars": 1580,
"preview": "#include \"vs_editor_log_definitions.h\"\n\n#include \"styled_log_view_core.h\"\n\n#include <VapourSynth4.h>\n#include <map>\n#inc"
},
{
"path": "common-src/log/vs_editor_log_definitions.h",
"chars": 776,
"preview": "#ifndef VS_EDITOR_LOG_DEFINITIONS_H_INCLUDED\n#define VS_EDITOR_LOG_DEFINITIONS_H_INCLUDED\n\n#include <QString>\n\nextern co"
},
{
"path": "common-src/settings/settings_definitions.cpp",
"chars": 9163,
"preview": "#include \"settings_definitions.h\"\n\n//==============================================================================\n\ncon"
},
{
"path": "common-src/settings/settings_definitions.h",
"chars": 8026,
"preview": "#ifndef SETTINGS_DEFINITIONS_H_INCLUDED\n#define SETTINGS_DEFINITIONS_H_INCLUDED\n\n#include \"../timeline_slider/timeline_s"
},
{
"path": "common-src/settings/settings_definitions_core.cpp",
"chars": 8494,
"preview": "#include \"settings_definitions_core.h\"\n\n#include <QObject>\n#include <QJsonArray>\n#include <QVariant>\n#include <map>\n\n//="
},
{
"path": "common-src/settings/settings_definitions_core.h",
"chars": 4012,
"preview": "#ifndef SETTINGS_DEFINITIONS_CORE_H_INCLUDED\n#define SETTINGS_DEFINITIONS_CORE_H_INCLUDED\n\n#include <QString>\n#include <"
},
{
"path": "common-src/settings/settings_manager.cpp",
"chars": 40857,
"preview": "#include \"settings_manager.h\"\n\n#include \"../helpers.h\"\n\n#include <QSettings>\n#include <QFileInfo>\n#include <QPalette>\n#i"
},
{
"path": "common-src/settings/settings_manager.h",
"chars": 6606,
"preview": "#ifndef SETTINGSMANAGER_H\n#define SETTINGSMANAGER_H\n\n#include \"settings_manager_core.h\"\n#include \"settings_definitions.h"
},
{
"path": "common-src/settings/settings_manager_core.cpp",
"chars": 18398,
"preview": "#include \"settings_manager_core.h\"\n\n#include <QCoreApplication>\n#include <QFile>\n#include <QFileInfo>\n#include <QStandar"
},
{
"path": "common-src/settings/settings_manager_core.h",
"chars": 2619,
"preview": "#ifndef SETTINGS_MANAGER_CORE_H_INCLUDED\n#define SETTINGS_MANAGER_CORE_H_INCLUDED\n\n#include \"settings_definitions_core.h"
},
{
"path": "common-src/timeline_slider/timeline_slider.cpp",
"chars": 21555,
"preview": "#include \"timeline_slider.h\"\n\n#include \"../helpers.h\"\n\n#include <QKeyEvent>\n#include <QMouseEvent>\n#include <QPaintEvent"
},
{
"path": "common-src/timeline_slider/timeline_slider.h",
"chars": 2865,
"preview": "#ifndef TIMELINESLIDER_H\n#define TIMELINESLIDER_H\n\n#include <QWidget>\n#include <set>\n\nclass QKeyEvent;\nclass QMouseEvent"
},
{
"path": "common-src/vapoursynth/vapoursynth_script_processor.cpp",
"chars": 31803,
"preview": "#include \"vapoursynth_script_processor.h\"\n\n#include \"../helpers.h\"\n#include \"vs_script_library.h\"\n#include \"vs_pack_rgb."
},
{
"path": "common-src/vapoursynth/vapoursynth_script_processor.h",
"chars": 3169,
"preview": "#ifndef VAPOURSYNTHSCRIPTPROCESSOR_H\n#define VAPOURSYNTHSCRIPTPROCESSOR_H\n\n#include \"vs_script_processor_structures.h\"\n#"
},
{
"path": "common-src/vapoursynth/vs_pack_rgb.cpp",
"chars": 2965,
"preview": "#include \"vs_pack_rgb.h\"\n#include \"../libp2p/p2p_api.h\"\n\n#include <VSHelper4.h>\n\n#include <vector>\n\nstruct PackData\n{\n "
},
{
"path": "common-src/vapoursynth/vs_pack_rgb.h",
"chars": 207,
"preview": "#ifndef VS_PACK_RGB_H_INCLUDED\n#define VS_PACK_RGB_H_INCLUDED\n\n#include <VapourSynth4.h>\n\nVSNode *packRGBFilter(VSNode *"
},
{
"path": "common-src/vapoursynth/vs_script_library.cpp",
"chars": 13122,
"preview": "#include \"vs_script_library.h\"\n\n#include \"../settings/settings_manager_core.h\"\n#include \"../helpers.h\"\n\n#include <QSetti"
},
{
"path": "common-src/vapoursynth/vs_script_library.h",
"chars": 2439,
"preview": "#ifndef VS_SCRIPT_LIBRARY_H_INCLUDED\n#define VS_SCRIPT_LIBRARY_H_INCLUDED\n\n#include \"../version_info.h\"\n#include <VSScri"
},
{
"path": "common-src/vapoursynth/vs_script_processor_structures.cpp",
"chars": 2146,
"preview": "#include \"vs_script_processor_structures.h\"\n\n//========================================================================="
},
{
"path": "common-src/vapoursynth/vs_script_processor_structures.h",
"chars": 1399,
"preview": "#ifndef VS_SCRIPT_PROCESSOR_STRUCTURES_H_INCLUDED\n#define VS_SCRIPT_PROCESSOR_STRUCTURES_H_INCLUDED\n\n#include <VapourSyn"
},
{
"path": "common-src/vapoursynth/vs_set_matrix.cpp",
"chars": 2559,
"preview": "#include \"vs_set_matrix.h\"\n\n#include <VSHelper4.h>\n#include <VSConstants4.h>\n\n#include <memory>\n#include <cstring>\n\nstru"
},
{
"path": "common-src/vapoursynth/vs_set_matrix.h",
"chars": 193,
"preview": "#ifndef VS_SET_MATRIX_H_INCLUDED\n#define VS_SET_MATRIX_H_INCLUDED\n\n#include <VapourSynth4.h>\n\nvoid VS_CC setMatrixFilter"
},
{
"path": "common-src/version_info.cpp",
"chars": 382,
"preview": "#include \"version_info.h\"\n\n#include <iostream>\n\nvoid print_version()\n{\n\tstd::cerr << \"VapourSynth Editor \" << VSE_VERSIO"
},
{
"path": "common-src/version_info.h",
"chars": 391,
"preview": "#ifndef VERSION_INFO_H_INCLUDED\n#define VERSION_INFO_H_INCLUDED\n\n#define VSE_VERSION_STR \"R19-mod-6.10\"\n\n#define VS_USE_"
},
{
"path": "common-src/win32_console.cpp",
"chars": 1520,
"preview": "#pragma comment (lib, \"kernel32.lib\")\n#pragma comment (lib, \"user32.lib\")\n#if defined(_WIN32)\n\n#include \"win32_console.h"
},
{
"path": "common-src/win32_console.h",
"chars": 404,
"preview": "#ifndef WIN32_CONSOLE_H_INCLUDED\n#define WIN32_CONSOLE_H_INCLUDED\n\n#if defined(_WIN32)\n#define NOMINMAX\n#define WIN32_LE"
},
{
"path": "msvc/VapourSynthEditor.sln",
"chars": 5202,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.9.3472"
},
{
"path": "msvc/VapourSynthEditor.vcxproj",
"chars": 6487,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msb"
},
{
"path": "msvc/VapourSynthEditor.vcxproj.filters",
"chars": 837,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/libp2p/libp2p.vcxproj",
"chars": 7086,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msb"
},
{
"path": "msvc/libp2p/libp2p.vcxproj.filters",
"chars": 1952,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/vsedit/resource.h",
"chars": 433,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by vsedit.rc\n//\n#define IDI_ICON1 "
},
{
"path": "msvc/vsedit/vsedit.vcxproj",
"chars": 14535,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"17.0\" xmlns=\"http://schemas.micros"
},
{
"path": "msvc/vsedit/vsedit.vcxproj.filters",
"chars": 15877,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/vsedit-encode/resource.h",
"chars": 433,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by vsedit.rc\n//\n#define IDI_ICON1 "
},
{
"path": "msvc/vsedit-encode/vsedit-encode.vcxproj",
"chars": 11092,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"17.0\" xmlns=\"http://schemas.micros"
},
{
"path": "msvc/vsedit-encode/vsedit-encode.vcxproj.filters",
"chars": 9704,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/vsedit-job-server/resource.h",
"chars": 433,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by vsedit.rc\n//\n#define IDI_ICON1 "
},
{
"path": "msvc/vsedit-job-server/vsedit-job-server.vcxproj",
"chars": 9055,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"17.0\" xmlns=\"http://schemas.micros"
},
{
"path": "msvc/vsedit-job-server/vsedit-job-server.vcxproj.filters",
"chars": 6909,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/vsedit-job-server-watcher/resource.h",
"chars": 433,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by vsedit.rc\n//\n#define IDI_ICON1 "
},
{
"path": "msvc/vsedit-job-server-watcher/vsedit-job-server-watcher.vcxproj",
"chars": 11836,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"17.0\" xmlns=\"http://schemas.micros"
},
{
"path": "msvc/vsedit-job-server-watcher/vsedit-job-server-watcher.vcxproj.filters",
"chars": 11270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "msvc/vsedit-previewer/resource.h",
"chars": 433,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by vsedit.rc\n//\n#define IDI_ICON1 "
},
{
"path": "msvc/vsedit-previewer/vsedit-previewer.vcxproj",
"chars": 10691,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"17.0\" xmlns=\"http://schemas.micros"
},
{
"path": "msvc/vsedit-previewer/vsedit-previewer.vcxproj.filters",
"chars": 9573,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "pro/build-inno-setup.iss",
"chars": 4076,
"preview": "; https://jrsoftware.org/ishelp/index.php\n\n#define AppName \"VapourSynth Editor\"\n#define ExeName \"vsedit\"\n#define Version"
},
{
"path": "pro/build-msvc.bat",
"chars": 1032,
"preview": "@ECHO THIS SCRIPT IS OUTDATED AND NO MORE MAINTAINED. USE IT AS A REFERENCE ONLY.\n@SET BRANCH=%1\n@IF \"%BRANCH%\"==\"\" (\nSE"
},
{
"path": "pro/common.pri",
"chars": 140,
"preview": "VER_MAJ = 19\nVERSION = $$VER_MAJ\n\nQMAKE_TARGET_COMPANY = 'Aleksey [Mystery Keeper] Lyashin'\nQMAKE_TARGET_COPYRIGHT = $$Q"
},
{
"path": "pro/pro.pro",
"chars": 546,
"preview": "lessThan(QT_MAJOR_VERSION, 6) {\n\terror(You must build with Qt 6 or later)\n}\n\nTEMPLATE = subdirs\n\nSUBDIRS += vsedit\nSUBDI"
},
{
"path": "pro/vsedit/vsedit.pro",
"chars": 14350,
"preview": "CONFIG += qt\n\nQT += widgets\nQT += network\n\nwin32 {\n\tQT += multimedia\n}\n\n\nHOST_64_BIT = contains(QMAKE_HOST.arch, \"x86_64"
},
{
"path": "pro/vsedit-encode/vsedit-encode.pro",
"chars": 11209,
"preview": "CONFIG += qt\n\nQT += widgets\n\nwin32 {\n\tCONFIG += console\n}\n\nHOST_64_BIT = contains(QMAKE_HOST.arch, \"x86_64\")\nTARGET_64_B"
},
{
"path": "pro/vsedit-job-server/vsedit-job-server.pro",
"chars": 8462,
"preview": "CONFIG += qt\n\nQT += websockets\nQT += widgets\n\nwin32 {\n\tCONFIG += console\n}\n\nHOST_64_BIT = contains(QMAKE_HOST.arch, \"x86"
},
{
"path": "pro/vsedit-job-server-watcher/vsedit-job-server-watcher.pro",
"chars": 9954,
"preview": "CONFIG += qt\n\nQT += widgets\nQT += websockets\n\nHOST_64_BIT = contains(QMAKE_HOST.arch, \"x86_64\")\nTARGET_64_BIT = contains"
},
{
"path": "pro/vsedit-previewer/vsedit-previewer.pro",
"chars": 10785,
"preview": "CONFIG += qt\n\nQT += widgets\n\nwin32 {\n\tQT += multimedia\n\tCONFIG += console\n}\n\nHOST_64_BIT = contains(QMAKE_HOST.arch, \"x8"
},
{
"path": "resources/dark/LICENSE.rst",
"chars": 19135,
"preview": "License\n=======\n\nThe MIT License (MIT) - Code\n----------------------------\n\nCopyright (c) 2013-2019 Colin Duquesnoy\n\nPer"
},
{
"path": "resources/dark/rc/.keep",
"chars": 2,
"preview": " \n"
},
{
"path": "resources/dark/style.qrc",
"chars": 9965,
"preview": "\n<RCC warning=\"WARNING! File created programmatically. All changes made in this file will be lost!\">\n <qresource prefix"
},
{
"path": "resources/dark/style.qss",
"chars": 53479,
"preview": "/* Modified for VapourSynth Editor */\n\n/* ---------------------------------------------------------------------------\n\n "
},
{
"path": "resources/vsedit-job-server-watcher.qrc",
"chars": 496,
"preview": "<!DOCTYPE RCC><RCC version=\"1.0\">\n\t<qresource>\n\t\t<file alias=\"watcher.ico\">vsedit-job-server-watcher.ico</file>\n\t\t<file "
},
{
"path": "resources/vsedit.qrc",
"chars": 2418,
"preview": "<!DOCTYPE RCC><RCC version=\"1.0\">\n\t<qresource>\n\t\t<file alias=\"new.png\">page_white_text.png</file>\n\t\t<file alias=\"save.pn"
},
{
"path": "vsedit/src/frame_consumers/benchmark_dialog.cpp",
"chars": 8858,
"preview": "#include \"benchmark_dialog.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/vapoursynth/vapour"
},
{
"path": "vsedit/src/frame_consumers/benchmark_dialog.h",
"chars": 1535,
"preview": "#ifndef BENCHMARK_DIALOG_H_INCLUDED\n#define BENCHMARK_DIALOG_H_INCLUDED\n\n#include <ui_benchmark_dialog.h>\n\n#include \"../"
},
{
"path": "vsedit/src/frame_consumers/benchmark_dialog.ui",
"chars": 3261,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ScriptBenchmarkDialog</class>\n <widget class=\"QDialog\""
},
{
"path": "vsedit/src/frame_consumers/encode_dialog.cpp",
"chars": 15776,
"preview": "#include \"encode_dialog.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/settings/settings_man"
},
{
"path": "vsedit/src/frame_consumers/encode_dialog.h",
"chars": 1551,
"preview": "#ifndef ENCODE_DIALOG_H_INCLUDED\n#define ENCODE_DIALOG_H_INCLUDED\n\n#include <ui_encode_dialog.h>\n\n#include \"../../../com"
},
{
"path": "vsedit/src/frame_consumers/encode_dialog.ui",
"chars": 7421,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>EncodeDialog</class>\n <widget class=\"QDialog\" name=\"En"
},
{
"path": "vsedit/src/job_server_watcher_socket.cpp",
"chars": 2784,
"preview": "#include \"job_server_watcher_socket.h\"\n\n#include \"../../common-src/helpers.h\"\n#include \"../../common-src/ipc_defines.h\"\n"
},
{
"path": "vsedit/src/job_server_watcher_socket.h",
"chars": 563,
"preview": "#ifndef JOB_SERVER_WATCHER_SOCKET_H_INCLUDED\n#define JOB_SERVER_WATCHER_SOCKET_H_INCLUDED\n\n#include <QLocalSocket>\n\nclas"
},
{
"path": "vsedit/src/main.cpp",
"chars": 3076,
"preview": "#include \"main_window.h\"\n\n#include \"../../common-src/log/vs_editor_log.h\"\n#include \"../../common-src/settings/settings_m"
},
{
"path": "vsedit/src/main_window.cpp",
"chars": 30340,
"preview": "#include \"main_window.h\"\n\n#include \"../../common-src/settings/settings_manager.h\"\n#include \"../../common-src/vapoursynth"
},
{
"path": "vsedit/src/main_window.h",
"chars": 3217,
"preview": "#ifndef MAINWINDOW_H\n#define MAINWINDOW_H\n\n#include <ui_main_window.h>\n\n#include <vector>\n#include <mutex>\n\nclass Settin"
},
{
"path": "vsedit/src/main_window.ui",
"chars": 2808,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\""
},
{
"path": "vsedit/src/preview/preview_advanced_settings_dialog.cpp",
"chars": 9973,
"preview": "#include \"preview_advanced_settings_dialog.h\"\n\n#include \"../../../common-src/settings/settings_manager.h\"\n#include \"../."
},
{
"path": "vsedit/src/preview/preview_advanced_settings_dialog.h",
"chars": 824,
"preview": "#ifndef PREVIEW_ADVANCED_SETTINGS_DIALOG_H_INCLUDED\n#define PREVIEW_ADVANCED_SETTINGS_DIALOG_H_INCLUDED\n\n#include <ui_pr"
},
{
"path": "vsedit/src/preview/preview_advanced_settings_dialog.ui",
"chars": 6191,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>PreviewAdvancedSettingsDialog</class>\n <widget class=\""
},
{
"path": "vsedit/src/preview/preview_area.cpp",
"chars": 8204,
"preview": "#include \"preview_area.h\"\n\n#include \"scroll_navigator.h\"\n\n#include <QLabel>\n#include <QKeyEvent>\n#include <QWheelEvent>\n"
},
{
"path": "vsedit/src/preview/preview_area.h",
"chars": 1879,
"preview": "#ifndef PREVIEWAREA_H\n#define PREVIEWAREA_H\n\n#include <QScrollArea>\n#include <QPixmap>\n#include <QPoint>\n\nclass QLabel;\n"
},
{
"path": "vsedit/src/preview/preview_dialog.cpp",
"chars": 102219,
"preview": "#include \"preview_dialog.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/libp2p/p2p_api.h\"\n#i"
},
{
"path": "vsedit/src/preview/preview_dialog.h",
"chars": 10379,
"preview": "#ifndef PREVIEWDIALOG_H_INCLUDED\n#define PREVIEWDIALOG_H_INCLUDED\n\n#include <ui_preview_dialog.h>\n\n#include \"../vapoursy"
},
{
"path": "vsedit/src/preview/preview_dialog.ui",
"chars": 20203,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>PreviewDialog</class>\n <widget class=\"QDialog\" name=\"P"
},
{
"path": "vsedit/src/preview/scroll_navigator.cpp",
"chars": 3453,
"preview": "#include \"scroll_navigator.h\"\n\n#include <QPaintEvent>\n#include <QPainter>\n#include <QColor>\n\n//========================="
},
{
"path": "vsedit/src/preview/scroll_navigator.h",
"chars": 589,
"preview": "#ifndef SCROLLNAVIGATOR_H\n#define SCROLLNAVIGATOR_H\n\n#include <QWidget>\n\nclass QPaintEvent;\n\nclass ScrollNavigator : pub"
},
{
"path": "vsedit/src/preview/zoom_ratio_spinbox.cpp",
"chars": 1939,
"preview": "#include \"zoom_ratio_spinbox.h\"\n\n#include <cmath>\n\nZoomRatioSpinBox::ZoomRatioSpinBox(QWidget * a_pWidget): \n\tQDoubleSpi"
},
{
"path": "vsedit/src/preview/zoom_ratio_spinbox.h",
"chars": 469,
"preview": "#ifndef ZOOM_RATIO_SPINBOX_H_INCLUDED\n#define ZOOM_RATIO_SPINBOX_H_INCLUDED\n\n#include \"../../../common-src/settings/sett"
},
{
"path": "vsedit/src/script_editor/number_matcher.cpp",
"chars": 5037,
"preview": "#include \"number_matcher.h\"\n\n//==============================================================================\n\nNumberMat"
},
{
"path": "vsedit/src/script_editor/number_matcher.h",
"chars": 771,
"preview": "#ifndef NUMBERMATCHER_H_INCLUDED\n#define NUMBERMATCHER_H_INCLUDED\n\n#include <QString>\n\n/// Finite state machine Python n"
},
{
"path": "vsedit/src/script_editor/script_completer.cpp",
"chars": 1092,
"preview": "#include \"script_completer.h\"\n\n//==============================================================================\n\nScriptC"
},
{
"path": "vsedit/src/script_editor/script_completer.h",
"chars": 399,
"preview": "#ifndef SCRIPTCOMPLETER_H\n#define SCRIPTCOMPLETER_H\n\n#include <QCompleter>\n\nclass ScriptCompleter : public QCompleter\n{\n"
},
{
"path": "vsedit/src/script_editor/script_completer_model.cpp",
"chars": 2288,
"preview": "#include \"script_completer_model.h\"\n\n#include <algorithm>\n\n//==========================================================="
},
{
"path": "vsedit/src/script_editor/script_completer_model.h",
"chars": 449,
"preview": "#ifndef SCRIPTCOMPLETERMODEL_H\n#define SCRIPTCOMPLETERMODEL_H\n\n#include \"../vapoursynth/vs_plugin_data.h\"\n\n#include <QSt"
},
{
"path": "vsedit/src/script_editor/script_editor.cpp",
"chars": 36183,
"preview": "#include \"script_editor.h\"\n\n#include \"script_completer_model.h\"\n#include \"script_completer.h\"\n#include \"syntax_highlight"
},
{
"path": "vsedit/src/script_editor/script_editor.h",
"chars": 3741,
"preview": "#ifndef SCRIPTEDITOR_H\n#define SCRIPTEDITOR_H\n\n#include \"../../../common-src/helpers.h\"\n#include \"../vapoursynth/vs_plug"
},
{
"path": "vsedit/src/script_editor/syntax_highlighter.cpp",
"chars": 13297,
"preview": "#include \"syntax_highlighter.h\"\n\n#include \"number_matcher.h\"\n#include \"../../../common-src/settings/settings_manager.h\"\n"
},
{
"path": "vsedit/src/script_editor/syntax_highlighter.h",
"chars": 1187,
"preview": "#ifndef SYNTAXHIGHLIGHTER_H\n#define SYNTAXHIGHLIGHTER_H\n\n#include \"../vapoursynth/vs_plugin_data.h\"\n\n#include <QSyntaxHi"
},
{
"path": "vsedit/src/script_status_bar_widget/script_status_bar_widget.cpp",
"chars": 3103,
"preview": "#include \"script_status_bar_widget.h\"\n\n#include \"../../../common-src/helpers.h\"\n\n#include <QLocale>\n\n//================="
},
{
"path": "vsedit/src/script_status_bar_widget/script_status_bar_widget.h",
"chars": 880,
"preview": "#ifndef SCRIPT_STATUS_BAR_WIDGET_H_INCLUDED\n#define SCRIPT_STATUS_BAR_WIDGET_H_INCLUDED\n\n#include <ui_script_status_bar_"
},
{
"path": "vsedit/src/script_status_bar_widget/script_status_bar_widget.ui",
"chars": 3950,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ScriptStatusBarWidget</class>\n <widget class=\"QWidget\""
},
{
"path": "vsedit/src/script_templates/drop_file_category_model.cpp",
"chars": 7590,
"preview": "#include \"drop_file_category_model.h\"\n\n#include <QRegularExpression>\n#include <QSet>\n\n//================================"
},
{
"path": "vsedit/src/script_templates/drop_file_category_model.h",
"chars": 1539,
"preview": "#ifndef DROP_FILE_CATEGORY_MODEL_H_INCLUDED\n#define DROP_FILE_CATEGORY_MODEL_H_INCLUDED\n\n#include \"../../../common-src/s"
},
{
"path": "vsedit/src/script_templates/templates_dialog.cpp",
"chars": 13626,
"preview": "#include \"templates_dialog.h\"\n\n#include \"drop_file_category_model.h\"\n#include \"../../../common-src/settings/settings_man"
},
{
"path": "vsedit/src/script_templates/templates_dialog.h",
"chars": 1836,
"preview": "#ifndef TEMPLATES_DIALOG_H_INCLUDED\n#define TEMPLATES_DIALOG_H_INCLUDED\n\n#include <ui_templates_dialog.h>\n\n#include \"../"
},
{
"path": "vsedit/src/script_templates/templates_dialog.ui",
"chars": 9484,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>TemplatesDialog</class>\n <widget class=\"QDialog\" name="
},
{
"path": "vsedit/src/settings/actions_hotkey_edit_model.cpp",
"chars": 4872,
"preview": "#include \"actions_hotkey_edit_model.h\"\n\n//=============================================================================="
},
{
"path": "vsedit/src/settings/actions_hotkey_edit_model.h",
"chars": 1185,
"preview": "#ifndef ACTIONSHOTKEYEDITMODEL_H\n#define ACTIONSHOTKEYEDITMODEL_H\n\n#include \"../../../common-src/settings/settings_manag"
},
{
"path": "vsedit/src/settings/clearable_key_sequence_editor.cpp",
"chars": 1652,
"preview": "#include \"clearable_key_sequence_editor.h\"\n\n#include <QKeySequenceEdit>\n#include <QToolButton>\n#include <QBoxLayout>\n\n//"
},
{
"path": "vsedit/src/settings/clearable_key_sequence_editor.h",
"chars": 649,
"preview": "#ifndef CLEARABLE_KEY_SEQUENCE_EDITOR_H_INCLUDED\n#define CLEARABLE_KEY_SEQUENCE_EDITOR_H_INCLUDED\n\n#include <QWidget>\n#i"
},
{
"path": "vsedit/src/settings/item_delegate_for_hotkey.cpp",
"chars": 2349,
"preview": "#include \"item_delegate_for_hotkey.h\"\n\n#include \"clearable_key_sequence_editor.h\"\n\n//==================================="
},
{
"path": "vsedit/src/settings/item_delegate_for_hotkey.h",
"chars": 834,
"preview": "#ifndef ITEMDELEGATEFORHOTKEY_H\n#define ITEMDELEGATEFORHOTKEY_H\n\n#include <QStyledItemDelegate>\n\nclass ItemDelegateForHo"
},
{
"path": "vsedit/src/settings/settings_dialog.cpp",
"chars": 14491,
"preview": "#include \"settings_dialog.h\"\n\n#include \"../../../common-src/settings/settings_manager.h\"\n#include \"../../../common-src/h"
},
{
"path": "vsedit/src/settings/settings_dialog.h",
"chars": 1035,
"preview": "#ifndef SETTINGSDIALOG_H\n#define SETTINGSDIALOG_H\n\n#include <ui_settings_dialog.h>\n\n#include \"actions_hotkey_edit_model."
},
{
"path": "vsedit/src/settings/settings_dialog.ui",
"chars": 20568,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>SettingsDialog</class>\n <widget class=\"QDialog\" name=\""
},
{
"path": "vsedit/src/settings/theme_elements_model.cpp",
"chars": 7383,
"preview": "#include \"theme_elements_model.h\"\n\n#include \"../../../common-src/settings/settings_manager.h\"\n\n//======================="
},
{
"path": "vsedit/src/settings/theme_elements_model.h",
"chars": 1853,
"preview": "#ifndef THEME_ELEMENTS_MODEL_H_INCLUDED\n#define THEME_ELEMENTS_MODEL_H_INCLUDED\n\n#include \"../../../common-src/settings/"
},
{
"path": "vsedit/src/vapoursynth/vapoursynth_plugins_manager.cpp",
"chars": 5681,
"preview": "#include \"vapoursynth_plugins_manager.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/setting"
},
{
"path": "vsedit/src/vapoursynth/vapoursynth_plugins_manager.h",
"chars": 1058,
"preview": "#ifndef VAPOURSYNTHPLUGINSMANAGER_H\n#define VAPOURSYNTHPLUGINSMANAGER_H\n\n#include \"vs_plugin_data.h\"\n\n#include <VapourSy"
},
{
"path": "vsedit/src/vapoursynth/vs_plugin_data.cpp",
"chars": 4183,
"preview": "#include \"vs_plugin_data.h\"\n\n#include <QStringList>\n\n//================================================================="
},
{
"path": "vsedit/src/vapoursynth/vs_plugin_data.h",
"chars": 1484,
"preview": "#ifndef VSPLUGINDATA_H_INCLUDED\n#define VSPLUGINDATA_H_INCLUDED\n\n#include <QString>\n#include <vector>\n\n/// Data, gathere"
},
{
"path": "vsedit/src/vapoursynth/vs_script_processor_dialog.cpp",
"chars": 8396,
"preview": "#include \"vs_script_processor_dialog.h\"\n\n#include \"../../../common-src/helpers.h\"\n#include \"../../../common-src/settings"
},
{
"path": "vsedit/src/vapoursynth/vs_script_processor_dialog.h",
"chars": 3107,
"preview": "#ifndef VS_SCRIPT_PROCESSOR_DIALOG_H_INCLUDED\n#define VS_SCRIPT_PROCESSOR_DIALOG_H_INCLUDED\n\n#include \"../../../common-s"
},
{
"path": "vsedit/src/vsedit_encode_main.cpp",
"chars": 6512,
"preview": "#include \"../../common-src/settings/settings_manager.h\"\n#include \"../../common-src/vapoursynth/vs_script_library.h\"\n#inc"
},
{
"path": "vsedit/src/vsedit_previewer_main.cpp",
"chars": 6736,
"preview": "#include \"../../common-src/settings/settings_manager.h\"\n#include \"../../common-src/vapoursynth/vs_script_library.h\"\n#inc"
},
{
"path": "vsedit-job-server/src/job_server.cpp",
"chars": 16215,
"preview": "#include \"job_server.h\"\n\n#include \"../../common-src/ipc_defines.h\"\n#include \"../../common-src/helpers.h\"\n#include \"jobs/"
},
{
"path": "vsedit-job-server/src/job_server.h",
"chars": 2428,
"preview": "#ifndef WEB_SOCKET_JOB_SERVER_H_INCLUDED\n#define WEB_SOCKET_JOB_SERVER_H_INCLUDED\n\n#include \"../../common-src/settings/s"
},
{
"path": "vsedit-job-server/src/jobs/job_definitions.h",
"chars": 263,
"preview": "#ifndef JOB_DEFINITIONS_H_INCLUDED\n#define JOB_DEFINITIONS_H_INCLUDED\n\n#include \"../../../common-src/jobs/job.h\"\n\nenum c"
},
{
"path": "vsedit-job-server/src/jobs/jobs_manager.cpp",
"chars": 14642,
"preview": "#include \"jobs_manager.h\"\n\n#include \"../../../common-src/settings/settings_manager_core.h\"\n#include \"../../../common-src"
},
{
"path": "vsedit-job-server/src/jobs/jobs_manager.h",
"chars": 2828,
"preview": "#ifndef JOBS_MANAGER_H_INCLUDED\n#define JOBS_MANAGER_H_INCLUDED\n\n#include \"../../../common-src/jobs/job.h\"\n#include \"job"
},
{
"path": "vsedit-job-server/src/main.cpp",
"chars": 1218,
"preview": "#include \"job_server.h\"\n\n#include \"../../common-src/application_instance_file_guard/application_instance_file_guard.h\"\n#"
},
{
"path": "vsedit-job-server-watcher/src/connect_to_server_dialog.cpp",
"chars": 1663,
"preview": "#include \"connect_to_server_dialog.h\"\n\n#include \"../../common-src/settings/settings_manager.h\"\n\n#include <QComboBox>\n\nCo"
},
{
"path": "vsedit-job-server-watcher/src/connect_to_server_dialog.h",
"chars": 704,
"preview": "#ifndef CONNECT_TO_SERVER_DIALOG_H_INCLUDED\n#define CONNECT_TO_SERVER_DIALOG_H_INCLUDED\n\n#include <ui_connect_to_server_"
},
{
"path": "vsedit-job-server-watcher/src/connect_to_server_dialog.ui",
"chars": 2421,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ConnectToServerDialog</class>\n <widget class=\"QDialog\""
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_dependencies_delegate.cpp",
"chars": 4380,
"preview": "#include \"job_dependencies_delegate.h\"\n\n#include \"jobs_model.h\"\n\n#include \"../../../common-src/helpers.h\"\n\n#include <QLi"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_dependencies_delegate.h",
"chars": 863,
"preview": "#ifndef JOB_DEPENDENCIES_DELEGATE_H_INCLUDED\n#define JOB_DEPENDENCIES_DELEGATE_H_INCLUDED\n\n#include <QStyledItemDelegate"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_edit_dialog.cpp",
"chars": 14842,
"preview": "#include \"job_edit_dialog.h\"\n\n#include \"../../../common-src/settings/settings_manager.h\"\n#include \"../../../common-src/v"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_edit_dialog.h",
"chars": 1356,
"preview": "#ifndef JOB_EDIT_DIALOG_H_INCLUDED\n#define JOB_EDIT_DIALOG_H_INCLUDED\n\n#include <ui_job_edit_dialog.h>\n\n#include \"../../"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_edit_dialog.ui",
"chars": 12839,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>JobEditDialog</class>\n <widget class=\"QDialog\" name=\"J"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_state_delegate.cpp",
"chars": 2663,
"preview": "#include \"job_state_delegate.h\"\n\n#include \"jobs_model.h\"\n\n#include \"../../../common-src/helpers.h\"\n\n#include <QPainter>\n"
},
{
"path": "vsedit-job-server-watcher/src/jobs/job_state_delegate.h",
"chars": 617,
"preview": "#ifndef JOB_STATE_DELEGATE_H_INCLUDED\n#define JOB_STATE_DELEGATE_H_INCLUDED\n\n#include \"../../../common-src/settings/sett"
},
{
"path": "vsedit-job-server-watcher/src/jobs/jobs_model.cpp",
"chars": 15805,
"preview": "#include \"jobs_model.h\"\n\n#include \"../../../common-src/settings/settings_manager.h\"\n#include \"../../../common-src/helper"
},
{
"path": "vsedit-job-server-watcher/src/jobs/jobs_model.h",
"chars": 3211,
"preview": "#ifndef JOBS_MODEL_H_INCLUDED\n#define JOBS_MODEL_H_INCLUDED\n\n#include \"../../../common-src/settings/settings_definitions"
},
{
"path": "vsedit-job-server-watcher/src/main.cpp",
"chars": 2964,
"preview": "#include \"main_window.h\"\n\n#include \"../../common-src/settings/settings_manager.h\"\n#include \"../../common-src/log/vs_edit"
},
{
"path": "vsedit-job-server-watcher/src/main_window.cpp",
"chars": 43530,
"preview": "#include \"main_window.h\"\n\n#include \"jobs/jobs_model.h\"\n#include \"jobs/job_state_delegate.h\"\n#include \"jobs/job_dependenc"
},
{
"path": "vsedit-job-server-watcher/src/main_window.h",
"chars": 4292,
"preview": "#ifndef MAINWINDOW_H\n#define MAINWINDOW_H\n\n#include <ui_main_window.h>\n\n#include \"../../common-src/settings/settings_def"
},
{
"path": "vsedit-job-server-watcher/src/main_window.ui",
"chars": 7593,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\""
},
{
"path": "vsedit-job-server-watcher/src/trusted_clients_addresses_dialog.cpp",
"chars": 3063,
"preview": "#include \"trusted_clients_addresses_dialog.h\"\n\n#include <QHostAddress>\n\n//=============================================="
},
{
"path": "vsedit-job-server-watcher/src/trusted_clients_addresses_dialog.h",
"chars": 682,
"preview": "#ifndef TRUSTED_CLIENTS_ADDRESSES_DIALOG_H_INCLUDED\n#define TRUSTED_CLIENTS_ADDRESSES_DIALOG_H_INCLUDED\n\n#include <ui_tr"
},
{
"path": "vsedit-job-server-watcher/src/trusted_clients_addresses_dialog.ui",
"chars": 3564,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>TrustedClientsAddressesDialog</class>\n <widget class=\""
}
]
// ... and 6 more files (download for full content)
About this extraction
This page contains the full source code of the YomikoR/VapourSynth-Editor GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 200 files (1.2 MB), approximately 335.9k tokens, and a symbol index with 344 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.