The status bar now displays:
- Auto-reconnect information (reconnecting and reconnect success)
- Dropped frames (as well as percentage of total video frames)
- Duration of session
- CPU usage of the program
- Kbp/s
The OBSBasic class is getting a bit big, so I separated out the
status bar code to its own class derived from QStatusBar.
Contains Move Up, Move Down, Move to Top, Move to Bottom. Also assigns
Ctrl-Up, Ctrl-Down, Ctrl-Home, Ctrl-End to each action.
This was also added to the right-click context menu popup for sources.
The removeItemAction just for a keyboard shortcut was unnecessary.
Instead, use the toolbar button to associate a shortcut with, and remove
the removeItemAction object.
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
Implement the 'file path' in output settings, and implement the 'start
recording' button, though for the time being I'm just going to make it
use a directory rather than allow custom file names.
This file output will actually share the video and audio encoder with
the stream.
I don't really know what to do about MP4 -- I don't really like the idea
of saving directly in the program, if you do and the program crashes,
that MP4 file is lost. I'm contemplating making some sort of mp4 output
process stub. So no MP4 file output for the time being.
If you need MP4, just remux it with FFmpeg:
ffmpeg -i flv_file.flv -acodec copy -vcodec copy mp4_file.mp4
Added github gist API uploading to the help menu to help make problems a
bit easier to debug in the future. It's somewhat vital that this
functionality be implemented before any release in order to analyze any
given problem a user may be experiencing.
Add a 'source selection' dialog to replace the 'enter a name' dialog.
This new dialog allows you to make new instances of pre-existing sources
so that you can add a pre-existing source to a different scene, or in to
the same scene more than once.
Also started implementing locale.
Comtemplating switching to JSON-based locale later, so we can add things
like descriptions/disambiguation, and so we can use jansson's built-in
hash table when doing the string lookup.
- Add volume control
These volume controls are basically nothing more than sliders. They
look terrible and hopefully will be as temporary as they are
terrible.
- Allow saving of specific non-user sources via obs_load_source and
obs_save_source functions.
- Save data of desktop/mic audio sources (sync data, volume data, etc),
and load the data on startup.
- Make it so that a scene is created by default if first time using the
application. On certain operating systems where supported, a default
capture will be created. Desktop capture on mac, particularly. Not
sure what to do about windows because monitor capture on windows 7 is
completely terrible and is bad to start users off with.
- Add a properties window for sources so that you can now actually edit
the settings for sources. Also, display the source by itself in the
window (Note: not working on mac, and possibly not working on linux).
When changing the settings for a source, it will call
obs_source_update on that source when you have modified any values
automatically.
- Add a properties 'widget', eventually I want to turn this in to a
regular nice properties view like you'd see in the designer, but
right now it just uses a form layout in a QScrollArea with regular
controls to display the properties. It's clunky but works for the
time being.
- Make it so that swap chains and the main graphics subsystem will
automatically use at least one backbuffer if none was specified
- Fix bug where displays weren't added to the main display array
- Make it so that you can get the properties of a source via the actual
pointer of a source/encoder/output in addition to being able to look
up properties via identifier.
- When registering source types, check for required functions (wasn't
doing it before). getheight/getwidth should not be optional if it's
a video source as well.
- Add an RAII OBSObj wrapper to obs.hpp for non-reference-counted
libobs pointers
- Add an RAII OBSSignal wrapper to obs.hpp for libobs signals to
automatically disconnect them on destruction
- Move the "scale and center" calculation in window-basic-main.cpp to
its own function and in its own source file
- Add an 'update' callback to WASAPI audio sources
- Add some temporary streaming code using FFmpeg. FFmpeg itself is not
very ideal for streaming; lack of direct control of the sockets and
no framedrop handling means that FFmpeg is definitely not something
you want to use without wrapper code. I'd prefer writing my own
network framework in this particular case just because you give away
so much control of the network interface. Wasted an entire day
trying to go through FFmpeg issues.
There's just no way FFmpeg should be used for real streaming (at
least without being patched or submitting some sort of patch, but I'm
sort of feeling "meh" on that idea)
I had to end up writing multiple threads just to handle both
connecting and writing, because av_interleaved_write_frame blocks
every call, stalling the main encoder thread, and thus also stalling
draw signals.
- Add some temporary user interface for streaming settings. This is
just temporary for the time being. It's in the outputs section of
the basic-mode settings
- Make it so that dynamic arrays do not free all their data when the
size just happens to be reduced to 0. This prevents constant
reallocation when an array keeps going from 1 item to 0 items. Also,
it was bad to become dependent upon that functionality. You must now
always explicitly call "free" on it to ensure the data is free, and
that's how it should be. Implicit functionality can lead to
confusion and maintainability issues.
Modify the obs_display API so that it always uses an orthographic
projection that is the size of the display, rather than OBS' base size.
Having it do an orthographic projection to OBS' base size was silly
because it meant that everything would be skewed if you wanted to draw
1:1 in the display. This deoes mean that the callbacks must handle
resizing the images, but it's worth it to ensure 1:1 draw sizes.
As for the preview widget, instead of making some funky widget within
widget that resizes, it's just going to be a widget within the entire
top layout. Also changed the preview padding color to gray.
- Move over the last of the original settings dialog code to QT. It was
actually a bit easier to write in the QT version. wxWidgets was
definitely not ideal for that because the pages would fully
create/destroy every time.
- [Win32] Fix os_dlopen so that it only appends .dll if not present
- [MacOS] Fix name dialog text edit widget issue (it would be better if
we could just use the list widget for editing labels, will have to
look in to that in the future)
- Tweak the settings UI a bit more and make 30 FPS default
- Add a macro to convert a QString to a UTF-8 const char * string
- Rename build/plugins to build/obs-plugins
- Remove the last of the wxWidgets code
- Fix the size issue with list boxes on mac. Was displaying the list
boxes with an improper size. Turns out it was just the wrong size
policies on the frame below.
- Ensure the main windows are fully displayed *before* initializing
subsystems. This ensures that the graphics system will properly start
up on macos, and allows the glitch fix.
- Made a workaround for weird QT glitch that would happen to the parent
of a pure native widget that also has internal painting fully
disabled. (Should definitely write an example and report this bug on
the QT forums)
- Had the wrong names set for the up/down widgets for sources/scenes
- Updated the settings dialog and gave most of the widgets actual object
names
- Added code for the settings window. Settings window should now at
least display.
- I seem to have fixed ths issues with the main preview widget. It
seems you just need to set the right window attributes to stop it from
breaking. Though when opengl is enabled, there appears to be a weird
background glitch in the Qt stuff -- I'm not entirely sure what's
going on. Bug in Qt?
Also fixed the layout issues, and the widget now properly resizes and
centers in to its parent widget.
- Prevent the render loop from accessing data if the data isn't valid.
Because obs->data is freed before the graphics stuff, it can cause
the graphics to keep trying to query the obs->data.displays_mutex
after it had already been destroyed.
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)