Compare commits

...

431 Commits
0.6.1 ... 0.7.2

Author SHA1 Message Date
Bruno Herbelin
6d835297b2 tag 0.7.2 2022-11-19 23:44:08 +01:00
Bruno Herbelin
b44c29e235 No build in flatpak 2022-11-19 22:25:36 +01:00
Bruno Herbelin
8da9a9cf27 flatpak repo preparation 2022-11-19 22:22:37 +01:00
Bruno Herbelin
a3617626f7 Merge remote-tracking branch 'origin/master' 2022-11-19 20:20:27 +01:00
Bruno Herbelin
e44832ea9e Packaging with flatpak
Successful flatpak-builder process. Not tested further.
2022-11-19 20:20:12 +01:00
Bruno
f841e78dcf Bundle fix (OSX) 2022-10-26 10:01:28 +02:00
Bruno
e7a8d48cca Packaging fix (Cpack OSX) 2022-10-26 09:44:10 +02:00
Bruno
69e8d0e32f Compilation fix (OSX) 2022-10-25 21:38:21 +02:00
Bruno
830d1a6bf9 OSX entitlements to include audio input
Used for gstreamer sources that generates visuals from audio
2022-10-25 00:32:18 +02:00
Bruno Herbelin
e9b72b442a Cleanup source tree
Move all C++ source files in the src subfolder. Adapted the cmake process accordingly and cleanup.
2022-10-25 00:29:22 +02:00
Bruno Herbelin
77ac7eca18 OSC message fror session open, close and save 2022-10-22 10:45:56 +02:00
BHBN
86d4198ffd Merge pull request #54 from felixgonsug/flatpak-build
adding a startpoint to flatpak building
2022-10-20 21:32:26 +02:00
felix
37dfe31ac2 adding a startpoint to flatpak building 2022-10-18 13:34:27 -03:00
Bruno Herbelin
584e1c48e6 oops 2022-10-15 21:40:13 +02:00
Bruno Herbelin
15766ceb97 Prevent bad window manipulation 2022-10-15 19:12:09 +02:00
Bruno Herbelin
6e79f28b69 Prevent Player Inspector conflict with info overlay 2022-10-15 19:11:53 +02:00
Bruno Herbelin
e9632d206b OOps, fixed debug testing 2022-10-15 19:10:55 +02:00
Bruno Herbelin
a0f55bfcb5 Added Fading target for OSC session 2022-10-15 19:06:52 +02:00
Bruno Herbelin
3c32f1da6e Bugfix generation image sequence
Fixed pb with non-power of two height of video, added more informative error messages, fixed UI issue.
2022-10-15 15:19:17 +02:00
Bruno Herbelin
7e13c1b22a Move Group/Ungroup actions to Edit menu 2022-10-15 11:51:16 +02:00
Bruno Herbelin
2fc52e673f Added Color Correction mapping input
Map image processing source callbacks to key inputs.
2022-10-15 00:26:16 +02:00
Bruno Herbelin
48001a660b Source callbacks for Image Processing color correction
Added SourceCallback classes for brightness, contrast, saturation, etc. Added OSC interface to modify color corrections
2022-10-14 19:05:14 +02:00
Bruno Herbelin
5a6daf79b6 Allow Nil Values in OSC messages
Allows providing only one argument value when two (e.g. x and y) are required by specifying the NIL type ('N') in the OSC message. E.g. /vimix/current/position Nf 0.5 sets the Y position.
2022-10-13 17:34:17 +02:00
Bruno Herbelin
ae4fd9f7df Disable Broardast and inform user if SRT not available 2022-10-13 16:24:01 +02:00
Bruno Herbelin
7dfa8776fd Minor improvement Tooltips Settings 2022-09-10 11:24:02 +02:00
Bruno Herbelin
a836796fcc Fix previous 2022-09-08 23:36:13 +02:00
Bruno Herbelin
fb131972d4 Non-blocking deletion of source in SourcePreview
Detach a thread to delete the source currently in SourcePreview in Source new panel; avoids freezing display.
2022-09-08 23:31:27 +02:00
Bruno Herbelin
140ce358fa Added history of recent SRT hosts
Saving known hosts in settings and validating ip and port in SRT connector for source
2022-09-08 20:36:58 +02:00
Bruno Herbelin
dd92f2dccb Improved OSC sync
Accept OSC request to sync source by name or id. Changed OSC seek request to be by percent target
2022-08-17 19:11:21 +02:00
Bruno Herbelin
d62004eadf Update screenshots documentation recording 2022-08-17 18:49:25 +02:00
Bruno Herbelin
abc21e9692 Send source name in Status bundle of all sources 2022-08-09 23:44:22 +02:00
Bruno Herbelin
a13b0d5d91 BugFix Shadertoy ImageFilter 2022-08-08 21:17:16 +02:00
Bruno Herbelin
12f8c75c2d Update screenshots documentation 2022-08-07 11:17:28 +02:00
Bruno Herbelin
bdc1920166 Clone with copy attributes
Two modes of cloning: from the source panel with 'Clone & filter' clones with copy of attributes (geometry, alpha, etc.), from the Insert source panel with 'Internal' source creates a fresh new copy.
2022-08-07 11:13:45 +02:00
Bruno Herbelin
8cb0d57ffe Documenting advances features 2022-08-05 23:22:34 +02:00
Bruno Herbelin
7344689263 Update screenshot Ubuntu snap 2022-08-04 00:23:06 +02:00
Bruno Herbelin
f521ca1118 Fix UI and doc of Share local network 2022-08-04 00:22:38 +02:00
Bruno Herbelin
6712f1383e Fun vimix crow in About dialog 2022-08-02 23:36:09 +02:00
Bruno Herbelin
d756fd4a29 New communication image
Crow drawing done by DALL-E (no human copyright)
2022-08-01 22:22:36 +02:00
Bruno Herbelin
e070ef1b7f adding screenshots documentation SRT 2022-08-01 13:02:05 +02:00
Bruno Herbelin
ea7786a002 Set SRT Latency to 200ms
TODO: make it configurable
2022-08-01 12:39:55 +02:00
Bruno Herbelin
3eec07fac1 BugFix Discoverer for Stream 2022-08-01 11:22:50 +02:00
Bruno Herbelin
46afa76af8 update SRT documentation 2022-07-30 22:09:09 +02:00
Bruno Herbelin
6cc1ba64d8 adding screenshots documentation SRT 2022-07-29 23:26:20 +02:00
Bruno Herbelin
225596481f no architecture snap 2022-07-29 14:44:28 +02:00
Bruno Herbelin
4ef3b3b332 snapping fix 2022-07-29 14:33:52 +02:00
Bruno Herbelin
e7ac768b5b Merge remote-tracking branch 'origin/master' 2022-07-29 00:45:13 +02:00
Bruno Herbelin
b1e8833daa Complement snapcraft info and archittectures 2022-07-29 00:45:07 +02:00
Bruno Herbelin
155d71dc80 Complement snapcraft info and archittectures 2022-07-28 23:27:41 +02:00
Bruno Herbelin
94ebf17134 Add link to Wiki Filters and ShaderToy in Help 2022-07-28 23:11:12 +02:00
Bruno Herbelin
d6fe2edf0d Update and new images for wiki
Preparing documentation for filters a,d group features
2022-07-28 00:00:59 +02:00
Bruno Herbelin
867cd7e583 BugFix test number string 2022-07-27 23:33:36 +02:00
Bruno Herbelin
1a2471a32d Implementation of OSC targets Position, Size, Angle and Seek
Creation of SourceCallback to seek in MediaSource
2022-07-27 17:55:51 +02:00
Bruno Herbelin
057dd9c01d New images for wiki on filters 2022-07-23 23:18:11 +02:00
Bruno Herbelin
5a2c0e15e9 Change Player menu and new Frame inspector
Frame menu is active when a single source is selected. The Frame menu include actions to capture frame and to enable Frame Inspector. Frame inspector zooms on the image at cursor coordinate. Previous Control menu actions are back to main menu.
2022-07-23 22:45:14 +02:00
Bruno Herbelin
ae5ae24f6f BugFix source editor if playable 2022-07-23 12:07:44 +02:00
Bruno Herbelin
7a2f3fe840 BugFix Quit action in menu 2022-07-23 12:07:07 +02:00
Bruno Herbelin
b46788c81a snap 0.7.1 2022-07-21 23:05:20 +02:00
Bruno Herbelin
3c1f37e5f9 BugFix GLSL shader array init 2022-07-21 22:42:32 +02:00
Bruno Herbelin
d8d4322b2e Added option Recorder file naming style
VideoRecorder and PNGRecorder now have setting to decide how to name the files, with date prefix or sequentially numbered.  A base name is given with session filename.
2022-07-20 23:47:22 +02:00
Bruno Herbelin
1613e9ce46 BugFix: session creator restore play status of all types of sources
moved 'play' attribute to source instead of mediaplayer and use source callback to set play state after initialization.
2022-07-19 23:52:51 +02:00
Bruno Herbelin
aee3c8db1b Added ShaderToy support for iMouse to ImageFilter 2022-07-19 22:43:49 +02:00
Bruno Herbelin
becaeedff1 New fun shader vimix logo 2022-07-19 00:09:17 +02:00
Bruno Herbelin
c9c6651368 BugFix load display faster 2022-07-08 22:14:39 +02:00
Bruno Herbelin
d77371912b Changed Group ALL sources action to Group ACTIVE sources
Manage mixing groups and clones on the way. This makes the action more flexible for the user, allowing to group only a selection.
2022-07-06 23:34:36 +02:00
Bruno Herbelin
93cb12be89 BugFix UI Sequence recorder 2022-07-05 23:03:45 +02:00
Bruno Herbelin
4ac2bd8e92 BugFix fisplay Shader Code 2022-07-05 22:18:12 +02:00
Bruno Herbelin
34d52c975e Compilation fix
not needed call of non standard gst call
2022-07-05 22:17:59 +02:00
Bruno Herbelin
85194c7f4f Integration of MultiFileRecorder in UI for sequence creation 2022-07-04 00:07:23 +02:00
Bruno Herbelin
af009e03a0 BugFix New source pannel
Clear status of new source pannel when changing type of input.
2022-07-02 11:34:43 +02:00
Bruno Herbelin
cef7379c07 Initial implementation of MultiFileRecorder
Generate a video from a sequence of images.
2022-07-02 11:34:04 +02:00
Bruno Herbelin
f1e75d8593 BugFix change texture input Stream Sources 2022-06-22 23:48:21 +02:00
Bruno Herbelin
c5a194e98c Frame capture settings and options 2022-06-22 23:01:01 +02:00
Bruno Herbelin
7858033628 Player Frame capture F10
New feature of Player: capture frame (F10 shortcut). Extending the Screenshot class for reading pixels and saving to PNG. Cleaup of screenshot (now associated to F9).
2022-06-22 01:40:47 +02:00
Bruno Herbelin
f2405e02f6 Player display of non-playable source
Show also non-playable sources to allow testing pre- post-display. Show post-processed image only if source made changes.
2022-06-21 01:37:30 +02:00
Bruno Herbelin
452221daa5 User input unified and fixed for clone source
Fixed slider in player, show filtered image when disabled (outside mixing circle), correct timing for clone source (different for filters).
2022-06-20 17:29:12 +02:00
Bruno Herbelin
91f551c2d8 BugFix ShaderEditor 2022-06-19 02:00:32 +02:00
Bruno Herbelin
2ca1763280 Cleanup headers and licenses shaders code 2022-06-18 19:35:52 +02:00
Bruno Herbelin
da4a8333f7 Bugfix and clean code image filters ui, save and load 2022-06-18 18:08:16 +02:00
Bruno Herbelin
c0b08f3219 F11 for screen capture 2022-06-18 17:26:05 +02:00
Bruno Herbelin
c273e9125c F12 for enable/disable output
replacing the 'END' key that is not available on many keyboards.
2022-06-18 11:30:40 +02:00
Bruno Herbelin
7244b95844 Documentation and icons for FrameBuffer filters
unified icons, new entry in help window.
2022-06-18 11:30:11 +02:00
Bruno Herbelin
a298b6587d Added header for GLSL code, GLP3+
Ref to original ShaderToy authors.
2022-06-11 23:35:01 +02:00
Bruno Herbelin
d87f6b74f3 Fixed Shader Editor menu and behavior
Only Clones with ImageFilter of custom type are linked to UI for ShaderEditor. New menu to try presets of shader code. Link to ShaderToy website.
2022-06-10 00:04:56 +02:00
Bruno Herbelin
1f0b145740 Original implementation of Smooth Image filters
Smoothing and noise reduction filters + noise generators.
2022-06-08 23:44:19 +02:00
Bruno Herbelin
f6d528d36d Finalizing implementation of chroma and luma key Transparency filters 2022-06-07 23:49:21 +02:00
Bruno Herbelin
ea6502a282 Removing chromakey and lumakey from standard color correction shader
These effects now should be performed with effect on clone (alpha image processing shaders).
2022-06-07 19:04:52 +02:00
Bruno
8a36a94e73 not all GL Shading compilers accept ## for comments... 2022-06-07 10:45:23 +02:00
Bruno Herbelin
1604eaa239 Original implementation of Alpha Image filters
Chromakey (to finish), lumakey and alpha fill.
2022-06-06 23:33:36 +02:00
Bruno Herbelin
fec2fb7ce6 Original implementation of Resampling Image filters
This involves also resizing the renderbuffer of the clone source. Upsampling is cubic (faster approximation) and Downsampling is bilinear.
2022-06-05 23:43:23 +02:00
Bruno Herbelin
d2e3b854aa Put sobel as default edge filter
Default should be archetypal and efficient filter
2022-06-05 10:19:56 +02:00
Bruno Herbelin
f8e8d33c61 Bugfix show editor of clone source 2022-06-05 10:18:36 +02:00
Bruno Herbelin
dd76135efd Polishing sharpen and edge Image filters 2022-06-02 23:57:43 +02:00
Bruno Herbelin
d7be7a69ab Original implementation of Edge Image filters 2022-06-01 23:49:12 +02:00
Bruno Herbelin
fd942b28c6 Finishing Sharpen Image filters 2022-05-31 23:14:53 +02:00
Bruno Herbelin
7c850b0405 Original implementation of Sharpen Image filters 2022-05-31 22:53:28 +02:00
Bruno Herbelin
e3bb95b3dd Original implementation of Blur Image Filters
With Gaussian, fast Gaussian, Hashed and morphological (opening and closing) methods. Remembering shader code for other fast methods.
2022-05-31 00:34:37 +02:00
Bruno Herbelin
662d8bcfda Minor UI and wording changes 2022-05-24 23:28:36 +02:00
Bruno Herbelin
3c0b2c64e1 Added opposite action of 'Group all sources'
Mixer action ungroupAll expands all SessionGroupSources.
2022-05-24 21:30:54 +02:00
Bruno Herbelin
ed7d42cf6d Improved Player view of pre- and post-filtered images 2022-05-23 19:31:36 +02:00
Bruno
8852914ceb BugFix FrameBuffer Filter init 2022-05-23 08:55:16 +02:00
Bruno Herbelin
944778175a Improved computation of framebuffer memory usage 2022-05-23 00:45:54 +02:00
Bruno Herbelin
81704c08c9 Show post-processed image in Player by default 2022-05-22 22:19:07 +02:00
Bruno Herbelin
810059e6da Bugfix attach source 2022-05-22 22:18:43 +02:00
Bruno Herbelin
8d95bd16fd BugFix: change Device of DeviceSource with different resolution 2022-05-22 22:04:45 +02:00
Bruno Herbelin
4600253d1e Cleanup alignment Source pannel 2022-05-22 18:02:59 +02:00
Bruno Herbelin
d695aa9f57 FrameBuffer creation flags replace booleans
Instead of many creation options (with alpha, with multisampling, etc) use a single flag with boolean operators. Creation of the new mipmap flag for FrameBuffer, rendering the current FBO into multiple sub-resolutions.
2022-05-22 15:14:10 +02:00
Bruno Herbelin
7867aac55f Cleanup use of new icons 2022-05-22 11:18:57 +02:00
Bruno Herbelin
e26563c3d6 Remove all reference and icons from iconmonstr
Icons were unused and license was incompatible with GPL
2022-05-21 22:39:30 +02:00
Bruno
07ad262857 Sofware limiter for OSX seems to need more margin 2022-05-19 09:08:53 +02:00
Bruno Herbelin
cb0abd51db RenderingManager: FPS software limiter even with VSYNC
V-sync on multiple windows is not always performing well. So limiting to 61 FPS works with both VSYNC at 60FPS or without VSYNC. This means the settings for VSYNC is useless (removed from Settings panel).
2022-05-18 23:46:27 +02:00
Bruno
cc69baf0dd Compilation fix 2022-05-18 12:50:07 +02:00
Bruno Herbelin
852a8d04c9 Fixup UI ImageFilter 2022-05-18 00:19:48 +02:00
Bruno Herbelin
ffdacb3850 Unified implementation of filters for CloneSources
All filters now derive from FrameBufferFilter, which is always used in a CloneSource. Default FrameBufferFilter is Passthrough filter. Others are Delay and Image filters. Implemented UI selection of filter type, XML session save and load. Linked ImageFilter to Code editor.
2022-05-18 00:10:14 +02:00
Bruno Herbelin
062e8357fa Fixing morphological shaders code 2022-05-15 23:34:09 +02:00
Bruno Herbelin
07dece9cd7 Adding Filters 2022-05-15 23:33:18 +02:00
Bruno Herbelin
d628a513d9 Place clone at same depth of origin
TODO: shift other sources to make room?
2022-05-11 21:27:10 +02:00
Bruno Herbelin
6012ad9b1e Unified edge ImageFilters to invert 2022-05-07 23:31:21 +02:00
Bruno Herbelin
c3e618de36 BugFix Show Player 2022-05-07 23:30:52 +02:00
Bruno Herbelin
6b9795fe96 Remove (obsolete) filters from ImageProcessingShader
This shader is now only for Color correction
2022-05-07 23:15:35 +02:00
Bruno Herbelin
f7da3a347d New morphological operators 2022-05-07 23:01:17 +02:00
Bruno Herbelin
cf020d06c6 Place clone next to origin upon cloning 2022-05-07 23:01:02 +02:00
Bruno Herbelin
137b5ca4f9 BugFix ImageFilter timing
new debuging shader
2022-05-07 18:24:38 +02:00
Bruno Herbelin
82be9326a8 Fixed ImageFilter timing 2022-05-07 15:39:06 +02:00
Bruno Herbelin
222282dced Populating CloneSource with many preset ImageFilters 2022-05-07 13:39:08 +02:00
Bruno Herbelin
c7a2086850 Change Source filter to Color Correction
Removed filter selection from UI
2022-05-03 23:31:08 +02:00
Bruno Herbelin
168ac5065d Performance improvement: disable render when No ImageFilter selected 2022-05-03 23:30:21 +02:00
Bruno Herbelin
158ea1984f BugFix: more stable use of FBOs for delay 2022-05-03 23:29:18 +02:00
Bruno Herbelin
f66d73e385 Improved and added settings for MediaPlayer split view slider 2022-05-03 20:04:02 +02:00
Bruno Herbelin
252ed1c6f2 Added slider to show source pre-post processed in Player 2022-05-03 00:39:10 +02:00
Bruno Herbelin
69e35167bc BugFix Support for GStreamer upgrade to 1.20 2022-05-02 19:50:30 +02:00
Bruno Herbelin
2140075133 bugfix equal operator 2022-05-01 22:25:20 +02:00
Bruno Herbelin
80469ead18 Initial commit of ImageFilter shader presets
Clone source can choose a filter
2022-05-01 22:24:59 +02:00
Bruno Herbelin
77dc563219 Minimally operational Shader editor
Can edit code in GLSL, syntax highlighted, and compile shader. Compatible with ShaderToy code.
2022-04-23 01:02:31 +02:00
Bruno Herbelin
9d7f0b22f7 BugFix ATI get memory GL_TEXTURE_FREE_MEMORY_ATI 2022-04-21 18:38:34 +02:00
Bruno Herbelin
56b17116e3 Preliminary implementation of Shader editor
Connect TextEditor with ImageFilter from current Clone Source.  GLSL Compilation seems to work....
2022-04-21 00:18:37 +02:00
Bruno Herbelin
c71791b649 Bugfix handle keyboard for TextEditor. Starting to create Shader Editor
New WorkspaceWindow for the shader editor.
2022-04-20 18:26:31 +02:00
Bruno Herbelin
c8f8fcf9d3 BugFix: prevent View Terminate if not previously Initiated
Ensures Action::Manager stores terminated actions only if previously initiated (caused iterative action storing on keyboard repeat).
2022-04-20 16:43:42 +02:00
Bruno Herbelin
d41a85f4a1 New ImageFilter applied to Clone Sources
Preliminary implementation, effective but without consequence on the rendering.
2022-04-19 01:23:50 +02:00
Bruno Herbelin
3c465f9a7a Improved Shader compilation 2022-04-19 01:23:04 +02:00
Bruno Herbelin
c25427cf4a Add possibility to define ShadingProgram with GLSL code 2022-04-18 14:02:51 +02:00
Bruno Herbelin
1c8575e40c Add test of resource availability 2022-04-18 14:01:50 +02:00
Bruno Herbelin
e512eab1e8 Move code of getGPUMemoryInformation to Rendering manager 2022-04-18 14:01:21 +02:00
Bruno Herbelin
4dd8ceb245 Clone Source connection with directional dot line
use arrows to draw dot line between clone and its origin
2022-04-17 21:46:48 +02:00
Bruno Herbelin
07e2bd4bcf Improvement: reuse FBO for Thumbnailing
Avoid create and delete a new FBO for each thumbnail, as they are often the same size.
2022-04-17 12:51:55 +02:00
Bruno Herbelin
05eb62bb35 Allow CTRL+move of Locked sources 2022-04-17 12:35:34 +02:00
Bruno Herbelin
0df3342757 Improve Source naming increment 2022-04-17 11:22:32 +02:00
Bruno Herbelin
0615f38a26 BugFix Thumbnail in 21:9 aspect ratio 2022-04-17 00:19:34 +02:00
Bruno Herbelin
1fe63b68ee Message improvement Warning Change XML version 2022-04-16 23:52:13 +02:00
Bruno Herbelin
1e7dbb5331 BugFix Source init with clones when inactive at creation 2022-04-16 23:25:20 +02:00
Bruno Herbelin
0ddc03b7c0 Fixed Clone Source Activation 2022-04-16 21:18:45 +02:00
Bruno Herbelin
becc3d0953 Clone Source loading fixed and simplified
Fixed loading order. Removed the option of origin selection for Clone: not meaningful anymore with chain of clones.
2022-04-16 19:52:52 +02:00
Bruno Herbelin
48b1bfaebd Graphics Card Memory check before allocating FBO
Improved warning when allocating FrameBuffer. Avoid allocating FrameBuffer when buffering delay in Clone Source if we risk to consume all RAM in graphics card.
2022-04-16 12:57:31 +02:00
Bruno Herbelin
c043026764 Clone Source; dynamic memory for delay, connection line to origin 2022-04-16 01:33:41 +02:00
Bruno Herbelin
0aed9fc306 Added dotted line rendering 2022-04-16 01:31:55 +02:00
Bruno Herbelin
739559783b GPU monitoring of RAM available when allocating FBO
Warning when allocation of FBO is critical.
2022-04-16 01:31:09 +02:00
Bruno Herbelin
0f4076acab Documenting SRT Broadcast 2022-04-11 22:41:22 +02:00
BHBN
9692ac3f4d Merge pull request #43 from prez/musl
Fix compilation on musl libc
2022-04-11 22:24:01 +02:00
prez
365a333b1d Fix compilation on musl libc 2022-04-11 17:09:36 +02:00
Bruno Herbelin
f039755bde Set Max Clone delay to 2.0s 2022-04-10 23:32:44 +02:00
Bruno Herbelin
d314f1bae2 Player empty message more meaningful 2022-04-10 00:50:56 +02:00
Bruno Herbelin
aae1915519 SessionFile source restore version snapshot from UI 2022-04-10 00:50:31 +02:00
Bruno Herbelin
220df8918c Lock behavior change: do not show lock icon on unlocked inactive sources
Show unlocked icon only when active, show locked icon always
2022-04-09 19:29:37 +02:00
Bruno Herbelin
3e41655902 Unified Logs for sources initialization 2022-04-09 15:20:48 +02:00
Bruno Herbelin
54a23f5ae7 BugFix CountVisitor 2022-04-09 15:07:55 +02:00
Bruno Herbelin
edffcf8902 Added Total count of source in Session mix info 2022-04-09 14:46:09 +02:00
Bruno Herbelin
dd55f41264 BugFix Session Group init and playable status.
Improved logs
2022-04-09 14:45:12 +02:00
Bruno Herbelin
8fef0052a3 New CountVisitor to count the number of sources in session
Session size is the number of elements, use CountVisitor to count the total number of sources inside (recursively through SessionSources).
2022-04-09 00:35:20 +02:00
Bruno Herbelin
f2db10d29a Added Double Frame on Session Source 2022-04-09 00:33:43 +02:00
Bruno Herbelin
33756c775c Fixed Session load recursion, allow higher level of imbrication
Recursive load of SessionFile in a Session is now detected by filename and prevented. Deeper level of integration of sessionfile inside session is thus possible (set to 3). Sessions now have an id, allowing to reference them by id in the logs. Terminology is clarified between level and recursion.
2022-04-08 17:44:39 +02:00
Bruno Herbelin
ef65dd8cc6 Source list UI with Initials of source and name 2022-04-03 23:29:12 +02:00
Bruno Herbelin
74d0d851ca Display list of sources in Session Group UI panel 2022-04-03 23:18:14 +02:00
Bruno Herbelin
49ebc17334 Source info() gives type, InfoVisitor gives instance info
Changed (back) to clean use of source->info() to return type dependent info string. The InfoVisitor gives unified detailed information about instance.
2022-04-03 00:02:20 +02:00
Bruno Herbelin
548aba5b7c BugFix wrong initialization time counter 2022-04-02 23:59:00 +02:00
Bruno Herbelin
dc1f1e02a1 Unifying icons for session and group sources UI 2022-04-02 17:45:57 +02:00
Bruno
d10b809687 Unified Information string on Group Source 2022-03-28 10:57:32 +02:00
Bruno
ad438ef339 BugFix Session Group creation
Duplicate Action history store can cause crash
2022-03-28 10:57:09 +02:00
Bruno Herbelin
8a7a6ed4f5 Improve group session (play, info) 2022-03-27 23:38:35 +02:00
Bruno Herbelin
c6097e0397 Bugfix and cleanup Group source insert
NB: default setAlpha now re-uses the source previous mixing coordinates (does not force default location)
2022-03-27 15:30:56 +02:00
Bruno Herbelin
0f3e856438 BugFix WorkspaceWindow clear on ESC and Transition view 2022-03-27 00:09:18 +01:00
Bruno Herbelin
5b6ec81cee Depth sort View all scene (background, workspace and foreground) 2022-03-26 15:08:47 +01:00
Bruno Herbelin
e888bfbc8d BugFix SessionFile source import 2022-03-26 15:02:28 +01:00
Bruno Herbelin
b04ab65258 Merge remote-tracking branch 'origin/master' 2022-03-24 23:55:04 +01:00
Bruno Herbelin
46b707f246 Unified & fixed implementation of Group of sources (formerly flatten)
Fixed MixingGroup keep&restore when making Session Group Sources. New global feature to Group all sources into one session source. Unused but potentially useful implementation of flatten of mixer session into one new session source.
2022-03-24 23:52:00 +01:00
Bruno Herbelin
f2a6073829 Unified & fixed implementation of Group of sources (formerly flatten)
Fixed MixingGroup keep&restore when making Session Group Sources. New global feature to Group all sources into one session source. Unused but potentially useful implementation of flatten of mixer session into one new session source.
2022-03-24 00:23:27 +01:00
Bruno Herbelin
e5926a5371 BugFix Load mixing groups for Session source and groups 2022-03-23 22:03:02 +01:00
Bruno Herbelin
86c4581a50 BugFix gstreamer HW decoding
Enforce low priority when disabling on launch.
2022-03-23 22:01:07 +01:00
Bruno Herbelin
a80074dc21 Mixer functions cleanup, new flatten 'Embed in new' session 2022-03-22 00:20:41 +01:00
Bruno Herbelin
3effdd1408 Spelling and fix README and doc 2022-03-22 00:19:53 +01:00
Bruno
b927c55216 Temporary fix for preventing horizontal scrolling in main pannel 2022-03-21 16:24:40 +01:00
Bruno
49c590a9b5 OSX compilation update 0.7.0 2022-03-21 16:19:52 +01:00
Bruno Herbelin
8df6a2dd83 Display more informative error message on XML load fail. 2022-03-20 12:06:32 +01:00
Bruno Herbelin
fe66c95a29 Load Settings even for different version.
Cleanup Settings implementation.
2022-03-20 12:06:09 +01:00
Bruno Herbelin
c080959f64 Avoid very-long-line-length-in-source-file warning for glad generated source code 2022-03-20 00:30:56 +01:00
Bruno Herbelin
f27a88787d Add linux manpage and update main accordingly 2022-03-19 21:24:42 +01:00
Bruno Herbelin
5853495125 IMGUI API change for Text display 2022-03-19 16:46:59 +01:00
Bruno Herbelin
f49d94948d Bugfix Duplicate input mapping 2022-03-19 14:58:27 +01:00
Bruno Herbelin
82dad0fad3 UI improvement, rescaling windows content with user font scale 2022-03-19 14:58:12 +01:00
Bruno Herbelin
fea99498af Show initials of source in combo selectors. 2022-03-19 01:27:14 +01:00
Bruno Herbelin
5582ee8ed8 Compilation warning fix 2022-03-18 21:46:22 +01:00
Bruno Herbelin
f4b6db9404 Remove uncessary font, find fonts in system if not available. 2022-03-18 21:46:08 +01:00
Bruno Herbelin
5c92362aae Fixing typos and spelling mistakes 2022-03-16 23:28:39 +01:00
Bruno Herbelin
667ea9fa64 Fix glfw dependency different version 2022-03-15 22:15:18 +01:00
Bruno Herbelin
b710750035 Merge remote-tracking branch 'origin/master' 2022-03-15 18:49:12 +01:00
Bruno Herbelin
491ff01c79 Optional library dependency CMake 2022-03-14 23:34:02 +01:00
Bruno Herbelin
4981145dd8 Fix version from git 2022-03-14 23:34:02 +01:00
Bruno Herbelin
e9497b03f4 Fix version from git 2022-03-14 23:31:50 +01:00
Bruno Herbelin
d76e518db1 Optional library dependency CMake 2022-03-14 22:52:50 +01:00
Bruno Herbelin
a2906c6aa5 Preparing 0.7 2022-03-14 01:10:45 +01:00
Bruno Herbelin
e0676c66a0 Metronome fix
do not call now() multiple times to avoid time difference between calls.
2022-03-13 23:13:32 +01:00
Bruno Herbelin
0b12c5a169 Bugfix and Help Input mapping.
Duplicate input mapping, drag'n drop, and various UI improvements.
2022-03-12 18:05:53 +01:00
Bruno Herbelin
39b61fe331 Reimplementation of SourceInputCallbacks into Session
Session should be the object holding the list of inputs parameters (e.g. synchrony) and the list of source callbacks. This also avoids mixing input when copying sources.  Code could be improved but is operational.
2022-03-07 00:23:24 +01:00
Bruno Herbelin
83e77681d9 Various BugFix and UI improvements
Prevent key repeat for commands, allow maintain ESC key, replaced timeline BPM display (innacurate and confusing) with a simplified icon indicator for Metronome synchronization of Media player, improved Media Player loop mode tooltip, improved Pattern source selector.
2022-02-26 22:35:27 +01:00
Bruno Herbelin
95a69937bd BugFix Mediaplayer loop and info mediaplayer 2022-02-26 22:32:37 +01:00
Bruno Herbelin
c355bd7569 Bugfix: update depth of sources from dropped media file
To be investigated further if problem persists: patch seems to work (increment twice View::need_deep_update_) but not fully sure why two frames are necessary...
2022-02-22 23:32:43 +01:00
Bruno Herbelin
559a186cd9 BugFix repeated toggle clear workspace 2022-02-22 22:43:58 +01:00
Bruno Herbelin
7e81ef37d7 Upper-case keyboard key info 2022-02-21 12:33:22 +01:00
Bruno Herbelin
2e167d260d New Geometry source callback
Set Geometry callback applies and interpolates position, scale and rotation of a source. Implemented UI and XML.
2022-02-21 12:32:48 +01:00
Bruno Herbelin
aa50d818ec Added directionality and speed selection in Input Callback
Unified implementation of constructor for SourceCallbacks. New icons and IconMultitouch for configuration GUI of input callback.
2022-02-20 21:03:39 +01:00
Bruno Herbelin
b9dd0a3877 Added icons in Output window menu bar
Unified appearance with other windows
2022-02-20 21:01:28 +01:00
Bruno Herbelin
e03ef7e214 BugFix Clone is playable if its origin is playable too 2022-02-19 12:42:42 +01:00
Bruno Herbelin
caa05d739f BugFix double clic output window 2022-02-19 03:24:25 +01:00
Bruno Herbelin
f580673dea Minor changes in SRT and generator sources to help user
Clearly state 'listener' and 'call' roles for SRT. Add a '>' indicator to indicate if a generator is playable.
2022-02-18 19:09:37 +01:00
Bruno Herbelin
297d271e63 Change direction Loom
more logical to set positive delta to increase visibility
2022-02-15 23:44:54 +01:00
Bruno Herbelin
a28e4be5a3 Bugfix play selection 2022-02-15 23:44:14 +01:00
Bruno Herbelin
6b672acdc7 Improved UI for Input Mapping 2022-02-14 23:40:26 +01:00
Bruno Herbelin
26f5368264 Implementation Control manager with singleton mechanism (not static) 2022-02-13 22:29:55 +01:00
Bruno Herbelin
fc5b967973 Imput Mapping support for Multitouch with TouchOSC
16 touch buttons in Multitouch tab of TouchOSC companion app for user customized callbacks.
2022-02-13 12:49:43 +01:00
Bruno
3cf497fa91 Change Multitouch TouchOSC
Akai MPC inspiration for 16 buttons with touch variability
2022-02-11 12:48:43 +01:00
Bruno Herbelin
f50411e9db Bugfix Callbacks
Added duration to SetAlpha callback. Saving and loading Play callback.
2022-02-11 00:28:25 +01:00
Bruno Herbelin
74eca2e527 Added UI actions to change key of source callbacks and copy-paste
Drag&drop input button keys to change key associated to a list of source callbacks (i.e. move). Copy Paste in context popup menu to remember the input model to copy at another input.
2022-02-10 00:24:38 +01:00
Bruno Herbelin
6200e78e93 Bugfix Guru plot 2022-02-07 23:51:43 +01:00
Bruno Herbelin
904c122ee0 Minor UI improvement Input Mapping 2022-02-07 23:34:45 +01:00
Bruno Herbelin
741afaea18 Improved Source Callback for multi-callbacks compatibility 2022-02-07 17:45:34 +01:00
Bruno Herbelin
6cf86d80e2 Input Mapping suport for Gamepad Axis (multiply SourceCallback)
Apply the ControlValue as a multiplyer to the Callback. UI with indication bars for gamepad axis.
2022-02-07 13:27:05 +01:00
Bruno Herbelin
886305ec13 Input Mapping support for Gamepad buttons
Cleanup UI defines.
2022-02-06 23:37:11 +01:00
Bruno Herbelin
ab040f5268 First working implementation of Inputs Mapping
Management of inputs in Control, Management of callbacks creator per input in Source, Saving and Loading in Session, Unified renaming of SourceCallbacks, User interface window for creating and editing input mapping from Keyboard and Numerical keypad, with appropriate Settings.
2022-02-06 00:36:05 +01:00
Bruno Herbelin
8404e0f670 Milestone in SourceCallbacks and Keyboard callback trigger
Updated SourceCallback class to accept cloning, reversing, and visitors for saving./loading. New mechanism in Source to listen to key triggers for launching SourceCallbacks. Saving and loading in SessionVisitor and SessionCreator.
2022-01-30 00:25:08 +01:00
Bruno Herbelin
3605ae14b5 Validate Port value in UI before changing 2022-01-28 18:44:32 +01:00
Bruno Herbelin
bce372bd79 Display Info of created source in Preview 2022-01-26 18:58:43 +01:00
Bruno
715c48b7eb Slight Font offset ajustment for FontAwesome glyphs 2022-01-25 13:11:23 +01:00
Bruno Herbelin
eb9a3c2ad1 Make Metrics semi-transparent when Workspace cleared 2022-01-24 23:53:53 +01:00
Bruno Herbelin
b261829aea BugFix interference output window rescale on Workspace UI windows 2022-01-24 23:53:27 +01:00
Bruno Herbelin
595be6b7b8 Change Shortcut for sources Restart to CTRL_SPACE
Updated Help UI accordingly, plus including SrtReceiverSource
2022-01-24 23:34:23 +01:00
Bruno Herbelin
9ed76ae4da Finalizing implementation of SrtReceiverSource
Added icons, unified UI, loading and saving in XML.
2022-01-24 23:06:47 +01:00
Bruno Herbelin
2ae0ef40d4 SrtReceiverSource for broadcasted stream
Implemented dedicated source, with UI for creation and saving appropriate settings.
Also updated info and imgui visitors accordingly
2022-01-24 20:18:33 +01:00
Bruno Herbelin
f5f7d3c154 Fixed nvidia hw encoding pipelines 2022-01-23 19:43:07 +01:00
Bruno Herbelin
a9ab4dbe38 More robust implementation of Video Broadcast
Testing GST features and using HW accelerated  encoding if available
2022-01-23 12:17:08 +01:00
Bruno Herbelin
5c3c26851c Implemented Broadcast
Initial implementation of SRT streaming as listener. Changed stream terminology to distinguish network broadcasting and network sharing in local network. Updated user settings accordingly.
2022-01-23 01:10:10 +01:00
Bruno Herbelin
2b3696aab1 Slight change in terminology to distinguish streaming from broadcasting
VideoStream is reserved for point-to-point video streaming (between vimix), while VideoBroadcast is for sending out to many potential clients.
2022-01-22 00:23:59 +01:00
Bruno Herbelin
35ec0c9bcf BugFix: prevent repeated initialization 2022-01-22 00:20:40 +01:00
Bruno Herbelin
4f915d6708 UI info procrastination 2022-01-20 23:27:43 +01:00
Bruno Herbelin
f4eb8b246b Minor improvements in InfoVisitor for source info 2022-01-20 22:46:47 +01:00
Bruno Herbelin
1a80e52241 Initiating implementation of VideoBroadcast 2022-01-20 22:46:24 +01:00
Bruno Herbelin
afa27a04fe BugFix: fail DeviceSource if not plugged 2022-01-20 18:01:07 +01:00
Bruno Herbelin
b82c83de5e BugFix DeviceSource: shared access to stream vis Device::manager
Creation of multiple DeviceSources is possible (also for multiple sessions and transitions) through centralized management of gst streams. Creation and deletion of a shared stream accross DeviceSources is handled.
2022-01-20 01:28:30 +01:00
Bruno Herbelin
625e2305ba Fix Quit call for Linux 2022-01-17 23:55:44 +01:00
Bruno
6b4781b7d5 BugFix Device manager initialization
Ensure initialization is complete before other calls to Device::manager can operate (e.g. setDevice in session Creator)
2022-01-17 23:47:07 +01:00
Bruno
7acffabdd8 restore commented line 2022-01-17 20:23:50 +01:00
Bruno
e6f2aa2399 Merge remote-tracking branch 'origin/master' 2022-01-17 20:21:04 +01:00
Bruno
ece7e04c7c BugFix: correctly wait for Mixer to save file on exit
On the way, also improved Connection Manager ending properly.
2022-01-17 20:20:44 +01:00
Bruno
0b4d273e08 BugFix: correctly wait for Mixer to save file on exit
On the way, also improved Connection Manager ending properly.
2022-01-17 19:45:58 +01:00
Bruno Herbelin
81e8d6d99c Refactoring Session saving
use Session::save static method to save a session from a thread (same mechanism as Session::load). It calls Action::takeSnapshot if saving version is required. Mixer is busy during saving, pops up info when done.
2022-01-17 00:38:48 +01:00
Bruno Herbelin
e96444671e BugFix: give time to Save on exit and stop recordings on Quit 2022-01-16 19:16:51 +01:00
Bruno Herbelin
e52785a8b4 Cleanup UI for source info, cleanup code 2022-01-16 17:47:43 +01:00
Bruno Herbelin
ddccc5ff6b Strengthen implementation of Clone and Render sources
Change of vocabulary, UI display of playtime
2022-01-16 15:27:22 +01:00
Bruno Herbelin
8bbcef585f Isolate implementation of RenderSource and new Non-Recursive mode
Separate files for RenderSource, make RenderSource playable, and implement two rendering mechanisms
2022-01-16 12:20:28 +01:00
Bruno Herbelin
e58041227b Added delay and image selection to CloneSource 2022-01-15 00:15:52 +01:00
Bruno Herbelin
3678e8fb27 Isolate implementation of CloneSource 2022-01-13 22:00:25 +01:00
Bruno Herbelin
1146a9125b Cleanup extension filename and bugfix session preview 2022-01-13 21:41:50 +01:00
Bruno Herbelin
aab0c055ed UI improvements
Make room for more icons in left bar if necessary. Also react to resizing of workspace for windows not visible.
2022-01-09 13:18:13 +01:00
Bruno Herbelin
685082e212 Improved UI main panel & control
bugfix; scrolling about and settings icons, clic outside buttonswitch. Updated default windows position.
2022-01-09 00:01:06 +01:00
Bruno Herbelin
1bb8b636b9 Bugfix pop font 2022-01-08 15:04:31 +01:00
Bruno Herbelin
43c51c3b82 Navigator lower-left corner icons for Fullscreen and Workspace mode
Added icons to toggle fullscreen & show/hide windows. Using View names instead of hardcoded string. Cleanup some UI variables.
2022-01-08 15:04:21 +01:00
Bruno Herbelin
b9ed64fba2 Make sure the name of the view is set correclty
even if there was a setting found
2022-01-08 15:01:12 +01:00
Bruno Herbelin
ceaac03adf Log Window - Display last log line in title when collapsed 2022-01-08 10:57:12 +01:00
Bruno Herbelin
3085a837c8 Nicer rendering of workspace windows with transparency 2022-01-08 01:05:10 +01:00
Bruno Herbelin
2e5e2c8430 On Save-as, open FileDialog in same directory of previous filename 2022-01-08 00:49:20 +01:00
Bruno Herbelin
48df5c0eb1 Cleanup UI - Filters menu, Save-as property
Cleanup code in ImGuiToolkit::IconButton
2022-01-08 00:35:02 +01:00
Bruno Herbelin
fcad6766c3 Update UI update and TransitionView to match WorkspaceWindows clear
Enter Workspace Clear mode when switching to Transition view (instead of specific hack). Do not render all windows when in Clear workspace mode.
2022-01-07 20:08:32 +01:00
Bruno Herbelin
c91a4670de Added Link status next to source preview in left pannel
Give quick access to select the linked group.
2022-01-07 18:31:25 +01:00
Bruno Herbelin
5e7c325874 BugFix: double-clic selection of mixing group crash
Improved CTRL+Clic for mixing group selection instead.
2022-01-07 17:57:16 +01:00
Bruno Herbelin
6b8a1428d7 Disabled Debug log Framebuffer 2022-01-07 17:56:26 +01:00
Bruno Herbelin
5bd81db37e Bugfix DeviceSource
API changed v4l2.
2022-01-07 16:10:58 +01:00
Bruno Herbelin
9834baedfa Passing main argument to open session 2022-01-07 11:10:28 +01:00
Bruno Herbelin
0b4c42859d Last minute entries into Help toolbox 2022-01-07 01:56:35 +01:00
Bruno Herbelin
a92b45ae26 Select Linked MixingGroup on double clic & a bug fix 2022-01-06 22:04:05 +01:00
Bruno Herbelin
1e2096e691 Bugfix restore Session Recent combo on start 2022-01-06 21:46:41 +01:00
Bruno Herbelin
3df6ffe280 Major BugFix: avoid default gst g_main_context
Do NOT update g_main_context at RenderingManager update. Do not use g_main_context for Dialogs. Do not rely on default g_main_context for Device discoverer (implemented a thread save g_main_loop dedicated).
2022-01-06 20:20:30 +01:00
Bruno Herbelin
d4f370c071 UI WorkspaceWindows follow window resize
Fixed bug in restore window position.
2022-01-06 14:58:35 +01:00
Bruno Herbelin
b894ea866a Make Timer a workspace window 2022-01-06 09:13:50 +01:00
Bruno Herbelin
3a300a4ca3 New UI windows behavior to clear workspace on ESC
Press ESC to toggle a 'clear workspace' mode. 
Cleanup of UserInterface rendering of output preview to enable this.
Move include to internal_imgui.h outside of ImGuiToolkit.h.
2022-01-06 01:21:18 +01:00
Bruno Herbelin
0ad844d10e Do not show source panel after source creation 2022-01-05 15:48:36 +01:00
Bruno
d310a45f72 Updated CMake comment to new tinyfiledialog git 2022-01-05 15:38:24 +01:00
Bruno
57c31804b4 Cleanup UI dialog save on exit
Also set save-on-exit by default
2022-01-05 15:37:47 +01:00
Bruno Herbelin
5fb70a9b9a Save on exit; test before closing
Detect window close or quit events to make sure a filename is given if save-on-exit is active.
2022-01-05 15:08:52 +01:00
Bruno Herbelin
d402143989 Cleanup icons and minor bugfix UI 2022-01-05 01:02:44 +01:00
Bruno Herbelin
ad8d799cf6 BugFix Session group 2022-01-04 22:13:41 +01:00
Bruno
cec705264d Replaced Tinyfiledialog repo
Updated code is at https://git.code.sf.net/p/tinyfiledialogs/code
2022-01-04 18:16:12 +01:00
Bruno
28a2e61361 Removed submodule ext/tfd 2022-01-04 18:04:32 +01:00
Bruno
6017215ada Get Tinyfiledialog from its original author 2022-01-04 17:48:14 +01:00
Bruno
8f3128e4b3 Merge remote-tracking branch 'origin/master' 2022-01-04 14:38:04 +01:00
Bruno Herbelin
109e6f590a Disabling vtenc streaming for OSX (could not make it work) 2022-01-04 14:37:56 +01:00
Bruno
ac86d75e10 Merge remote-tracking branch 'origin/master' 2022-01-04 12:33:59 +01:00
Bruno Herbelin
8f0491ea57 Video Streamer with H264 hardware acceleration
Simplified option in user menu; lower bandwidth with H264, otherwise use JPEG. Always use RAW for localhost.
2022-01-04 12:33:46 +01:00
Bruno
6403e51ba7 Merge remote-tracking branch 'origin/master' 2022-01-04 10:02:05 +01:00
Bruno Herbelin
e0522608a4 UI improvement; hovering icons indicate possible action
Source filters icons without button. Unified lock icon with view. Updated help.
2022-01-04 00:54:12 +01:00
Bruno Herbelin
4b9a230803 oops 2022-01-03 22:16:55 +01:00
Bruno Herbelin
fc5246efaa New & improved align and distribute in MixingView 2022-01-03 18:20:02 +01:00
Bruno Herbelin
4eebfbb89f Improved Glyph layout
Support for shape and placement of glyph
2022-01-03 17:16:55 +01:00
Bruno Herbelin
353d2c4744 New Glyph decoration to show initials of source 2022-01-03 15:41:08 +01:00
Bruno Herbelin
2718e83132 Happy new year 2022 2022-01-02 23:17:22 +01:00
Bruno Herbelin
7547d1179d Cleanup UI
Ensure icons are dedicated to one single thing.
2022-01-02 19:54:48 +01:00
Bruno Herbelin
61e89286bc Fixed Device manager: restore gmainloop
The gmainloop is used by gst to detect devices. Fixed bugs on detection of invalid devices.
2022-01-02 14:17:10 +01:00
Bruno Herbelin
53ae715816 Restart the source after insertion from New Source panel 2022-01-02 11:49:02 +01:00
Bruno Herbelin
8cb37dba36 ORDER change: add sources at the end when create
Inserting sources at front was changing their index every time, which broke OSC addressing
2022-01-02 11:41:47 +01:00
Bruno Herbelin
4426f70de7 Code editor for Custom pattern gstreamer
Bugfix in Streamsource and UI
2022-01-01 23:59:30 +01:00
Bruno Herbelin
f0ca13150f New Custom pattern entry for New Source 2022-01-01 10:14:51 +01:00
Bruno Herbelin
780a20689c Improved user message for stream discovery failure 2022-01-01 10:13:46 +01:00
Bruno Herbelin
28f9ed1d8d Cleanup & new unwrapped function 2022-01-01 10:12:50 +01:00
Bruno Herbelin
2b5b8ad02c Bugfix Stream timeout initialization test 2021-12-31 14:24:51 +01:00
Bruno Herbelin
d5092b1765 Save & load GenericStrreamSource 2021-12-31 13:30:51 +01:00
Bruno Herbelin
fda62314f9 UI integration of GenericStreamSource 2021-12-31 13:16:39 +01:00
Bruno Herbelin
17018c137f MultiLine text display 2021-12-31 13:16:16 +01:00
Bruno Herbelin
8838c19c39 String functions to wrap test or join lists 2021-12-31 13:16:00 +01:00
Bruno Herbelin
f02a99a4e2 Improved GenericStreamSource, with stream discoverer
Also timeout to fail if open does not works + new GST icon.
2021-12-31 13:15:23 +01:00
Bruno Herbelin
7b26b0f23e Unified IMGUI_SAME_LINE width 2021-12-31 13:13:29 +01:00
Bruno Herbelin
0e9984827a Cleanup gst_element_get_state 2021-12-31 13:12:12 +01:00
Bruno Herbelin
033d41863a Added Stream Discoverer to detect frame size from a gstreamer pipeline
Previous use of Stream are not affected (the discoverer is passively returning the given width and height). But if the Stream is created without dimensions, it will run a discoverer to try to get preroll frames and detect width and height from there.
2021-12-30 00:15:43 +01:00
Bruno Herbelin
bc540044ac Accept launch of vimix if OSC connection failed 2021-12-29 14:41:27 +01:00
Bruno Herbelin
76a2535da3 Fixed issue of low quality stream in JPEG: new default to RGB RAW RTP stream
Backward compatibility through menu un stream output view (allow selecting JPEG)
2021-12-29 14:37:56 +01:00
Bruno Herbelin
ff48877d16 Fixed OSC feedback after source change. Added OSC command to lock source. 2021-12-27 23:36:28 +01:00
Bruno Herbelin
4b8efabc5f Improve and cleanup OSC control and translation
Changed default send Port to 7001. Updated documentation.
2021-12-27 17:28:11 +01:00
Bruno Herbelin
c79be090df Implementation of OSC settings and translator
Translations are in a config xml file in settings directory, and can be directly edited in text by the user. Settings UI allows changing Ports for incoming and outgoing UDP.
2021-12-27 01:04:49 +01:00
Bruno Herbelin
626eab7e8f Update and advertising of TouchOSC layout 2021-12-27 01:02:43 +01:00
Bruno Herbelin
c103b7d883 Finalization of OSC API, Tutorial for TouchOSC 2021-12-26 14:44:07 +01:00
Bruno Herbelin
cde055e29b Implementation of Session control
With Session recall from OSC
2021-12-26 01:20:44 +01:00
Bruno Herbelin
1cb448c42e Output session fading fixed for OSC and animation.
Linear interpolation (instead of dichotomy converge) for fading at Session update. Mixing View update reads value of session fading to animate the cursor (which was preventing other manipulation of fading). Cleanup fading in OSC controller, with animation options and fade-in and fade-out controls.
2021-12-26 00:41:02 +01:00
Bruno Herbelin
3d05444f30 Improved OSC control with TouchOSC
Added Looming source callback, and cleanup sync of sources. New horizontal version of OSCTouch UI.
2021-12-25 16:05:43 +01:00
Bruno Herbelin
7a551189d9 Improved log of OSC message. 2021-12-25 00:41:51 +01:00
Bruno Herbelin
b885e70fed Remove spaces from Source name
Replace space by underscore
2021-12-25 00:41:24 +01:00
Bruno Herbelin
0a27c14041 Control manager and TouchOSC sync 2021-12-23 22:17:05 +01:00
Bruno Herbelin
eb8e33e311 Correct call to Source Activation (inheritance) 2021-12-23 22:16:16 +01:00
Bruno Herbelin
2d44a60b90 Bi-directional OSC communication for Control manager
Unified OSC message declaration with Communicator
2021-12-21 23:48:20 +01:00
Bruno Herbelin
135b6a5702 cleanup SourceCallbacks on source destructor 2021-12-21 00:19:55 +01:00
Bruno Herbelin
706c72fda8 More OSC control
Grab and resize dynamically, select source by index, etc.
2021-12-21 00:19:39 +01:00
Bruno Herbelin
fb7bdba388 Code cleanup 2021-12-20 00:30:59 +01:00
Bruno Herbelin
733d08638d Control manager thread save with SourceCallbacks 2021-12-20 00:30:50 +01:00
Bruno Herbelin
cb3cca8a64 catchup previous commits 2021-12-20 00:29:57 +01:00
Bruno Herbelin
a3a581794e Node update callbacks do not need to be disabled 2021-12-20 00:26:08 +01:00
Bruno Herbelin
f921e7610c New mechanism for source update with callbacks
Similarly to Node update callbacks, sources now have SourceCallbacks called at the start of each update. Several SourceCallback are implemented to ensure thread safe update of more complex properties (mixing alpha, depth, etc.).
2021-12-20 00:25:42 +01:00
Bruno Herbelin
8deb364025 Cleanup of main update calbacks
Clarify update and draw of rendering manager by using callbacks (instead of hidden calls in draw method).
2021-12-19 01:12:25 +01:00
Bruno Herbelin
3a9c6f56bf Work in progress OSC Control manager
Support for log, output and source targets. Now needs to be developed for all attributes.
2021-12-19 01:11:29 +01:00
Bruno Herbelin
a612154123 Initial implementation of Control manager
Control manager will handle control actions, recorded or from OSC. Here skeleton for receiving OSC messages is in place. Cleanup of includes for NetworkToolkit. Touched a bit the BaseToolkit.
2021-12-18 16:02:37 +01:00
Bruno Herbelin
bbc5e50491 bugfix show Player when clic source 2021-12-18 10:18:36 +01:00
Bruno
6e3dd8165e Merge remote-tracking branch 'origin/master' 2021-12-13 09:37:13 +01:00
Bruno Herbelin
a7689a8f54 Help window, setting to show/hide Tooltips
Menu and keyboard shortcut declaration centralized. List of all keyboard shortcuts. ImGuiToolkit unified tooltips.
2021-12-12 23:12:56 +01:00
Bruno Herbelin
731a1af1a6 Defines for ImGuiToolkit icons for source. 2021-12-12 23:10:07 +01:00
Bruno Herbelin
f53ebd4389 BugFix crash on close Player window 2021-12-11 21:35:23 +01:00
Bruno
a2d61cc30a Merge remote-tracking branch 'origin/master' 2021-12-09 12:36:21 +01:00
Bruno Herbelin
baa6ddb401 Implementation of user defined mixing deactivation limit
Mixing view handles to grab and scale limbo area. Saving of user defined limit in Session (and snapshot). Testing for source activation outside of update during session update loop.
2021-12-08 23:55:27 +01:00
Bruno
4455aa6709 Merge remote-tracking branch 'origin/master' 2021-12-06 14:04:06 +01:00
Bruno Herbelin
315a8534d5 Store output PNG capture in list of recent recordings 2021-12-06 12:35:09 +01:00
Bruno Herbelin
d77bd4034d Improved UI tooltips 2021-12-06 12:29:22 +01:00
Bruno Herbelin
fa71797ed2 Unified implementation saving and loading settings history files 2021-12-06 11:41:03 +01:00
Bruno Herbelin
8c63552573 Global settings for Save and continue auto-preload
Added configuration for recent recording list. Added tooltip for filename in list.
2021-12-06 11:16:47 +01:00
Bruno Herbelin
a18d53c637 Improved Save and continue recording
When triggered from menu, prepare the UI for next openning of the new source pannel
2021-12-06 00:16:53 +01:00
Bruno Herbelin
ffe05368e8 Update New Source panel for Media
Added list of recent files, recent recordings, and folders list of media files. All saved in settings. Connect list of recent recordings with recorder.
2021-12-05 18:41:58 +01:00
Bruno Herbelin
923d84f378 Unified SystemToolkit list directory with dialog file patterns 2021-12-05 18:39:58 +01:00
Bruno Herbelin
e5334aae0a Cleaner file patterns for dialogs 2021-12-05 18:33:53 +01:00
Bruno Herbelin
4675be7e2a Unified notification of source creation with Source info
New virtual function source::info used for notification after adding source
2021-12-05 18:32:23 +01:00
Bruno Herbelin
bf3fc61ef7 Bad idea: do not use nvidia hardware decoder for jpeg
just crashes without reason and not very useful
2021-12-04 23:05:12 +01:00
Bruno Herbelin
ebd9fab312 Improved ordering of hardware decoding and log info 2021-12-04 00:23:27 +01:00
Bruno Herbelin
d359cf33d1 Improved runtime check of hardware encoder
gstreamer toolkit has_feature now tests possible instanciation
2021-12-03 23:36:07 +01:00
Bruno Herbelin
14bab1e299 Runtime selection of hardware GPU encoder
temporary implementation
2021-12-03 01:05:32 +01:00
Bruno Herbelin
4c4ad144b9 Finish Frame grabber after return on failed initialization 2021-12-03 01:05:04 +01:00
Bruno Herbelin
1157c0b1c5 cleanup frame grabber gst timer 2021-12-03 01:03:21 +01:00
Bruno Herbelin
68b2c5e0c1 Frame grabber threaded initialization
Start gstreamer init of frame grabber in a thread and wait future return from initializer before switching to active recording mode.
2021-12-02 11:45:22 +01:00
Bruno Herbelin
b97fd06f2a Bugfix Resolution frame buffer
Set width to power of 2, needed for encoding (even if OpenGL accepts to display it)
2021-12-02 11:40:31 +01:00
Bruno Herbelin
51f0f5bd66 Fixed ending of recording on exit 2021-12-02 09:35:02 +01:00
Bruno Herbelin
66f445997d Preliminary implementation of recording 'save & continue' 2021-12-01 23:05:41 +01:00
Bruno
addd199407 Merge remote-tracking branch 'origin/master' 2021-11-29 11:16:22 +01:00
Bruno Herbelin
73d4f7c1ea Ensure swap interval 2021-11-28 23:58:01 +01:00
Bruno Herbelin
25fc5562db Unified layout of HelpMarkers 2021-11-28 23:57:33 +01:00
Bruno Herbelin
4d52bcb5b3 Fix glfw set window pos 2021-11-28 20:50:56 +01:00
Bruno Herbelin
3d2de560b0 Timelines of metro-synched media player 2021-11-28 11:36:56 +01:00
Bruno Herbelin
809e30d906 Timeline display in beat unit for synched to metronome 2021-11-27 19:26:33 +01:00
Bruno Herbelin
ef9e41f20d Fixed display of time in minimal string mode 2021-11-27 19:23:51 +01:00
Bruno Herbelin
1b4849f214 Media player synchronicity to beat or phase
Metronome synched play, rewind and step. saving in xml.
2021-11-26 12:22:39 +01:00
Bruno
26cc67cd41 Merge remote-tracking branch 'origin/master' 2021-11-25 09:56:24 +01:00
Bruno Herbelin
e123d139e4 Introducing modes of Metronome synchronicity 2021-11-24 21:48:51 +01:00
Bruno Herbelin
a8abd52afb Merge remote-tracking branch 'origin/add-code-of-conduct-1' 2021-11-24 20:32:49 +01:00
Bruno Herbelin
091e99f21b New export function for Version of a session 2021-11-24 20:32:29 +01:00
Bruno
7b7875e23f Merge remote-tracking branch 'origin/add-code-of-conduct-1' 2021-11-24 10:41:55 +01:00
Bruno Herbelin
b6593c2a83 Added date to snapshot
Allows showing date of version
2021-11-24 00:15:40 +01:00
Bruno Herbelin
5ac7887360 Convert Snapshots into Versions of session
Added auto-snapshot on save to have an Iterative Saving mode, and change terminology of 'snapshots' to 'versions' management.
2021-11-23 22:47:44 +01:00
Bruno Herbelin
ed7627af6f Fixed UI spacing proportional to screen DPI 2021-11-23 22:46:22 +01:00
BHBN
1ea9fc54b2 Create CODE_OF_CONDUCT.md 2021-11-22 00:22:18 +01:00
Bruno Herbelin
3819571ec0 Fixed UI display time in readable form 2021-11-21 22:39:11 +01:00
Bruno Herbelin
94f131fc57 Fixed panel window show/hide 2021-11-21 22:10:17 +01:00
Bruno Herbelin
3c20314aab Metronome and Stopwatch User Interface
New Timer window in UI for Metronome (Ableton Link management) and replaces Timers. Former Timers in Metrics are replaced with Runtime (of session, of program and of total vimix runtime in settings). Temporarily disconnected Metronome from MediaPlayer actions.
2021-11-21 16:54:56 +01:00
Bruno Herbelin
1506d36407 Readable GST time is at 1/10th second precision 2021-11-21 16:52:09 +01:00
Bruno Herbelin
aa4b2967c7 Adding a timestamp to Session instanciation
Used to compute runtime of a session
2021-11-21 16:51:19 +01:00
Bruno Herbelin
a42881d31f Texture view slider UI fix 2021-11-21 16:46:18 +01:00
Bruno Herbelin
6a3ff2f235 More freedom of grab translation for all views 2021-11-17 23:11:15 +01:00
Bruno Herbelin
fc4e3dc362 Metronome settings and UI improvements 2021-11-14 00:18:32 +01:00
Bruno Herbelin
d6c689c5bb Cleanup include ImGuiToolkit 2021-11-14 00:18:10 +01:00
Bruno Herbelin
8676e9b900 Integration of Ableton link in vimix application
No useful functionality yet. Only connecting, set parameters, show metrics and save settings.
2021-11-13 15:01:02 +01:00
Bruno Herbelin
c271cad9aa Cleanup headers and dependencies 2021-11-13 00:14:05 +01:00
Bruno Herbelin
8e3bf786c0 Initial implementation of Metronome from Ableton LINK
Added submodule for github ableton link, and compiled draft of Metronome class.
2021-11-13 00:13:50 +01:00
Bruno Herbelin
a6ba694fbd Code warning cleanup and add GPL license header to all CPP files 2021-11-10 23:19:38 +01:00
Bruno
790ccc320e OSX bundle install of Frei0r plugins 2021-11-10 21:16:16 +01:00
Bruno Herbelin
26e951e59b Update website screenshot 2021-11-10 11:02:05 +01:00
Bruno Herbelin
a97581f5d7 semi-transparent icon of lock to inform its not interactive
need to CTRL+clic to unlock, as opposed to other handles: this is not perfect but shows the difference
2021-11-10 00:13:57 +01:00
Bruno Herbelin
5bf280ca4d warning on not found pattern 2021-11-10 00:13:08 +01:00
Bruno Herbelin
fe00baa701 Fixed snap to find frei0r plugins
added the package to install and the PATH to find in $SNAP
2021-11-10 00:12:55 +01:00
Bruno Herbelin
d3cb1d7f42 oops 2021-11-08 00:08:19 +01:00
Bruno Herbelin
593363732a Pattern generator improvement
Testing gstreamer feature to provide only available patterns, and added many more patterns to choose from.
2021-11-08 00:05:16 +01:00
Bruno Herbelin
d00f4cf715 Cosmetics
More adapted icons and link to user manual
2021-11-07 12:25:51 +01:00
Bruno Herbelin
cac31dbb21 Help info for mask file open 2021-11-07 12:25:06 +01:00
Bruno Herbelin
eb1fa6ca04 clean file dialog after cancel 2021-11-07 12:24:46 +01:00
Bruno Herbelin
0ac515ea5a Yet more update graphical manual 2021-11-07 01:42:39 +01:00
Bruno Herbelin
190e2a4952 Continue update graphical manual 2021-11-06 22:50:59 +01:00
Bruno Herbelin
0857b1bab6 Update graphical user manual
New screenshots from vimix 6.1
2021-11-06 18:08:52 +01:00
Bruno Herbelin
f3e42fdc95 Bugfix window resize log window 2021-10-31 00:06:08 +02:00
Bruno Herbelin
d617f3308a Added Cancel button to Transition view
And minor code improvements.
2021-10-30 19:57:43 +02:00
Bruno Herbelin
27cec85443 Do not re-open previous session if new session last created 2021-10-26 23:50:26 +02:00
Bruno Herbelin
63f7cab508 Improved gstreamer support for GPU decoding in Linux 2021-10-26 23:38:41 +02:00
Bruno Herbelin
ce0ac1bee1 Minor improvement precision media player gap timing 2021-10-12 23:20:16 +02:00
Bruno Herbelin
2c2584c8df Keyboard shortcut END for Disable output 2021-10-11 23:17:29 +02:00
Bruno Herbelin
14fd4d96c3 Shortcut for output window fullscreen and raise 2021-10-11 22:46:38 +02:00
384 changed files with 29657 additions and 11093 deletions

8
.gitignore vendored
View File

@@ -24,3 +24,11 @@ osx/.DS_Store
.DS_Store
osx/runvimix
*.autosave
flatpak/.flatpak-builder
flatpak/repo/
flatpak/build/

9
.gitmodules vendored
View File

@@ -13,9 +13,12 @@
[submodule "ext/Dirent"]
path = ext/Dirent
url = https://github.com/tronkko/dirent.git
[submodule "ext/tfd"]
path = ext/tfd
url = https://github.com/native-toolkit/tinyfiledialogs.git
[submodule "ext/glm"]
path = ext/glm
url = https://github.com/g-truc/glm.git
[submodule "ext/link"]
path = ext/link
url = https://github.com/Ableton/link.git
[submodule "ext/tfd"]
path = ext/tfd
url = https://git.code.sf.net/p/tinyfiledialogs/code

View File

@@ -1,9 +1,15 @@
#####
##### This file is part of vimix - video live mixer
##### **Copyright** (C) 2019-2022 Bruno Herbelin <bruno.herbelin@gmail.com>
#####
cmake_minimum_required(VERSION 3.8.2)
project(vimix VERSION 0.0.1 LANGUAGES CXX C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# use git
#####
##### Use git to read version from tags
#####
find_package (Git)
if(GIT_EXECUTABLE)
execute_process(
@@ -16,23 +22,36 @@ if(GIT_EXECUTABLE)
if(NOT GIT_DESCRIBE_ERROR_CODE)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 0 1 VIMIX_VERSION_MAJOR)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 2 1 VIMIX_VERSION_MINOR)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 4 1 VIMIX_VERSION_PATCH)
string(FIND ${GIT_DESCRIBE_VERSION} "-" VIMIX_VERSION_LENGTH)
if (VIMIX_VERSION_LENGTH GREATER 4)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 4 1 VIMIX_VERSION_PATCH)
else()
set(VIMIX_VERSION_PATCH "0")
endif()
add_definitions(-DVIMIX_VERSION_MAJOR=${VIMIX_VERSION_MAJOR})
add_definitions(-DVIMIX_VERSION_MINOR=${VIMIX_VERSION_MINOR})
add_definitions(-DVIMIX_VERSION_PATCH=${VIMIX_VERSION_PATCH})
message(STATUS "Compiling vimix version ${VIMIX_VERSION_MAJOR}.${VIMIX_VERSION_MINOR}.${VIMIX_VERSION_PATCH}")
else()
message(STATUS "Compiling vimix (unknown version)")
endif()
endif()
set(CMAKE_INCLUDE_CURRENTDIR ON)
# Find the cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules )
#####
##### Find the cmake modules
#####
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} /usr/share/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules )
include(MacroLogFeature)
include(MacroFindGStreamerLibrary)
#####
##### Configure cmake
#####
set(BUILD_STATIC_LIBS ON)
set(CMAKE_INCLUDE_CURRENTDIR ON)
if(UNIX)
if (APPLE)
add_definitions(-DAPPLE)
@@ -43,12 +62,21 @@ if(UNIX)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
# CPACK
set(CPACK_SYSTEM_NAME "OSX_${CMAKE_OSX_DEPLOYMENT_TARGET}_${CMAKE_OSX_ARCHITECTURES}")
set(CPACK_GENERATOR DragNDrop)
set(CPACK_BINARY_DRAGNDROP ON)
set(APPLE_CODESIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/osx/entitlements.plist")
# find icu4c in OSX (pretty well hidden...)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/icu4c/lib/pkgconfig")
else()
add_definitions(-DLINUX)
# CPACK
set(CPACK_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}")
# linux opengl
set(OpenGL_GL_PREFERENCE "GLVND")
@@ -63,23 +91,26 @@ elseif(WIN32)
add_definitions(-DMINGW32)
endif()
#####
##### Dependencies
#####
#
# Basics
#
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
find_package(GLIB2)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org" TRUE)
find_package(GObject)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org" TRUE)
find_package(PNG REQUIRED)
macro_log_feature(PNG_FOUND "PNG" "Portable Network Graphics" "http://www.libpng.org" TRUE)
find_package(ZLIB REQUIRED)
#
# GSTREAMER
#
find_package(GLIB2 REQUIRED)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org" TRUE)
find_package(GObject REQUIRED)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org" TRUE)
find_package(GStreamer 1.0.0 COMPONENTS base)
macro_log_feature(GSTREAMER_FOUND "GStreamer"
@@ -105,6 +136,17 @@ macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer o
# Various preprocessor definitions for GST
add_definitions(-DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
include_directories(
${GLIB2_INCLUDE_DIR}
${GSTREAMER_INCLUDE_DIR}
${GSTREAMER_AUDIO_INCLUDE_DIR}
${GSTREAMER_VIDEO_INCLUDE_DIR}
${GSTREAMER_BASE_INCLUDE_DIR}
${GSTREAMER_APP_INCLUDE_DIR}
${GSTREAMER_PBUTILS_INCLUDE_DIR}
${GSTREAMER_GL_INCLUDE_DIR}
)
#
# ICU4C
#
@@ -113,8 +155,17 @@ if (PKG_CONFIG_FOUND)
else ()
find_package(ICU REQUIRED COMPONENTS i18n io uc)
endif ()
macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http://site.icu-project.org" TRUE)
include_directories(
${ICU_INCLUDE_DIRS}
)
link_directories(
${ICU_LIBRARY_DIRS}
)
#
# GLFW3
#
@@ -123,30 +174,148 @@ if (PKG_CONFIG_FOUND)
else ()
find_package(glfw3 3.2 REQUIRED)
endif()
macro_log_feature(GLFW3_FOUND "glfw3" "Open Source multi-platform library for OpenGL" "http://www.glfw.org" TRUE)
include_directories(
${GLFW3_INCLUDE_DIRS}
)
macro_display_feature_log()
# static sub packages in ext
set(BUILD_STATIC_LIBS ON)
link_directories(
${GLFW3_LIBRARY_DIRS}
)
#
# GLM
#
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
message(STATUS "Compiling 'GLM' OpenGL mathematics https://glm.g-truc.net -- ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm")
if (PKG_CONFIG_FOUND)
pkg_check_modules(GLM QUIET glm>=0.9.9)
else ()
find_package(glm 0.9.9 QUIET)
endif()
if (GLM_FOUND)
macro_log_feature(GLM_FOUND "GLM" "OpenGL mathematics" "https://glm.g-truc.net" TRUE)
else ()
set(GLM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
message(STATUS "Compiling 'GLM' OpenGL mathematics https://glm.g-truc.net -- ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm")
endif()
include_directories(
${GLM_INCLUDE_DIRS}
)
#
# TINY XML 2
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(TINYXML2 QUIET tinyxml2>=8.0)
else ()
find_package(tinyxml2 8.0 QUIET)
endif()
if (TINYXML2_FOUND)
macro_log_feature(TINYXML2_FOUND "TinyXML2" "TinyXML2 library" "https://github.com/leethomason/tinyxml2.git" TRUE)
else ()
set(TINYXML2_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2)
set(TINYXML2_LIBRARIES TINYXML2)
add_library(TINYXML2 "${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2/tinyxml2.cpp")
message(STATUS "Compiling 'TinyXML2' from https://github.com/leethomason/tinyxml2.git -- ${TINYXML2_INCLUDE_DIRS}")
endif()
include_directories(
${TINYXML2_INCLUDE_DIRS}
)
#
# STB
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(STB QUIET stb)
else ()
find_package(stb QUIET)
endif()
if (STB_FOUND)
macro_log_feature(STB_FOUND "STB" "single-file image and audio processing" "https://github.com/nothings/stb" TRUE)
else ()
set(STB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/stb)
message(STATUS "Including 'STB' single-file image and audio processing from https://github.com/nothings/stb -- ${STB_INCLUDE_DIRS}")
endif()
include_directories(
${STB_INCLUDE_DIRS}
)
#
# Ableton LINK
#
find_package(AbletonLink QUIET)
if (AbletonLink_FOUND)
macro_log_feature(AbletonLink_FOUND "AbletonLink" "Ableton Link synchronizer" "https://github.com/Ableton/link" TRUE)
else ()
include(${CMAKE_CURRENT_SOURCE_DIR}/ext/link/AbletonLinkConfig.cmake)
message(STATUS "Compiling 'Ableton Link' from https://github.com/Ableton/link -- ${CMAKE_CURRENT_SOURCE_DIR}/ext/link")
endif()
include_directories(
${link_HEADERS}
)
#
# FILE DIALOG: use tinyfiledialog for all except Linux
#
if(APPLE OR WIN32)
set(TINYFD_LIBRARIES TINYFD)
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
include_directories(
${TINYFD_INCLUDE_DIR}
)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://git.code.sf.net/p/tinyfiledialogs/code -- ${TINYFD_INCLUDE_DIR}.")
endif()
#
# DIRENT (windows only)
if(WIN32)
set(DIRENT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/Dirent/include)
include_directories(
${DIRENT_INCLUDE_DIR}
)
message(STATUS "Including 'Dirent' from https://github.com/tronkko/dirent -- ${DIRENT_INCLUDE_DIR}.")
endif()
# show message about found libs
macro_display_feature_log()
#####
##### Locally built libraries
#####
#
# GLAD
#
set(GLAD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/include)
set(GLAD_LIBRARIES GLAD)
set(GLAD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/include)
include_directories(
${GLAD_INCLUDE_DIRS}
)
add_library(GLAD "${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/src/glad.c")
message(STATUS "Compiling 'GLAD' Open source multi-language OpenGL loader https://glad.dav1d.de -- ${GLAD_INCLUDE_DIR}")
message(STATUS "Including 'GLAD' Open source multi-language OpenGL loader https://glad.dav1d.de -- ${GLAD_INCLUDE_DIRS}")
#
# DEAR IMGUI
#
set(IMGUI_LIBRARIES IMGUI IMGUITEXTEDIT)
set(IMGUI_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui)
set(IMGUI_BACKEND_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples)
include_directories(
${IMGUI_INCLUDE_DIRS}
${IMGUI_BACKEND_INCLUDE_DIRS}
)
set(IMGUI_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/imgui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_demo.cpp
@@ -154,18 +323,23 @@ set(IMGUI_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_widgets.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_glfw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_opengl3.cpp
)
set(IMGUI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui)
)
add_library(IMGUI "${IMGUI_SRCS}")
target_compile_definitions(IMGUI PRIVATE "IMGUI_IMPL_OPENGL_LOADER_GLAD")
message(STATUS "Compiling 'Dear ImGui' from https://github.com/ocornut/imgui.git -- ${IMGUI_INCLUDE_DIR}")
target_compile_definitions(IMGUI PRIVATE "IMGUI_USE_STB_SPRINTF")
message(STATUS "Compiling 'Dear ImGui' from https://github.com/ocornut/imgui.git -- ${IMGUI_INCLUDE_DIRS}")
#
# TINY XML 2
# ImGui Color Text Editor
#
set(TINYXML2_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2)
add_library(TINYXML2 "${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2/tinyxml2.cpp")
message(STATUS "Compiling 'TinyXML2' from https://github.com/leethomason/tinyxml2.git -- ${TINYXML2_INCLUDE_DIR}")
set(IMGUITEXTEDIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit)
include_directories(
${IMGUITEXTEDIT_INCLUDE_DIR}
)
add_library(IMGUITEXTEDIT "${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit/TextEditor.cpp")
set_property(TARGET IMGUITEXTEDIT PROPERTY CXX_STANDARD 17)
message(STATUS "Compiling 'ImGuiColorTextEdit' from https://github.com/BalazsJako/ImGuiColorTextEdit -- ${IMGUITEXTEDIT_INCLUDE_DIR}")
#
# OSCPack
@@ -184,154 +358,94 @@ set(OSCPACK_SRCS
${OSCPACK_PLATFORM_DIR}/NetworkingUtils.cpp
${OSCPACK_PLATFORM_DIR}/UdpSocket.cpp
)
set(OSCPACK_LIBRARIES OSCPACK)
set(OSCPACK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack)
include_directories(
${OSCPACK_INCLUDE_DIR}
)
add_library(OSCPACK "${OSCPACK_SRCS}")
message(STATUS "Compiling 'OSCPack' from http://www.rossbencina.com/code/oscpack -- ${OSCPACK_INCLUDE_DIR}")
#####
##### Ressources
#####
set(RSC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rsc)
#
# FILE DIALOG: use tinyfiledialog for all except Linux
# Fonts
#
if(UNIX)
if (APPLE)
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
set(TINYFD_LIBRARY TINYFD)
endif()
else()
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
set(TINYFD_LIBRARY TINYFD)
file(GLOB_RECURSE ROBOTO_REGULAR "${RSC_DIR}/*/Roboto-Regular.ttf")
if(NOT ROBOTO_REGULAR)
file(GLOB_RECURSE ROBOTO_REGULAR "/usr/share/fonts/*/Roboto-Regular.ttf")
message(STATUS "Copy ${ROBOTO_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_REGULAR "${RSC_DIR}/fonts/Roboto-Regular.ttf")
endif()
#
# ImGui Color Text Editor
#
set(IMGUITEXTEDIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit)
set(IMGUITEXTEDIT_SRC
${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit/TextEditor.cpp
)
message(STATUS "Including 'ImGuiColorTextEdit' from https://github.com/BalazsJako/ImGuiColorTextEdit -- ${IMGUITEXTEDIT_INCLUDE_DIR}")
#
# STB
#
set(STB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/stb)
add_definitions(-DIMGUI_USE_STB_SPRINTF)
message(STATUS "Including 'STB Nothings' from https://github.com/nothings/stb -- ${STB_INCLUDE_DIR}")
#
# DIRENT (windows only)
if(WIN32)
set(DIRENT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/Dirent/include)
message(STATUS "Including 'Dirent' from https://github.com/tronkko/dirent -- ${DIRENT_INCLUDE_DIR}.")
file(GLOB_RECURSE ROBOTO_BOLD "${RSC_DIR}/*/Roboto-Bold.ttf")
if(NOT ROBOTO_BOLD)
file(GLOB_RECURSE ROBOTO_BOLD "/usr/share/fonts/*/Roboto-Bold.ttf")
message(STATUS "Copy ${ROBOTO_BOLD} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_BOLD} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_BOLD "${RSC_DIR}/fonts/Roboto-Bold.ttf")
endif()
#
# Application
#
file(GLOB_RECURSE ROBOTO_ITALIC "${RSC_DIR}/*/Roboto-Italic.ttf")
if(NOT ROBOTO_ITALIC)
file(GLOB_RECURSE ROBOTO_ITALIC "/usr/share/fonts/*/Roboto-Italic.ttf")
message(STATUS "Copy ${ROBOTO_ITALIC} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_ITALIC} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_ITALIC "${RSC_DIR}/fonts/Roboto-Italic.ttf")
endif()
file(GLOB_RECURSE HACK_REGULAR "${RSC_DIR}/*/Hack-Regular.ttf")
if(NOT HACK_REGULAR)
file(GLOB_RECURSE HACK_REGULAR "/usr/share/fonts/*/Hack-Regular.ttf")
message(STATUS "Copy ${HACK_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${HACK_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(HACK_REGULAR "${RSC_DIR}/fonts/Hack-Regular.ttf")
endif()
file(GLOB_RECURSE AWESOME_SOLID "${RSC_DIR}/*/fa-solid-900.ttf")
if(NOT AWESOME_SOLID)
file(GLOB_RECURSE AWESOME_SOLID "/usr/share/fonts/*/fa-solid-900.ttf")
message(STATUS "Copy ${AWESOME_SOLID} to ${RSC_DIR}/fonts")
file(COPY ${AWESOME_SOLID} DESTINATION ${RSC_DIR}/fonts)
set(AWESOME_SOLID "${RSC_DIR}/fonts/fa-solid-900.ttf")
endif()
file(GLOB_RECURSE AWESOME_REGULAR "${RSC_DIR}/*/fa-regular-400.ttf")
if(NOT AWESOME_REGULAR)
file(GLOB_RECURSE AWESOME_REGULAR "/usr/share/fonts/*/fa-regular-400.ttf")
message(STATUS "Copy ${AWESOME_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${AWESOME_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(AWESOME_REGULAR "${RSC_DIR}/fonts/fa-regular-400.ttf")
endif()
# Setup the environment
include_directories(
${GSTREAMER_INCLUDE_DIR}
${GSTREAMER_AUDIO_INCLUDE_DIR}
${GSTREAMER_VIDEO_INCLUDE_DIR}
${GSTREAMER_BASE_INCLUDE_DIR}
${GSTREAMER_APP_INCLUDE_DIR}
${GSTREAMER_PBUTILS_INCLUDE_DIR}
${GSTREAMER_GL_INCLUDE_DIR}
${GLFW3_INCLUDE_DIRS}
${ICU_INCLUDE_DIRS}
${GLM_INCLUDE_DIRS}
${GLIB2_INCLUDE_DIR}
${GLAD_INCLUDE_DIR}
${IMGUI_INCLUDE_DIR}
${IMGUI_INCLUDE_DIR}/examples
${IMGUITEXTEDIT_INCLUDE_DIR}
${TINYXML2_INCLUDE_DIR}
${TINYFD_INCLUDE_DIR}
${STB_INCLUDE_DIR}
${DIRENT_INCLUDE_DIR}
${OSCPACK_INCLUDE_DIR}
)
link_directories(
${GLFW3_LIBRARY_DIRS}
${ICU_LIBRARY_DIRS}
"${RSC_DIR}/fonts"
)
set(VMIX_BINARY "vimix")
set(VMIX_SRCS
main.cpp
Log.cpp
BaseToolkit.cpp
Shader.cpp
ImageShader.cpp
ImageProcessingShader.cpp
UpdateCallback.cpp
Scene.cpp
Primitives.cpp
Mesh.cpp
Decorations.cpp
View.cpp
RenderView.cpp
GeometryView.cpp
MixingView.cpp
MixingGroup.cpp
LayerView.cpp
TextureView.cpp
TransitionView.cpp
Source.cpp
SourceList.cpp
Session.cpp
Selection.cpp
SessionSource.cpp
SessionVisitor.cpp
Interpolator.cpp
SessionCreator.cpp
SessionParser.cpp
Mixer.cpp
FrameGrabber.cpp
Recorder.cpp
Streamer.cpp
Loopback.cpp
Settings.cpp
Screenshot.cpp
Resource.cpp
Timeline.cpp
Stream.cpp
MediaPlayer.cpp
MediaSource.cpp
StreamSource.cpp
PatternSource.cpp
DeviceSource.cpp
NetworkSource.cpp
MultiFileSource.cpp
FrameBuffer.cpp
RenderingManager.cpp
UserInterfaceManager.cpp
PickingVisitor.cpp
BoundingBoxVisitor.cpp
DrawVisitor.cpp
SearchVisitor.cpp
ImGuiToolkit.cpp
ImGuiVisitor.cpp
InfoVisitor.cpp
GstToolkit.cpp
GlmToolkit.cpp
SystemToolkit.cpp
DialogToolkit.cpp
tinyxml2Toolkit.cpp
NetworkToolkit.cpp
Connection.cpp
ActionManager.cpp
Overlay.cpp
)
#
# CMake RC module
#
# Include the CMake RC module
include(CMakeRC)
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
# set the files to package
set(VMIX_RSC_FILES
${ROBOTO_REGULAR}
${ROBOTO_BOLD}
${ROBOTO_ITALIC}
${HACK_REGULAR}
${AWESOME_REGULAR}
${AWESOME_SOLID}
./rsc/shaders/simple.fs
./rsc/shaders/simple.vs
./rsc/shaders/image.fs
@@ -344,12 +458,6 @@ set(VMIX_RSC_FILES
./rsc/shaders/image.vs
./rsc/shaders/imageprocessing.fs
./rsc/shaders/imageblending.fs
./rsc/fonts/Hack-Regular.ttf
./rsc/fonts/Roboto-Regular.ttf
./rsc/fonts/Roboto-Bold.ttf
./rsc/fonts/Roboto-Italic.ttf
./rsc/fonts/fa-regular-400.ttf
./rsc/fonts/fa-solid-900.ttf
./rsc/images/mask_vignette.png
./rsc/images/mask_halo.png
./rsc/images/mask_glow.png
@@ -360,6 +468,7 @@ set(VMIX_RSC_FILES
./rsc/images/mask_linear_left.png
./rsc/images/mask_linear_right.png
./rsc/images/vimix_256x256.png
./rsc/images/vimix_crow_white.png
./rsc/images/icons.dds
./rsc/images/gradient_0_cross_linear.png
./rsc/images/gradient_1_black_linear.png
@@ -404,6 +513,7 @@ set(VMIX_RSC_FILES
./rsc/mesh/shadow_perspective.ply
./rsc/mesh/point.ply
./rsc/mesh/square_point.ply
./rsc/mesh/triangle_point.ply
./rsc/mesh/icon_video.ply
./rsc/mesh/icon_image.ply
./rsc/mesh/icon_render.ply
@@ -431,89 +541,61 @@ set(VMIX_RSC_FILES
./rsc/mesh/icon_vector_square_slash.ply
./rsc/mesh/icon_cube.ply
./rsc/mesh/icon_sequence.ply
./rsc/mesh/icon_receive.ply
./rsc/mesh/h_line.ply
./rsc/mesh/h_mark.ply
./rsc/shaders/filters/default.glsl
./rsc/shaders/filters/bloom.glsl
./rsc/shaders/filters/bokeh.glsl
./rsc/shaders/filters/talk.glsl
./rsc/shaders/filters/fisheye.glsl
./rsc/shaders/filters/blur.glsl
./rsc/shaders/filters/blur_1.glsl
./rsc/shaders/filters/blur_2.glsl
./rsc/shaders/filters/lens_1.glsl
./rsc/shaders/filters/lens_2.glsl
./rsc/shaders/filters/hashedblur.glsl
./rsc/shaders/filters/circularblur.glsl
./rsc/shaders/filters/hashederosion.glsl
./rsc/shaders/filters/hasheddilation.glsl
./rsc/shaders/filters/sharp.glsl
./rsc/shaders/filters/sharpen.glsl
./rsc/shaders/filters/sharpen_1.glsl
./rsc/shaders/filters/sharpen_2.glsl
./rsc/shaders/filters/contour_2.glsl
./rsc/shaders/filters/sharpenedge.glsl
./rsc/shaders/filters/chromakey.glsl
./rsc/shaders/filters/lumakey.glsl
./rsc/shaders/filters/coloralpha.glsl
./rsc/shaders/filters/bilinear.glsl
./rsc/shaders/filters/edge.glsl
./rsc/shaders/filters/sobel.glsl
./rsc/shaders/filters/freichen.glsl
./rsc/shaders/filters/kuwahara.glsl
./rsc/shaders/filters/pixelate.glsl
./rsc/shaders/filters/focus.glsl
./rsc/shaders/filters/denoise.glsl
./rsc/shaders/filters/noise.glsl
./rsc/shaders/filters/grain.glsl
./rsc/shaders/filters/stippling.glsl
./rsc/shaders/filters/dithering.glsl
./rsc/shaders/filters/erosion.glsl
./rsc/shaders/filters/dilation.glsl
./rsc/shaders/filters/tophat.glsl
./rsc/shaders/filters/blackhat.glsl
./rsc/shaders/filters/resample_double.glsl
./rsc/shaders/filters/resample_half.glsl
./rsc/shaders/filters/resample_quarter.glsl
./rsc/shaders/filters/earlybird.glsl
./rsc/shaders/filters/logo.glsl
)
# Include the CMake RC module
include(CMakeRC)
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES})
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
### DEFINE THE TARGET (OS specific)
IF(APPLE)
# set icon
set(MACOSX_BUNDLE_ICON vimix.icns)
set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/osx/${MACOSX_BUNDLE_ICON})
# set where in the bundle to put the icns file
set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# create the application
add_executable(${VMIX_BINARY} MACOSX_BUNDLE
${VMIX_SRCS}
${IMGUITEXTEDIT_SRC}
${MACOSX_BUNDLE_ICON_FILE}
)
# set the Info.plist file
set(MACOSX_BUNDLE_PLIST_FILE ${CMAKE_SOURCE_DIR}/osx/Info.plist)
set_target_properties(${VMIX_BINARY} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_PLIST_FILE})
set(PLATFORM_LIBS
"-framework CoreFoundation"
"-framework Appkit"
)
ELSE(APPLE)
link_directories (${GTK3_LIBRARY_DIRS})
add_executable(${VMIX_BINARY}
${VMIX_SRCS}
${IMGUITEXTEDIT_SRC}
)
set(PLATFORM_LIBS
GTK::GTK
)
ENDIF(APPLE)
### COMPILE THE TARGET (all OS)
set_property(TARGET ${VMIX_BINARY} PROPERTY CXX_STANDARD 17)
set_property(TARGET ${VMIX_BINARY} PROPERTY C_STANDARD 11)
target_compile_definitions(${VMIX_BINARY} PUBLIC "IMGUI_IMPL_OPENGL_LOADER_GLAD")
target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
vmix::rc
glm::glm
GLAD
TINYXML2
IMGUI
OSCPACK
${TINYFD_LIBRARY}
${GLFW3_LIBRARIES}
${ICU_LIBRARIES}
${CMAKE_DL_LIBS}
${GOBJECT_LIBRARIES}
${GSTREAMER_LIBRARY}
${GSTREAMER_BASE_LIBRARY}
${GSTREAMER_APP_LIBRARY}
${GSTREAMER_AUDIO_LIBRARY}
${GSTREAMER_VIDEO_LIBRARY}
${GSTREAMER_PBUTILS_LIBRARY}
${GSTREAMER_GL_LIBRARY}
Threads::Threads
PNG::PNG
${PLATFORM_LIBS}
)
### DEFINE THE PACKAGING (all OS)
#####
##### DEFINE THE PACKAGING (all OS)
#####
SET(CPACK_PACKAGE_NAME "vimix")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "vimix\nReal-time video mixing for live performance.")
@@ -530,120 +612,15 @@ SET(CPACK_SOURCE_IGNORE_FILES
"/\\\\.gitignore$"
"/\\\\.gitmodules$"
)
# optimize size ?
SET(CPACK_STRIP_FILES TRUE)
### DEFINE THE PACKAGING (OS specific)
IF(APPLE)
# Bundle target
set(CPACK_GENERATOR DragNDrop)
set(CPACK_BINARY_DRAGNDROP ON)
# OSX cpack info
set(CPACK_SYSTEM_NAME "OSX_${CMAKE_OSX_DEPLOYMENT_TARGET}_${CMAKE_OSX_ARCHITECTURES}")
install(TARGETS ${VMIX_BINARY}
CONFIGURATIONS Release RelWithDebInfo
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime
)
# create GST plugins directory in Bundle Resources subfolder
set(plugin_dest_dir vimix.app/Contents/Resources/)
### TODO configure auto to find installation dir of gst
message(STATUS "install gst-plugins ${PKG_GSTREAMER_PLUGIN_DIR}")
message(STATUS "install gst-plugins-base ${PKG_GSTREAMER_BASE_PLUGIN_DIR}")
if (PKG_CONFIG_FOUND)
pkg_check_modules(PKG_GSTREAMER_PLUGINS_BAD gstreamer-plugins-bad-${GSTREAMER_ABI_VERSION})
set(PKG_GSTREAMER_BAD_PLUGIN_DIR ${PKG_GSTREAMER_PLUGINS_BAD_LIBDIR}/gstreamer-${GSTREAMER_ABI_VERSION})
message(STATUS "install gst-plugins-bad ${PKG_GSTREAMER_BAD_PLUGIN_DIR}")
endif()
# intall the gst-plugin-scanner program (used by plugins at load time)
set(PKG_GSTREAMER_SCANNER "${PKG_GSTREAMER_PREFIX}/libexec/gstreamer-1.0/gst-plugin-scanner")
message(STATUS "install gst-plugin-scanner ${PKG_GSTREAMER_SCANNER}")
install(FILES "${PKG_GSTREAMER_SCANNER}"
DESTINATION "${plugin_dest_dir}"
PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
COMPONENT Runtime
)
# Install the gst-plugins (all those installed with brew )
install(DIRECTORY "${PKG_GSTREAMER_PLUGIN_DIR}" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "${PKG_GSTREAMER_BASE_PLUGIN_DIR}" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "${PKG_GSTREAMER_BAD_PLUGIN_DIR}" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-good/1.18.4/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-ugly/1.18.4_1/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-libav/1.18.4/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
# install locally recompiled & installed gst-plugins (because not included in brew package)
install(FILES "/usr/local/lib/gstreamer-1.0/libgstapplemedia.dylib" DESTINATION "${plugin_dest_dir}/gstreamer-1.0" COMPONENT Runtime)
install(FILES "/usr/local/lib/gstreamer-1.0/libgstde265.dylib" DESTINATION "${plugin_dest_dir}/gstreamer-1.0" COMPONENT Runtime)
install(FILES "/usr/local/lib/gstreamer-1.0/libgstx265.dylib" DESTINATION "${plugin_dest_dir}/gstreamer-1.0" COMPONENT Runtime)
# ICU DATA LIB GST dependency : undocumented and hacked here : seems to work
# install(FILES "${ICU_LINK_LIBRARIES}" DESTINATION "${plugin_dest_dir}/gstreamer-1.0" COMPONENT Runtime)
install(FILES "/usr/local/Cellar/icu4c/69.1/lib/libicudata.69.1.dylib" DESTINATION "${plugin_dest_dir}/gstreamer-1.0" RENAME "libicudata.69.dylib" COMPONENT Runtime)
message(STATUS "install ${ICU_LINK_LIBRARIES} from ${ICU_LIBRARY_DIRS}")
# package runtime fixup bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/vimix.app")
install(CODE "
file(GLOB_RECURSE GSTPLUGINS \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/gstreamer-1.0/*.dylib\")
list(APPEND LIBS_PATH \"\${ICU_LIBRARY_DIRS}\")
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
fixup_bundle(\"${APPS}\" \"\${GSTPLUGINS}\" \"${LIBS_PATH}\")
"
COMPONENT Runtime
)
set(APPLE_CODESIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/osx/entitlements.plist")
set(APPLE_CODESIGN_IDENTITY "" CACHE STRING "")
string(LENGTH "${APPLE_CODESIGN_IDENTITY}" APPLE_CODESIGN_IDENTITY_LENGHT)
if( ${APPLE_CODESIGN_IDENTITY_LENGHT} LESS 40 )
message(STATUS "Not signing bundle. Specify APPLE_CODESIGN_IDENTITY to cmake before running cpack to sign")
else()
install(CODE "
execute_process(COMMAND
codesign --verbose=4 --deep --force
--entitlements \"${APPLE_CODESIGN_ENTITLEMENTS}\"
--sign \"${APPLE_CODESIGN_IDENTITY}\"
\"${APPS}\" )
"
COMPONENT Runtime
)
endif()
# # package runtime fixup bundle and codesign
# set(BUNDLE_NAME "vimix.app")
# set(BUNDLE_LIBS_DIR "${plugin_dest_dir}/gstreamer-1.0")
# set(BUNDLE_DIRS "${ICU_LIBRARY_DIRS}")
# set(APPLE_CODESIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/osx/entitlements.plist")
# configure_file(cmake/modules/BundleInstall.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/BundleInstall.cmake" @ONLY)
# install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/BundleInstall.cmake" COMPONENT Runtime)
ELSE(APPLE)
install(TARGETS ${VMIX_BINARY}
CONFIGURATIONS Release RelWithDebInfo
RUNTIME DESTINATION bin COMPONENT Runtime
)
ENDIF(APPLE)
# Package full name
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_SYSTEM_NAME}")
set(CPACK_STRIP_FILES TRUE)
#####
##### Build Application
#####
add_subdirectory(src)
# To Create a package, run "cpack"
include(CPack)

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -1,581 +0,0 @@
#include <algorithm>
#include <sstream>
#include <glm/gtc/matrix_transform.hpp>
#include <gst/pbutils/gstdiscoverer.h>
#include <gst/pbutils/pbutils.h>
#include <gst/gst.h>
#include "DeviceSource.h"
#include "defines.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "Resource.h"
#include "Decorations.h"
#include "Stream.h"
#include "Visitor.h"
#include "Log.h"
#ifndef NDEBUG
#define DEVICE_DEBUG
//#define GST_DEVICE_DEBUG
#endif
#if defined(APPLE)
std::string gst_plugin_device = "avfvideosrc";
std::string gst_plugin_vidcap = "avfvideosrc capture-screen=true";
#else
std::string gst_plugin_device = "v4l2src";
std::string gst_plugin_vidcap = "ximagesrc";
#endif
////EXAMPLE :
///
//v4l2deviceprovider, udev-probed=(boolean)true,
//device.bus_path=(string)pci-0000:00:14.0-usb-0:2:1.0,
//sysfs.path=(string)/sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/video4linux/video0,
//device.bus=(string)usb,
//device.subsystem=(string)video4linux,
//device.vendor.id=(string)1bcf,
//device.vendor.name=(string)"Sunplus\\x20IT\\x20Co\\x20",
//device.product.id=(string)2286,
//device.product.name=(string)"AUSDOM\ FHD\ Camera:\ AUSDOM\ FHD\ C",
//device.serial=(string)Sunplus_IT_Co_AUSDOM_FHD_Camera,
//device.capabilities=(string):capture:,
//device.api=(string)v4l2,
//device.path=(string)/dev/video0,
//v4l2.device.driver=(string)uvcvideo,
//v4l2.device.card=(string)"AUSDOM\ FHD\ Camera:\ AUSDOM\ FHD\ C",
//v4l2.device.bus_info=(string)usb-0000:00:14.0-2,
//v4l2.device.version=(uint)328748,
//v4l2.device.capabilities=(uint)2225078273,
//v4l2.device.device_caps=(uint)69206017;
//Device added: AUSDOM FHD Camera: AUSDOM FHD C - v4l2src device=/dev/video0
//v4l2deviceprovider, udev-probed=(boolean)true,
//device.bus_path=(string)pci-0000:00:14.0-usb-0:4:1.0,
//sysfs.path=(string)/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/video4linux/video2,
//device.bus=(string)usb,
//device.subsystem=(string)video4linux,
//device.vendor.id=(string)046d,
//device.vendor.name=(string)046d,
//device.product.id=(string)080f,
//device.product.name=(string)"UVC\ Camera\ \(046d:080f\)",
//device.serial=(string)046d_080f_3EA77580,
//device.capabilities=(string):capture:,
//device.api=(string)v4l2,
//device.path=(string)/dev/video2,
//v4l2.device.driver=(string)uvcvideo,
//v4l2.device.card=(string)"UVC\ Camera\ \(046d:080f\)",
//v4l2.device.bus_info=(string)usb-0000:00:14.0-4,
//v4l2.device.version=(uint)328748,
//v4l2.device.capabilities=(uint)2225078273,
//v4l2.device.device_caps=(uint)69206017; // decimal of hexadecimal v4l code Device Caps : 0x04200001
//Device added: UVC Camera (046d:080f) - v4l2src device=/dev/video2
std::string pipelineForDevice(GstDevice *device, uint index)
{
std::ostringstream pipe;
const gchar *str = gst_structure_get_string(gst_device_get_properties(device), "device.api");
if (str && gst_plugin_device.find(str) != std::string::npos)
{
pipe << gst_plugin_device;
#if defined(APPLE)
pipe << " device-index=" << index;
#else
str = gst_structure_get_string(gst_device_get_properties(device), "device.path");
if (str)
pipe << " device=" << str;
#endif
}
return pipe.str();
}
gboolean
Device::callback_device_monitor (GstBus *, GstMessage * message, gpointer )
{
GstDevice *device;
gchar *name;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_DEVICE_ADDED: {
gst_message_parse_device_added (message, &device);
name = gst_device_get_display_name (device);
// ignore if already in the list
if ( std::find(manager().src_name_.begin(), manager().src_name_.end(), name) != manager().src_name_.end())
break;
manager().src_name_.push_back(name);
#ifdef GST_DEVICE_DEBUG
gchar *stru = gst_structure_to_string( gst_device_get_properties(device) );
g_print("\nDevice %s plugged : %s\n", name, stru);
g_free (stru);
#endif
g_free (name);
std::string p = pipelineForDevice(device, manager().src_description_.size());
manager().src_description_.push_back(p);
DeviceConfigSet confs = getDeviceConfigs(p);
manager().src_config_.push_back(confs);
manager().list_uptodate_ = false;
gst_object_unref (device);
}
break;
case GST_MESSAGE_DEVICE_REMOVED: {
gst_message_parse_device_removed (message, &device);
name = gst_device_get_display_name (device);
manager().remove(name);
#ifdef GST_DEVICE_DEBUG
g_print("\nDevice %s unplugged\n", name);
#endif
g_free (name);
manager().list_uptodate_ = false;
gst_object_unref (device);
}
break;
default:
break;
}
return G_SOURCE_CONTINUE;
}
void Device::remove(const char *device)
{
std::vector< std::string >::iterator nameit = src_name_.begin();
std::vector< std::string >::iterator descit = src_description_.begin();
std::vector< DeviceConfigSet >::iterator coit = src_config_.begin();
while (nameit != src_name_.end()){
if ( (*nameit).compare(device) == 0 )
{
src_name_.erase(nameit);
src_description_.erase(descit);
src_config_.erase(coit);
break;
}
++nameit;
++descit;
++coit;
}
}
Device::Device()
{
GstBus *bus;
GstCaps *caps;
// create GStreamer device monitor to capture
// when a device is plugged in or out
monitor_ = gst_device_monitor_new ();
bus = gst_device_monitor_get_bus (monitor_);
gst_bus_add_watch (bus, callback_device_monitor, NULL);
gst_object_unref (bus);
caps = gst_caps_new_empty_simple ("video/x-raw");
gst_device_monitor_add_filter (monitor_, "Video/Source", caps);
gst_caps_unref (caps);
gst_device_monitor_set_show_all_devices(monitor_, true);
gst_device_monitor_start (monitor_);
// initial fill of the list
GList *devices = gst_device_monitor_get_devices(monitor_);
GList *tmp;
for (tmp = devices; tmp ; tmp = tmp->next ) {
GstDevice *device = (GstDevice *) tmp->data;
gchar *name = gst_device_get_display_name (device);
src_name_.push_back(name);
g_free (name);
#ifdef GST_DEVICE_DEBUG
gchar *stru = gst_structure_to_string( gst_device_get_properties(device) );
g_print("\nDevice %s already plugged : %s", name, stru);
g_free (stru);
#endif
std::string p = pipelineForDevice(device, src_description_.size());
src_description_.push_back(p);
DeviceConfigSet confs = getDeviceConfigs(p);
src_config_.push_back(confs);
}
g_list_free(devices);
// Add config for plugged screen
src_name_.push_back("Screen capture");
src_description_.push_back(gst_plugin_vidcap);
// Try to auto find resolution
DeviceConfigSet confs = getDeviceConfigs(gst_plugin_vidcap);
if (!confs.empty()) {
// fix the framerate (otherwise at 1 FPS
DeviceConfig best = *confs.rbegin();
DeviceConfigSet confscreen;
best.fps_numerator = 15;
confscreen.insert(best);
src_config_.push_back(confscreen);
}
// TODO Use lib glfw to get monitors
// TODO Detect auto removal of monitors
list_uptodate_ = true;
}
int Device::numDevices() const
{
return src_name_.size();
}
bool Device::exists(const std::string &device) const
{
std::vector< std::string >::const_iterator d = std::find(src_name_.begin(), src_name_.end(), device);
return d != src_name_.end();
}
struct hasDevice: public std::unary_function<DeviceSource*, bool>
{
inline bool operator()(const DeviceSource* elem) const {
return (elem && elem->device() == _d);
}
explicit hasDevice(const std::string &d) : _d(d) { }
private:
std::string _d;
};
Source *Device::createSource(const std::string &device) const
{
Source *s = nullptr;
// find if a DeviceSource with this device is already registered
std::list< DeviceSource *>::const_iterator d = std::find_if(device_sources_.begin(), device_sources_.end(), hasDevice(device));
// if already registered, clone the device source
if ( d != device_sources_.end()) {
CloneSource *cs = (*d)->clone();
s = cs;
}
// otherwise, we are free to create a new device source
else {
DeviceSource *ds = new DeviceSource();
ds->setDevice(device);
s = ds;
}
return s;
}
bool Device::unplugged(const std::string &device) const
{
if (list_uptodate_)
return false;
return !exists(device);
}
std::string Device::name(int index) const
{
if (index > -1 && index < (int) src_name_.size())
return src_name_[index];
else
return "";
}
std::string Device::description(int index) const
{
if (index > -1 && index < (int) src_description_.size())
return src_description_[index];
else
return "";
}
DeviceConfigSet Device::config(int index) const
{
if (index > -1 && index < (int) src_config_.size())
return src_config_[index];
else
return DeviceConfigSet();
}
int Device::index(const std::string &device) const
{
int i = -1;
std::vector< std::string >::const_iterator p = std::find(src_name_.begin(), src_name_.end(), device);
if (p != src_name_.end())
i = std::distance(src_name_.begin(), p);
return i;
}
DeviceSource::DeviceSource(uint64_t id) : StreamSource(id)
{
// create stream
stream_ = new Stream;
// set symbol
symbol_ = new Symbol(Symbol::CAMERA, glm::vec3(0.75f, 0.75f, 0.01f));
symbol_->scale_.y = 1.5f;
}
DeviceSource::~DeviceSource()
{
// unregister this device source
Device::manager().device_sources_.remove(this);
}
void DeviceSource::setDevice(const std::string &devicename)
{
device_ = devicename;
Log::Notify("Creating Source with device '%s'", device_.c_str());
int index = Device::manager().index(device_);
if (index > -1) {
// register this device source
Device::manager().device_sources_.push_back(this);
// start filling in the gstreamer pipeline
std::ostringstream pipeline;
pipeline << Device::manager().description(index);
// test the device and get config
DeviceConfigSet confs = Device::manager().config(index);
#ifdef DEVICE_DEBUG
Log::Info("Device %s supported configs:", devicename.c_str());
for( DeviceConfigSet::iterator it = confs.begin(); it != confs.end(); ++it ){
float fps = static_cast<float>((*it).fps_numerator) / static_cast<float>((*it).fps_denominator);
Log::Info(" - %s %s %d x %d %.1f fps", (*it).stream.c_str(), (*it).format.c_str(), (*it).width, (*it).height, fps);
}
#endif
DeviceConfig best = *confs.rbegin();
float fps = static_cast<float>(best.fps_numerator) / static_cast<float>(best.fps_denominator);
Log::Info("Device %s selected its optimal config: %s %s %dx%d@%.1ffps", device_.c_str(), best.stream.c_str(), best.format.c_str(), best.width, best.height, fps);
pipeline << " ! " << best.stream;
if (!best.format.empty())
pipeline << ",format=" << best.format;
pipeline << ",framerate=" << best.fps_numerator << "/" << best.fps_denominator;
pipeline << ",width=" << best.width;
pipeline << ",height=" << best.height;
if ( best.stream.find("jpeg") != std::string::npos )
pipeline << " ! jpegdec";
if ( device_.find("Screen") != std::string::npos )
pipeline << " ! videoconvert ! video/x-raw,format=RGB ! queue max-size-buffers=3";
pipeline << " ! videoconvert";
// resize render buffer
if (renderbuffer_)
renderbuffer_->resize(best.width, best.height);
// open gstreamer
stream_->open( pipeline.str(), best.width, best.height);
stream_->play(true);
// will be ready after init and one frame rendered
ready_ = false;
}
else
Log::Warning("No such device '%s'", device_.c_str());
}
void DeviceSource::accept(Visitor& v)
{
Source::accept(v);
if (!failed())
v.visit(*this);
}
bool DeviceSource::failed() const
{
return stream_->failed() || Device::manager().unplugged(device_);
}
DeviceConfigSet Device::getDeviceConfigs(const std::string &src_description)
{
DeviceConfigSet configs;
// create dummy pipeline to be tested
std::string description = src_description;
description += " name=devsrc ! fakesink name=sink";
// parse pipeline descriptor
GError *error = NULL;
GstElement *pipeline_ = gst_parse_launch (description.c_str(), &error);
if (error != NULL) {
Log::Warning("DeviceSource Could not construct test pipeline %s:\n%s", description.c_str(), error->message);
g_clear_error (&error);
return configs;
}
// get the pipeline element named "devsrc" from the Device class
GstElement *elem = gst_bin_get_by_name (GST_BIN (pipeline_), "devsrc");
if (elem) {
// initialize the pipeline
GstStateChangeReturn ret = gst_element_set_state (pipeline_, GST_STATE_PAUSED);
if (ret != GST_STATE_CHANGE_FAILURE) {
// get the first pad and its content
GstIterator *iter = gst_element_iterate_src_pads(elem);
GValue vPad = G_VALUE_INIT;
GstPad* pad_ret = NULL;
if (gst_iterator_next(iter, &vPad) == GST_ITERATOR_OK)
{
pad_ret = GST_PAD(g_value_get_object(&vPad));
GstCaps *device_caps = gst_pad_query_caps (pad_ret, NULL);
// loop over all caps offered by the pad
int C = gst_caps_get_size(device_caps);
for (int c = 0; c < C; ++c) {
// get GST cap
GstStructure *decice_cap_struct = gst_caps_get_structure (device_caps, c);
#ifdef GST_DEVICE_DEBUG
gchar *capstext = gst_structure_to_string (decice_cap_struct);
g_print("\nDevice caps: %s", capstext);
g_free(capstext);
#endif
// fill our config
DeviceConfig config;
// not managing opengl texture-target types
// TODO: support input devices texture-target video/x-raw(memory:GLMemory) for improved pipeline
if ( gst_structure_has_field (decice_cap_struct, "texture-target"))
continue;
// NAME : typically video/x-raw or image/jpeg
config.stream = gst_structure_get_name (decice_cap_struct);
// FORMAT : typically BGRA or YUVY
if ( gst_structure_has_field (decice_cap_struct, "format")) {
// get generic value
const GValue *val = gst_structure_get_value(decice_cap_struct, "format");
// if its a list of format string
if ( GST_VALUE_HOLDS_LIST(val)) {
int N = gst_value_list_get_size(val);
for (int n = 0; n < N; n++ ){
std::string f = gst_value_serialize( gst_value_list_get_value(val, n) );
// preference order : 1) RGBx, 2) JPEG, 3) ALL OTHER
// select f if it contains R (e.g. for RGBx) and not already RGB in config
if ( (f.find("R") != std::string::npos) && (config.format.find("R") == std::string::npos ) ) {
config.format = f;
break;
}
// default, take at least one if nothing yet in config
else if ( config.format.empty() )
config.format = f;
}
}
// single format
else {
config.format = gst_value_serialize(val);
}
}
// FRAMERATE : can be a fraction of a list of fractions
if ( gst_structure_has_field (decice_cap_struct, "framerate")) {
// get generic value
const GValue *val = gst_structure_get_value(decice_cap_struct, "framerate");
// if its a single fraction
if ( GST_VALUE_HOLDS_FRACTION(val)) {
config.fps_numerator = gst_value_get_fraction_numerator(val);
config.fps_denominator= gst_value_get_fraction_denominator(val);
}
// if its a range of fraction; take the max
else if ( GST_VALUE_HOLDS_FRACTION_RANGE(val)) {
config.fps_numerator = gst_value_get_fraction_numerator(gst_value_get_fraction_range_max(val));
config.fps_denominator= gst_value_get_fraction_denominator(gst_value_get_fraction_range_max(val));
}
// deal otherwise with a list of fractions; find the max
else if ( GST_VALUE_HOLDS_LIST(val)) {
gdouble fps_max = 1.0;
// loop over all fractions
int N = gst_value_list_get_size(val);
for (int i = 0; i < N; ++i ){
const GValue *frac = gst_value_list_get_value(val, i);
// read one fraction in the list
if ( GST_VALUE_HOLDS_FRACTION(frac)) {
int n = gst_value_get_fraction_numerator(frac);
int d = gst_value_get_fraction_denominator(frac);
// keep only the higher FPS
gdouble f = 1.0;
gst_util_fraction_to_double( n, d, &f );
if ( f > fps_max ) {
config.fps_numerator = n;
config.fps_denominator = d;
fps_max = f;
}
}
}
}
}
// WIDTH and HEIGHT
if ( gst_structure_has_field (decice_cap_struct, "width"))
gst_structure_get_int (decice_cap_struct, "width", &config.width);
if ( gst_structure_has_field (decice_cap_struct, "height"))
gst_structure_get_int (decice_cap_struct, "height", &config.height);
// add this config
configs.insert(config);
}
}
gst_iterator_free(iter);
// terminate pipeline
gst_element_set_state (pipeline_, GST_STATE_NULL);
}
g_object_unref (elem);
}
gst_object_unref (pipeline_);
return configs;
}
glm::ivec2 DeviceSource::icon() const
{
if ( device_.find("Screen") != std::string::npos )
return glm::ivec2(19, 1);
else
return glm::ivec2(2, 14);
}

View File

@@ -1,856 +0,0 @@
#include "ImGuiVisitor.h"
#include <vector>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_access.hpp>
#include <tinyxml2.h>
#include "tinyxml2Toolkit.h"
#include "defines.h"
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "MediaPlayer.h"
#include "MediaSource.h"
#include "SessionSource.h"
#include "PatternSource.h"
#include "DeviceSource.h"
#include "NetworkSource.h"
#include "MultiFileSource.h"
#include "SessionCreator.h"
#include "SessionVisitor.h"
#include "Settings.h"
#include "Mixer.h"
#include "ActionManager.h"
#include "imgui.h"
#include "ImGuiToolkit.h"
#include "BaseToolkit.h"
#include "UserInterfaceManager.h"
#include "SystemToolkit.h"
ImGuiVisitor::ImGuiVisitor()
{
}
void ImGuiVisitor::visit(Node &n)
{
}
void ImGuiVisitor::visit(Group &n)
{
// MODEL VIEW
ImGui::PushID(std::to_string(n.id()).c_str());
if (ImGuiToolkit::ButtonIcon(1, 16)) {
n.translation_.x = 0.f;
n.translation_.y = 0.f;
n.rotation_.z = 0.f;
n.scale_.x = 1.f;
n.scale_.y = 1.f;
Action::manager().store("Geometry Reset");
}
ImGui::SameLine(0, 10);
ImGui::Text("Geometry");
if (ImGuiToolkit::ButtonIcon(6, 15)) {
n.translation_.x = 0.f;
n.translation_.y = 0.f;
Action::manager().store("Position 0.0, 0.0");
}
ImGui::SameLine(0, 10);
float translation[2] = { n.translation_.x, n.translation_.y};
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderFloat2("Position", translation, -5.0, 5.0) )
{
n.translation_.x = translation[0];
n.translation_.y = translation[1];
}
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Position " << std::setprecision(3) << n.translation_.x << ", " << n.translation_.y;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(3, 15)) {
n.scale_.x = 1.f;
n.scale_.y = 1.f;
Action::manager().store("Scale 1.0 x 1.0");
}
ImGui::SameLine(0, 10);
float scale[2] = { n.scale_.x, n.scale_.y} ;
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderFloat2("Scale", scale, -MAX_SCALE, MAX_SCALE, "%.2f") )
{
n.scale_.x = CLAMP_SCALE(scale[0]);
n.scale_.y = CLAMP_SCALE(scale[1]);
}
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Scale " << std::setprecision(3) << n.scale_.x << " x " << n.scale_.y;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(18, 9)){
n.rotation_.z = 0.f;
Action::manager().store("Angle 0.0");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderAngle("Angle", &(n.rotation_.z), -180.f, 180.f) ;
if (ImGui::IsItemDeactivatedAfterEdit()) {
std::ostringstream oss;
oss << "Angle " << std::setprecision(3) << n.rotation_.z * 180.f / M_PI;
Action::manager().store(oss.str());
}
ImGui::PopID();
// spacing
ImGui::Spacing();
}
void ImGuiVisitor::visit(Switch &n)
{
if (n.numChildren()>0)
n.activeChild()->accept(*this);
}
void ImGuiVisitor::visit(Scene &n)
{
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
if (ImGui::CollapsingHeader("Scene Property Tree"))
{
n.root()->accept(*this);
}
}
void ImGuiVisitor::visit(Primitive &n)
{
ImGui::PushID(std::to_string(n.id()).c_str());
ImGui::Text("Primitive %d");
n.shader()->accept(*this);
ImGui::PopID();
}
void ImGuiVisitor::visit(FrameBufferSurface &n)
{
ImGui::Text("Framebuffer");
}
void ImGuiVisitor::visit(MediaPlayer &n)
{
ImGui::Text("Media Player");
}
void ImGuiVisitor::visit(Shader &n)
{
ImGui::PushID(std::to_string(n.id()).c_str());
// Base color
// if (ImGuiToolkit::ButtonIcon(10, 2)) {
// n.blending = Shader::BLEND_OPACITY;
// n.color = glm::vec4(1.f, 1.f, 1.f, 1.f);
// }
// ImGui::SameLine(0, 10);
// ImGui::ColorEdit3("Color", glm::value_ptr(n.color), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel ) ;
// ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
int mode = n.blending;
if (ImGui::Combo("Blending", &mode, "Normal\0Screen\0Subtract\0Multiply\0Soft light"
"\0Hard light\0Soft subtract\0Lighten only\0") ) {
n.blending = Shader::BlendMode(mode);
std::ostringstream oss;
oss << "Blending ";
switch(n.blending) {
case Shader::BLEND_OPACITY:
oss<<"Normal";
break;
case Shader::BLEND_SCREEN:
oss<<"Screen";
break;
case Shader::BLEND_SUBTRACT:
oss<<"Subtract";
break;
case Shader::BLEND_MULTIPLY:
oss<<"Multiply";
break;
case Shader::BLEND_HARD_LIGHT:
oss<<"Hard light";
break;
case Shader::BLEND_SOFT_LIGHT:
oss<<"Soft light";
break;
case Shader::BLEND_SOFT_SUBTRACT:
oss<<"Soft subtract";
break;
case Shader::BLEND_LIGHTEN_ONLY:
oss<<"Lighten only";
break;
case Shader::BLEND_NONE:
oss<<"None";
break;
}
Action::manager().store(oss.str());
}
ImGui::PopID();
}
//void ImGuiVisitor::visit(ImageShader &n)
//{
// ImGui::PushID(std::to_string(n.id()).c_str());
// // get index of the mask used in this ImageShader
// int item_current = n.mask;
//// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0;
//// ImGui::SameLine(0, 10);
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// // combo list of masks
// if ( ImGui::Combo("Mask", &item_current, ImageShader::mask_names, IM_ARRAYSIZE(ImageShader::mask_names) ) )
// {
// if (item_current < (int) ImageShader::mask_presets.size())
// n.mask = item_current;
// else {
// // TODO ask for custom mask
// }
// Action::manager().store("Mask "+ std::string(ImageShader::mask_names[n.mask]));
// }
// ImGui::PopID();
//}
void ImGuiVisitor::visit(ImageProcessingShader &n)
{
ImGui::PushID(std::to_string(n.id()).c_str());
ImGuiToolkit::Icon(6, 2);
ImGui::SameLine(0, 10);
ImGui::Text("Filters");
if (ImGuiToolkit::ButtonIcon(6, 4)) {
n.gamma = glm::vec4(1.f, 1.f, 1.f, 1.f);
Action::manager().store("Gamma & Color");
}
ImGui::SameLine(0, 10);
ImGui::ColorEdit3("Gamma Color", glm::value_ptr(n.gamma), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel) ;
if (ImGui::IsItemDeactivatedAfterEdit())
Action::manager().store("Gamma Color changed");
ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Gamma", &n.gamma.w, 0.5f, 10.f, "%.2f", 2.f);
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Gamma " << std::setprecision(2) << n.gamma.w;
Action::manager().store(oss.str());
}
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// ImGui::SliderFloat4("Levels", glm::value_ptr(n.levels), 0.0, 1.0);
if (ImGuiToolkit::ButtonIcon(5, 16)) {
n.brightness = 0.f;
n.contrast = 0.f;
Action::manager().store("B & C 0.0 0.0");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
float bc[2] = { n.brightness, n.contrast};
if ( ImGui::SliderFloat2("B & C", bc, -1.0, 1.0) )
{
n.brightness = bc[0];
n.contrast = bc[1];
}
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "B & C " << std::setprecision(2) << n.brightness << " " << n.contrast;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(9, 16)) {
n.saturation = 0.f;
Action::manager().store("Saturation 0.0");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Saturation", &n.saturation, -1.0, 1.0);
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Saturation " << std::setprecision(2) << n.saturation;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(12, 4)) {
n.hueshift = 0.f;
Action::manager().store("Hue shift 0.0");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Hue shift", &n.hueshift, 0.0, 1.0);
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Hue shift " << std::setprecision(2) << n.hueshift;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(18, 1)) {
n.nbColors = 0;
Action::manager().store("Posterize None");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderInt("Posterize", &n.nbColors, 0, 16, n.nbColors == 0 ? "None" : "%d colors");
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Posterize ";
if (n.nbColors == 0) oss << "None"; else oss << n.nbColors;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(8, 1)) {
n.threshold = 0.f;
Action::manager().store("Threshold None");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Threshold", &n.threshold, 0.0, 1.0, n.threshold < 0.001 ? "None" : "%.2f");
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Threshold ";
if (n.threshold < 0.001) oss << "None"; else oss << std::setprecision(2) << n.threshold;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(3, 1)) {
n.lumakey = 0.f;
Action::manager().store("Lumakey 0.0");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Lumakey", &n.lumakey, 0.0, 1.0);
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Lumakey " << std::setprecision(2) << n.lumakey;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(13, 4)) {
n.chromakey = glm::vec4(0.f, 0.8f, 0.f, 1.f);
n.chromadelta = 0.f;
Action::manager().store("Chromakey & Color Reset");
}
ImGui::SameLine(0, 10);
ImGui::ColorEdit3("Chroma color", glm::value_ptr(n.chromakey), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel ) ;
if (ImGui::IsItemDeactivatedAfterEdit())
Action::manager().store("Chroma color changed");
ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Chromakey", &n.chromadelta, 0.0, 1.0, n.chromadelta < 0.001 ? "None" : "Tolerance %.2f");
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << "Chromakey ";
if (n.chromadelta < 0.001) oss << "None"; else oss << std::setprecision(2) << n.chromadelta;
Action::manager().store(oss.str());
}
if (ImGuiToolkit::ButtonIcon(6, 16)) {
n.invert = 0;
Action::manager().store("Invert None");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::Combo("Invert", &n.invert, "None\0Invert Color\0Invert Luminance\0"))
Action::manager().store("Invert " + std::string(n.invert<1 ? "None": (n.invert>1 ? "Luminance" : "Color")));
if (ImGuiToolkit::ButtonIcon(1, 7)) {
n.filterid = 0;
Action::manager().store("Filter None");
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::Combo("Filter", &n.filterid, ImageProcessingShader::filter_names, IM_ARRAYSIZE(ImageProcessingShader::filter_names) ) )
Action::manager().store("Filter " + std::string(ImageProcessingShader::filter_names[n.filterid]));
ImGui::PopID();
ImGui::Spacing();
}
void ImGuiVisitor::visit (Source& s)
{
ImGui::PushID(std::to_string(s.id()).c_str());
// blending
s.blendingShader()->accept(*this);
// preview
float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN;
float preview_height = 4.5f * ImGui::GetFrameHeightWithSpacing();
ImVec2 pos = ImGui::GetCursorPos(); // remember where we were...
float space = ImGui::GetStyle().ItemSpacing.y;
float width = preview_width;
float height = s.frame()->projectionArea().y * width / ( s.frame()->projectionArea().x * s.frame()->aspectRatio());
if (height > preview_height - space) {
height = preview_height - space;
width = height * s.frame()->aspectRatio() * ( s.frame()->projectionArea().x / s.frame()->projectionArea().y);
}
// centered image
ImGui::SetCursorPos( ImVec2(pos.x + 0.5f * (preview_width-width), pos.y + 0.5f * (preview_height-height-space)) );
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), ImVec2(width, height));
// inform on visibility status
ImGui::SetCursorPos( ImVec2(preview_width + 20, pos.y ) );
if (s.active()) {
if (s.blendingShader()->color.a > 0.f)
ImGuiToolkit::HelpMarker("Visible", ICON_FA_EYE);
else
ImGuiToolkit::HelpMarker("Not visible", ICON_FA_EYE_SLASH);
}
else
ImGuiToolkit::HelpMarker("Inactive", ICON_FA_SNOWFLAKE);
// Inform on workspace
ImGui::SetCursorPos( ImVec2(preview_width + 20, pos.y + ImGui::GetFrameHeightWithSpacing()) );
if (s.workspace() == Source::BACKGROUND)
ImGuiToolkit::HelpIcon("in Background",10, 16);
else if (s.workspace() == Source::FOREGROUND)
ImGuiToolkit::HelpIcon("in Foreground",12, 16);
else
ImGuiToolkit::HelpIcon("in Workspace",11, 16);
// locking
ImGui::SetCursorPos( ImVec2(preview_width + 20, pos.y + 2.f * ImGui::GetFrameHeightWithSpacing()) );
const char *tooltip[2] = {"Unlocked", "Locked"};
bool l = s.locked();
if (ImGuiToolkit::IconToggle(15,6,17,6, &l, tooltip ) ) {
s.setLocked(l);
if (l) {
Mixer::selection().clear();
Action::manager().store(s.name() + std::string(": lock."));
}
else {
Mixer::selection().set(&s);
Action::manager().store(s.name() + std::string(": unlock."));
}
}
// toggle enable/disable image processing
bool on = s.imageProcessingEnabled();
ImGui::SetCursorPos( ImVec2(preview_width + 15, pos.y + 3.5f * ImGui::GetFrameHeightWithSpacing()) );
if ( ImGuiToolkit::ButtonToggle(ICON_FA_MAGIC, &on) ){
std::ostringstream oss;
oss << s.name() << ": " << ( on ? "Enable Filter" : "Disable Filter");
Action::manager().store(oss.str());
}
s.setImageProcessingEnabled(on);
// image processing pannel
if (s.imageProcessingEnabled()) {
// menu icon for image processing
ImGui::SetCursorPos( ImVec2( preview_width - ImGui::GetTextLineHeight(), pos.y + 4.5f * ImGui::GetFrameHeightWithSpacing())); // ...come back
if (ImGuiToolkit::IconButton(5, 8))
ImGui::OpenPopup( "MenuImageProcessing" );
if (ImGui::BeginPopup( "MenuImageProcessing" ))
{
if (s.processingshader_link_.connected()) {
if (ImGui::MenuItem( "Unfollow" )){
s.processingshader_link_.disconnect();
}
}
else {
if (ImGui::MenuItem("Reset" )){
ImageProcessingShader defaultvalues;
s.processingShader()->copy(defaultvalues);
s.processingshader_link_.disconnect();
std::ostringstream oss;
oss << s.name() << ": " << "Reset Filter";
Action::manager().store(oss.str());
}
if (ImGui::MenuItem("Copy" )){
std::string clipboard = SessionVisitor::getClipboard(s.processingShader());
if (!clipboard.empty())
ImGui::SetClipboardText(clipboard.c_str());
}
const char *clipboard = ImGui::GetClipboardText();
const bool can_paste = (clipboard != nullptr && SessionLoader::isClipboard(clipboard));
if (ImGui::MenuItem("Paste", NULL, false, can_paste)) {
SessionLoader::applyImageProcessing(s, clipboard);
std::ostringstream oss;
oss << s.name() << ": " << "Change Filter";
Action::manager().store(oss.str());
}
// ImGui::Separator();
// if (ImGui::BeginMenu("Follow"))
// {
// for (auto mpit = Mixer::manager().session()->begin();
// mpit != Mixer::manager().session()->end(); mpit++ )
// {
// std::string label = (*mpit)->name();
// if ( (*mpit)->id() != s.id() &&
// (*mpit)->imageProcessingEnabled() &&
// !(*mpit)->processingshader_link_.connected()) {
// if (ImGui::MenuItem( label.c_str() )){
// s.processingshader_link_.connect(*mpit);
// s.touch();
// }
// }
// }
// ImGui::EndMenu();
// }
}
ImGui::EndPopup();
}
// full panel for image processing
ImGui::SetCursorPos( ImVec2( pos.x, pos.y + preview_height)); // ...come back
if (s.processingshader_link_.connected()) {
ImGuiToolkit::Icon(6, 2);
ImGui::SameLine(0, 10);
ImGui::Text("Filters");
Source *target = s.processingshader_link_.source();
ImGui::Text("Following");
if ( target != nullptr && ImGui::Button(target->name().c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().setCurrentSource(target);
}
else
s.processingShader()->accept(*this);
}
ImGui::PopID();
}
void ImGuiVisitor::visit (MediaSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
if ( s.mediaplayer()->isImage() )
ImGui::Text("Image File");
else
ImGui::Text("Video File");
// Media info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
// folder
std::string path = SystemToolkit::path_filename(s.path());
std::string label = BaseToolkit::trunc_string(path, 25);
label = BaseToolkit::transliterate(label);
ImGuiToolkit::ButtonOpenUrl( label.c_str(), path.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
ImGui::SameLine();
ImGui::Text("Folder");
}
void ImGuiVisitor::visit (SessionFileSource& s)
{
if (s.session() == nullptr)
return;
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Session File");
// info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
if ( ImGui::Button( ICON_FA_FILE_EXPORT " Import", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().import( &s );
ImGui::SameLine();
ImGui::Text("Sources");
if (ImGuiToolkit::ButtonIcon(3, 2)) s.session()->setFading(0.f);
float f = s.session()->fading();
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::SliderFloat("Fading", &f, 0.0, 1.0, f < 0.001 ? "None" : "%.2f") )
s.session()->setFading(f);
if (ImGui::IsItemDeactivatedAfterEdit()){
std::ostringstream oss;
oss << s.name() << ": Fading " << std::setprecision(2) << f;
Action::manager().store(oss.str());
}
if ( ImGui::Button( ICON_FA_FILE_UPLOAD " Open", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().set( s.detach() );
ImGui::SameLine();
ImGui::Text("File");
std::string path = SystemToolkit::path_filename(s.path());
std::string label = BaseToolkit::trunc_string(path, 25);
label = BaseToolkit::transliterate(label);
ImGuiToolkit::ButtonOpenUrl( label.c_str(), path.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
ImGui::SameLine();
ImGui::Text("Folder");
}
void ImGuiVisitor::visit (SessionGroupSource& s)
{
if (s.session() == nullptr)
return;
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Flat Sesion group");
// info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
if ( ImGui::Button( ICON_FA_UPLOAD " Expand", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ){
Mixer::manager().import( &s );
}
}
void ImGuiVisitor::visit (RenderSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Rendering Output");
if ( ImGui::Button(IMGUI_TITLE_PREVIEW, ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Settings::application.widget.preview = true;
}
void ImGuiVisitor::visit (CloneSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Clone");
if ( ImGui::Button(s.origin()->name().c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().setCurrentSource(s.origin());
ImGui::SameLine();
ImGui::Text("Source");
}
void ImGuiVisitor::visit (PatternSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Pattern");
// stream info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::BeginCombo("##Patterns", Pattern::pattern_types[s.pattern()->type()].c_str()) )
{
for (uint p = 0; p < Pattern::pattern_types.size(); ++p){
if (ImGui::Selectable( Pattern::pattern_types[p].c_str() )) {
s.setPattern(p, s.pattern()->resolution());
info.reset();
std::ostringstream oss;
oss << s.name() << ": Pattern " << Pattern::pattern_types[p];
Action::manager().store(oss.str());
}
}
ImGui::EndCombo();
}
ImGui::SameLine();
ImGui::Text("Generator");
}
void ImGuiVisitor::visit (DeviceSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Device");
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::BeginCombo("##Hardware", s.device().c_str()))
{
for (int d = 0; d < Device::manager().numDevices(); ++d){
std::string namedev = Device::manager().name(d);
if (ImGui::Selectable( namedev.c_str() )) {
s.setDevice(namedev);
info.reset();
std::ostringstream oss;
oss << s.name() << " Device " << namedev;
Action::manager().store(oss.str());
}
}
ImGui::EndCombo();
}
}
void ImGuiVisitor::visit (NetworkSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Network stream");
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_STREAM, 0.9f));
ImGui::Text("%s", s.connection().c_str());
ImGui::PopStyleColor(1);
// network info
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
if ( ImGui::Button( ICON_FA_REPLY " Reconnect", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
{
s.setConnection(s.connection());
info.reset();
}
}
void ImGuiVisitor::visit (MultiFileSource& s)
{
ImGuiToolkit::Icon(s.icon().x, s.icon().y);
ImGui::SameLine(0, 10);
ImGui::Text("Images sequence");
static int64_t id = 0;
// information text
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
s.accept(info);
ImGui::Text("%s", info.str().c_str());
ImGui::PopTextWrapPos();
// icon (>) to open player
if ( s.playable() ) {
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SameLine(0, 0);
ImGui::SameLine(0, ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN);
if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player"))
UserInterface::manager().showSourceEditor(&s);
ImGui::SetCursorPos(pos);
}
// change range
static int _begin = -1;
if (_begin < 0 || id != s.id())
_begin = s.begin();
static int _end = -1;
if (_end < 0 || id != s.id())
_end = s.end();
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::DragIntRange2("Range", &_begin, &_end, 1, s.sequence().min, s.sequence().max);
if (ImGui::IsItemDeactivatedAfterEdit()){
s.setRange( _begin, _end );
std::ostringstream oss;
oss << s.name() << ": Range " << _begin << "-" << _end;
Action::manager().store(oss.str());
_begin = _end = -1;
}
// change framerate
static int _fps = -1;
if (_fps < 0 || id != s.id())
_fps = s.framerate();
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderInt("Framerate", &_fps, 1, 30, "%d fps");
if (ImGui::IsItemDeactivatedAfterEdit()){
s.setFramerate(_fps);
std::ostringstream oss;
oss << s.name() << ": Framerate " << _fps << " fps";
Action::manager().store(oss.str());
_fps = -1;
}
// offer to open file browser at location
std::string path = SystemToolkit::path_filename(s.sequence().location);
std::string label = BaseToolkit::trunc_string(path, 25);
label = BaseToolkit::transliterate(label);
ImGuiToolkit::ButtonOpenUrl( label.c_str(), path.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
ImGui::SameLine();
ImGui::Text("Folder");
if (id != s.id())
id = s.id();
}

View File

@@ -1,259 +0,0 @@
#include "InfoVisitor.h"
#include <vector>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_access.hpp>
#include <tinyxml2.h>
#include "tinyxml2Toolkit.h"
#include "defines.h"
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "MediaPlayer.h"
#include "MediaSource.h"
#include "SessionSource.h"
#include "PatternSource.h"
#include "DeviceSource.h"
#include "NetworkSource.h"
#include "MultiFileSource.h"
#include "SessionCreator.h"
#include "SessionVisitor.h"
#include "Settings.h"
#include "Mixer.h"
#include "ActionManager.h"
#include "BaseToolkit.h"
#include "UserInterfaceManager.h"
#include "SystemToolkit.h"
InfoVisitor::InfoVisitor() : brief_(true), current_id_(0)
{
}
void InfoVisitor::visit(Node &n)
{
}
void InfoVisitor::visit(Group &n)
{
}
void InfoVisitor::visit(Switch &n)
{
}
void InfoVisitor::visit(Scene &n)
{
}
void InfoVisitor::visit(Primitive &n)
{
}
void InfoVisitor::visit(MediaPlayer &mp)
{
// do not ask twice
if (current_id_ == mp.id())
return;
std::ostringstream oss;
if (brief_) {
oss << SystemToolkit::filename(mp.filename()) << std::endl;
oss << mp.width() << " x " << mp.height() << ", ";
oss << mp.media().codec_name.substr(0, mp.media().codec_name.find_first_of(" (,"));
if (!mp.isImage())
oss << ", " << std::fixed << std::setprecision(1) << mp.frameRate() << " fps";
}
else {
oss << mp.filename() << std::endl;
oss << mp.media().codec_name << std::endl;
oss << mp.width() << " x " << mp.height() ;
if (!mp.isImage())
oss << ", " << std::fixed << std::setprecision(1) << mp.frameRate() << " fps";
}
information_ = oss.str();
// remember (except if codec was not identified yet)
if ( !mp.media().codec_name.empty() )
current_id_ = mp.id();
}
void InfoVisitor::visit(Stream &n)
{
std::ostringstream oss;
if (brief_) {
}
else {
}
information_ = oss.str();
}
void InfoVisitor::visit (MediaSource& s)
{
s.mediaplayer()->accept(*this);
}
void InfoVisitor::visit (SessionFileSource& s)
{
if (current_id_ == s.id() || s.session() == nullptr)
return;
std::ostringstream oss;
if (brief_) {
oss << SystemToolkit::filename(s.path()) << " (";
oss << s.session()->numSource() << " sources)" << std::endl;
}
else
oss << s.path() << std::endl;
if (s.session()->frame()){
oss << s.session()->frame()->width() << " x " << s.session()->frame()->height() << ", ";
oss << "RGB";
}
information_ = oss.str();
current_id_ = s.id();
}
void InfoVisitor::visit (SessionGroupSource& s)
{
if (current_id_ == s.id() || s.session() == nullptr)
return;
std::ostringstream oss;
oss << s.session()->numSource() << " sources in group" << std::endl;
if (s.session()->frame()){
oss << s.session()->frame()->width() << " x " << s.session()->frame()->height() << ", ";
oss << "RGB";
}
information_ = oss.str();
current_id_ = s.id();
}
void InfoVisitor::visit (RenderSource& s)
{
if (current_id_ == s.id())
return;
information_ = "Rendering Output";
current_id_ = s.id();
}
void InfoVisitor::visit (CloneSource& s)
{
if (current_id_ == s.id())
return;
information_ = "Clone of " + s.origin()->name();
current_id_ = s.id();
}
void InfoVisitor::visit (PatternSource& s)
{
if (current_id_ == s.id())
return;
std::ostringstream oss;
oss << Pattern::pattern_types[s.pattern()->type()] << std::endl;
if (s.pattern()) {
oss << s.pattern()->width() << " x " << s.pattern()->height();
oss << ", RGB";
}
information_ = oss.str();
current_id_ = s.id();
}
void InfoVisitor::visit (DeviceSource& s)
{
if (current_id_ == s.id())
return;
std::ostringstream oss;
DeviceConfigSet confs = Device::manager().config( Device::manager().index(s.device().c_str()));
if ( !confs.empty()) {
DeviceConfig best = *confs.rbegin();
float fps = static_cast<float>(best.fps_numerator) / static_cast<float>(best.fps_denominator);
if (brief_) {
oss << best.width << " x " << best.height << ", ";
oss << best.stream << " " << best.format << ", ";
oss << std::fixed << std::setprecision(1) << fps << " fps";
}
else {
oss << s.device() << std::endl;
oss << best.width << " x " << best.height << ", ";
oss << best.stream << " " << best.format << ", ";
oss << std::fixed << std::setprecision(1) << fps << " fps";
}
}
information_ = oss.str();
current_id_ = s.id();
}
void InfoVisitor::visit (NetworkSource& s)
{
if (current_id_ == s.id())
return;
NetworkStream *ns = s.networkStream();
std::ostringstream oss;
if (brief_) {
oss << ns->resolution().x << " x " << ns->resolution().y << ", ";
oss << NetworkToolkit::protocol_name[ns->protocol()] << std::endl;
oss << "IP " << ns->serverAddress();
}
else {
oss << s.connection() << " (IP " << ns->serverAddress() << ")" << std::endl;
oss << ns->resolution().x << " x " << ns->resolution().y << ", ";
oss << NetworkToolkit::protocol_name[ns->protocol()];
}
information_ = oss.str();
current_id_ = s.id();
}
void InfoVisitor::visit (MultiFileSource& s)
{
if (current_id_ == s.id())
return;
std::ostringstream oss;
if (brief_) {
oss << s.sequence().width << " x " << s.sequence().height << ", ";
oss << s.sequence().codec << std::endl;
oss << s.sequence().max - s.sequence().min + 1 << " images [";
oss << s.sequence().min << " - " << s.sequence().max << "]";
}
else {
oss << s.sequence().location << " [";
oss << s.sequence().min << " - " << s.sequence().max << "]" << std::endl;
oss << s.sequence().width << " x " << s.sequence().height << ", ";
oss << s.sequence().codec << " (";
oss << s.sequence().max - s.sequence().min + 1 << " images)";
}
information_ = oss.str();
current_id_ = s.id();
}

View File

@@ -1,169 +0,0 @@
#include <sstream>
#include <glm/gtc/matrix_transform.hpp>
#include "PatternSource.h"
#include "defines.h"
#include "ImageShader.h"
#include "Resource.h"
#include "Decorations.h"
#include "Stream.h"
#include "Visitor.h"
#include "Log.h"
#define MAX_PATTERN 24
// smpte (0) SMPTE 100%% color bars
// snow (1) Random (television snow)
// black (2) 100%% Black
// white (3) 100%% White
// red (4) Red
// green (5) Green
// blue (6) Blue
// checkers-1 (7) Checkers 1px
// checkers-2 (8) Checkers 2px
// checkers-4 (9) Checkers 4px
// checkers-8 (10) Checkers 8px
// circular (11) Circular
// blink (12) Blink
// smpte75 (13) SMPTE 75%% color bars
// zone-plate (14) Zone plate
// gamut (15) Gamut checkers
// chroma-zone-plate (16) Chroma zone plate
// solid-color (17) Solid color
// ball (18) Moving ball
// smpte100 (19) SMPTE 100%% color bars
// bar (20) Bar
// pinwheel (21) Pinwheel
// spokes (22) Spokes
// gradient (23) Gradient
// colors (24) Colors
const char* pattern_internal_[MAX_PATTERN] = { "videotestsrc pattern=black",
"videotestsrc pattern=white",
"videotestsrc pattern=gradient",
"videotestsrc pattern=checkers-1 ! video/x-raw,format=GRAY8 ! videoconvert",
"videotestsrc pattern=checkers-8 ! video/x-raw,format=GRAY8 ! videoconvert",
"videotestsrc pattern=circular",
"frei0r-src-lissajous0r ratiox=0.001 ratioy=0.999 ! videoconvert",
"videotestsrc pattern=pinwheel",
"videotestsrc pattern=spokes",
"videotestsrc pattern=red",
"videotestsrc pattern=green",
"videotestsrc pattern=blue",
"videotestsrc pattern=smpte100",
"videotestsrc pattern=colors",
"videotestsrc pattern=smpte",
"videotestsrc pattern=snow",
"videotestsrc pattern=blink",
"videotestsrc pattern=zone-plate",
"videotestsrc pattern=chroma-zone-plate",
"videotestsrc pattern=bar horizontal-speed=5",
"videotestsrc pattern=ball",
"frei0r-src-ising0r",
"videotestsrc pattern=black ! timeoverlay halignment=center valignment=center font-desc=\"Sans, 72\" ",
"videotestsrc pattern=black ! clockoverlay halignment=center valignment=center font-desc=\"Sans, 72\" "
};
std::vector<std::string> Pattern::pattern_types = { "Black",
"White",
"Gradient",
"Checkers 1x1 px",
"Checkers 8x8 px",
"Circles",
"Lissajous",
"Pinwheel",
"Spokes",
"Red",
"Green",
"Blue",
"Color bars",
"RGB grid",
"SMPTE test pattern",
"Television snow",
"Blink",
"Fresnel zone plate",
"Chroma zone plate",
"Bar moving",
"Ball bouncing"
#if GST_VERSION_MINOR > 17
,
"Blob",
"Timer",
"Clock"
#endif
};
Pattern::Pattern() : Stream(), type_(MAX_PATTERN) // invalid pattern
{
}
glm::ivec2 Pattern::resolution()
{
return glm::ivec2( width_, height_);
}
void Pattern::open( uint pattern, glm::ivec2 res )
{
type_ = MIN(pattern, MAX_PATTERN-1);
std::string gstreamer_pattern = pattern_internal_[type_];
// there is always a special case...
switch(type_)
{
case 18: // zone plates
case 17:
{
std::ostringstream oss;
oss << " kx2=" << (int)(res.x * 10.f / res.y) << " ky2=10 kt=4";
gstreamer_pattern += oss.str(); // Zone plate
}
break;
default:
break;
}
// all patterns before 'SMPTE test pattern' are single frames (not animated)
single_frame_ = type_ < 14;
Log::Info("Stream %d SingleFrame", single_frame_);
// (private) open stream
Stream::open(gstreamer_pattern, res.x, res.y);
}
PatternSource::PatternSource(uint64_t id) : StreamSource(id)
{
// create stream
stream_ = static_cast<Stream *>( new Pattern );
// set symbol
symbol_ = new Symbol(Symbol::PATTERN, glm::vec3(0.75f, 0.75f, 0.01f));
symbol_->scale_.y = 1.5f;
}
void PatternSource::setPattern(uint type, glm::ivec2 resolution)
{
Log::Notify("Creating Source with pattern '%s'", Pattern::pattern_types[type].c_str());
// open gstreamer
pattern()->open( (uint) type, resolution );
stream_->play(true);
// will be ready after init and one frame rendered
ready_ = false;
}
void PatternSource::accept(Visitor& v)
{
Source::accept(v);
if (!failed())
v.visit(*this);
}
Pattern *PatternSource::pattern() const
{
return dynamic_cast<Pattern *>(stream_);
}

View File

@@ -7,8 +7,8 @@ computer generated graphics, with image processing effects in real-time.
Its intuitive and hands-on user interface gives direct control on image opacity and
shape for producing live graphics during concerts and VJ-ing sessions.
The ouput image is typically projected full-screen on an external
monitor or a projector, but can be recorded live (no audio).
The output image is typically projected full-screen on an external
monitor or a projector, but can be streamed live (SRT) or recorded (no audio).
vimix is the successor for GLMixer - https://sourceforge.net/projects/glmixer/
@@ -69,15 +69,26 @@ Compile (or re-compile after pull):
**Libraries:**
- gstreamer
- gst-plugins : base, good, bad & ugly
- gst-plugins (libav, base, good, bad & ugly)
- libglfw3
- libicu
- libicu (icu-i18n icu-uc icu-io)
Optionnal:
- glm
- stb
- TinyXML2
- AbletonLink
#### Install Dependencies
**Ubuntu**
$ apt-get install build-essential cmake libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libicu-dev libgtk-3-dev
$ apt-get install build-essential cmake libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-libav libicu-dev libgtk-3-dev
Optionnal:
$ apt-get install libglm-dev libstb-dev libtinyxml2-dev ableton-link-dev
**OSX with Brew**

File diff suppressed because it is too large Load Diff

View File

@@ -1,270 +0,0 @@
#ifndef __UI_MANAGER_H_
#define __UI_MANAGER_H_
#include <string>
#include <list>
#define NAV_COUNT 68
#define NAV_MAX 64
#define NAV_NEW 65
#define NAV_MENU 66
#define NAV_TRANS 67
#include "SourceList.h"
#include "InfoVisitor.h"
#include "DialogToolkit.h"
#include "SessionParser.h"
struct ImVec2;
class MediaPlayer;
class FrameBufferImage;
class FrameGrabber;
class SourcePreview {
Source *source_;
std::string label_;
bool reset_;
public:
SourcePreview();
void setSource(Source *s = nullptr, const std::string &label = "");
Source *getSource();
void Render(float width, bool controlbutton = false);
bool ready() const;
inline bool filled() const { return source_ != nullptr; }
};
class Thumbnail
{
float aspect_ratio_;
uint texture_;
public:
Thumbnail();
~Thumbnail();
void reset();
void fill (const FrameBufferImage *image);
bool filled();
void Render(float width);
};
class Navigator
{
// geometry left bar & pannel
float width_;
float height_;
float pannel_width_;
float padding_width_;
// behavior pannel
bool show_config_;
bool pannel_visible_;
bool view_pannel_visible;
bool selected_button[NAV_COUNT];
int pattern_type;
std::list<std::string> _selectedFiles;
void clearButtonSelection();
void applyButtonSelection(int index);
// side pannels
void RenderSourcePannel(Source *s);
void RenderMainPannel();
void RenderMainPannelVimix();
void RenderMainPannelSettings();
void RenderTransitionPannel();
void RenderNewPannel();
void RenderViewPannel(ImVec2 draw_pos, ImVec2 draw_size);
SourcePreview new_source_preview_;
public:
Navigator();
bool pannelVisible() { return pannel_visible_; }
void hidePannel();
void showPannelSource(int index);
void togglePannelMenu();
void togglePannelNew();
void showConfig();
void Render();
};
class ToolBox
{
bool show_demo_window;
bool show_icons_window;
bool show_sandbox;
public:
ToolBox();
void Render();
};
class HelperToolbox
{
SessionParser parser_;
public:
HelperToolbox();
void Render();
};
class SourceController
{
bool focused_;
float min_width_;
float h_space_;
float v_space_;
float scrollbar_;
float timeline_height_;
float mediaplayer_height_;
float buttons_width_;
float buttons_height_;
bool play_toggle_request_, replay_request_;
std::string active_label_;
int active_selection_;
InfoVisitor info_;
SourceList selection_;
// re-usable ui parts
void DrawButtonBar(ImVec2 bottom, float width);
const char *SourcePlayIcon(Source *s);
bool SourceButton(Source *s, ImVec2 framesize);
// Render the sources dynamically selected
void RenderSelectedSources();
// Render a stored selection
bool selection_context_menu_;
MediaPlayer *selection_mediaplayer_;
double selection_target_slower_;
double selection_target_faster_;
void RenderSelectionContextMenu();
void RenderSelection(size_t i);
// Render a single source
void RenderSingleSource(Source *s);
// Render a single media player
MediaPlayer *mediaplayer_active_;
bool mediaplayer_edit_fading_;
bool mediaplayer_mode_;
bool mediaplayer_slider_pressed_;
float mediaplayer_timeline_zoom_;
void RenderMediaPlayer(MediaPlayer *mp);
public:
SourceController();
inline void Play() { play_toggle_request_ = true; }
inline void Replay() { replay_request_= true; }
void Update();
void resetActiveSelection();
void Render();
bool Visible() const;
inline bool Foccused() const { return focused_; }
};
class UserInterface
{
friend class Navigator;
Navigator navigator;
ToolBox toolbox;
SourceController sourcecontrol;
HelperToolbox sessiontoolbox;
bool ctrl_modifier_active;
bool alt_modifier_active;
bool shift_modifier_active;
bool show_vimix_about;
bool show_imgui_about;
bool show_gst_about;
bool show_opengl_about;
int show_view_navigator;
int target_view_navigator;
unsigned int screenshot_step;
// frame grabbers
FrameGrabber *video_recorder_;
#if defined(LINUX)
FrameGrabber *webcam_emulator_;
#endif
// Dialogs
DialogToolkit::OpenSessionDialog *sessionopendialog;
DialogToolkit::OpenSessionDialog *sessionimportdialog;
DialogToolkit::SaveSessionDialog *sessionsavedialog;
// Private Constructor
UserInterface();
UserInterface(UserInterface const& copy) = delete;
UserInterface& operator=(UserInterface const& copy) = delete;
public:
static UserInterface& manager()
{
// The only instance
static UserInterface _instance;
return _instance;
}
// pre-loop initialization
bool Init();
// loop update start new frame
void NewFrame();
// loop update rendering
void Render();
// Post-loop termination
void Terminate();
// status querries
inline bool ctrlModifier() const { return ctrl_modifier_active; }
inline bool altModifier() const { return alt_modifier_active; }
inline bool shiftModifier() const { return shift_modifier_active; }
void showPannel(int id = 0);
void showSourceEditor(Source *s);
// TODO implement the shader editor
std::string currentTextEdit;
void fillShaderEditor(const std::string &text);
void StartScreenshot();
inline bool isRecording() const { return video_recorder_ != nullptr; }
protected:
void showMenuFile();
void showMenuEdit();
void selectSaveFilename();
void selectOpenFilename();
void RenderMetrics (bool* p_open, int* p_corner, int *p_mode);
void RenderPreview();
void RenderHistory();
void RenderShaderEditor();
int RenderViewNavigator(int* shift);
void RenderAbout(bool* p_open);
void RenderNotes();
void handleKeyboard();
void handleMouse();
void handleScreenshot();
};
#endif /* #define __UI_MANAGER_H_ */

View File

@@ -41,8 +41,8 @@ foreach(_component ${GStreamerPluginsBad_FIND_COMPONENTS})
_find_gst_plugins_bad_component(PLAYER gstplayer.h)
elseif (${_component} STREQUAL "webrtc")
_find_gst_plugins_bad_component(WEBRTC webrtc.h)
elseif (${_component} STREQUAL "mpegts")
_find_gst_plugins_bad_component(MPEGTS mpegts.h)
elseif (${_component} STREQUAL "srtsrc")
_find_gst_plugins_bad_component(SRTSRC mpegts.h)
else()
message (AUTHOR_WARNING "FindGStreamerPluginBad.cmake: Invalid component \"${_component}\" was specified")
endif()

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 KiB

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 KiB

After

Width:  |  Height:  |  Size: 987 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 846 KiB

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 KiB

After

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 KiB

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 857 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 986 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 706 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 616 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 641 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 KiB

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 505 KiB

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 941 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 711 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 389 KiB

Some files were not shown because too many files have changed in this diff Show More