Non-NV12 video formats are primarily intended for recording. For
streaming, if the libobs color format is not set to NV12, it's likely
that the video frames will have to be converted to NV12, which will use
extra CPU usage. Due to that fact, it's important to warn the user of
that potential extra increased CPU usage that may be required when
streaming.
OBS will offer the user a list of themes which are .qss files inside
data/obs-studio/themes. If no theme is found in the configuration, it
loads the default theme for the system.
Currently, this allows the setting of values such as:
- Audio buffering time
- Color format (still somewhat unsupported)
- YUV color space (if a YUV format)
= YUV color range (if a YUV format)
More color formats will be added in the future, such as RGB and YUV
4:2:2 formats.
Add a checkbox named "Enforce streaming service encoder settings"
checkbox to advanced output. Disabling this checkbox allows the user to
optionally disable the enforcement of streaming service encoder
settings. I had a user complain that they didn't want to always have
the service's preferred encoder settings forced on them.
For the 'output resolution' setting in video settings, do not show
values in the list that it does not support (width must be aligned to a
128bit boundry, and height must be divisible by two)
For the 'rescale' settings in advanced outputs, the scales must all be
divisible by two.
The 'rescale' values in advanced output section are supposed to be based
upon the output resolution of the program. Meaning they should not be
used for scaling up, because the resolution downloaded from the graphics
processor is the output resolution set in video settings; thus any
resolution you set for the 'rescale' values is scaled from that.
To prevent from causing confusion/issues for our most awesome and
respected locale editors, only localize and translate the relevant text
rather than the extensions of the filter.
Before: After:
obs_service_gettype obs_service_get_type
It seems there was an API function that was missed when we were doing
our big API consistency update. Unsquishes obs_service_gettype to
obs_service_get_type.
Currently service settings are updated in real time via the properties
view, which means that OK/Cancel/Apply have no effect. This fixes that
by using the new type of properties view that operates only on settings
data, not an object.
Adds an 'advanced' mode to the output settings to allow more powerful
and complex streaming and recording options:
- Optionally use a different encoder for recording than for streaming to
allow the recording to use a different encoder or encoder settings if
desired (though at the cost if increased CPU usage depending on the
encoders being used)
- Use encoders other than x264
- Rescale the recording or streaming encoders in case the user wishes to
stream and record at different resolutions
- Select the specific mixer to use for recording and for streaming,
allowing the stream and recording to use separate mixers (to for
example allow a user to stream the game/mic audio but only record the
game audio)
- Use FFmpeg output for the recording button instead of only recording
h264/aac to FLV, allowing the user to output to various different
types of file formats or remote URLs, as well as allowing the user to
select and use different encoders and encoder settings that are
available in the FFmpeg library
- Optionally allow the use of multiple audio tracks in a single output
if the file formats or stream services support it
Typedef pointers are unsafe. If you do:
typedef struct bla *bla_t;
then you cannot use it as a constant, such as: const bla_t, because
that constant will be to the pointer itself rather than to the
underlying data. I admit this was a fundamental mistake that must
be corrected.
All typedefs that were pointer types will now have their pointers
removed from the type itself, and the pointers will be used when they
are actually used as variables/parameters/returns instead.
This does not break ABI though, which is pretty nice.
Instead of having functions like obs_signal_handler() that can fail to
properly specify their actual intent in the name (does it signal a
handler, or does it return a signal handler?), always prefix functions
that are meant to get information with 'get' to make its functionality
more explicit.
Previous names: New names:
-----------------------------------------------------------
obs_audio obs_get_audio
obs_video obs_get_video
obs_signalhandler obs_get_signal_handler
obs_prochandler obs_get_proc_handler
obs_source_signalhandler obs_source_get_signal_handler
obs_source_prochandler obs_source_get_proc_handler
obs_output_signalhandler obs_output_get_signal_handler
obs_output_prochandler obs_output_get_proc_handler
obs_service_signalhandler obs_service_get_signal_handler
obs_service_prochandler obs_service_get_proc_handler
The locale parameter was a mistake, because it puts extra needless
burden upon the module developer to have to handle this variable for
each and every single callback function. The parameter is being removed
in favor of a single centralized module callback function that
specifically updates locale information for a module only when needed.
Currently, if a user presses 'OK' or 'Apply' on the settings window, it
will save all data from all controls on a settings pane, regardless of
whether of not they were changed. The major issue with this is that
setting the data will overwrite all default values, making it impossible
for default values to be used if a user didn't actually change a value.
(Thanks to palana for pointing this fact out)
So instead, mark a control as 'changed' using QObject::property() and
QObject::sender(), and add a few helper functions to controls to ensure
that they are checked to see whether they were actually changed directly
by the user before saving the value to the config.
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.
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
Improve the properties API so that it can actually respond somewhat to
user input. Maybe later this might be further improved or replaced with
something script-based.
When creating a property, you can now add a callback to that property
that notifies when the property has been changed in the user interface.
Return true if you want the properties to be refreshed, or false if not.
Though now that I think about it I doubt there would ever be a case
where you would have this callback and *not* refresh the properties.
Regardless, this allows functions to change the values of properties or
settings, or enable/disable/hide other property controls from view
dynamically.
- 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.
- Fix a bug where the initial audio data insertion would cause all
audio data to unintentionally clear (mixed up < and > operators, damn
human error)
- Fixed a potential interdependant lock scenario with channel mutex
locks and graphics mutex locks. The main video thread could lock the
graphics mutex and then while in the graphics mutex could lock the
channels mutex. Meanwhile in another thread, the channel mutex could
get locked, and then the graphics mutex would get locked, causing a
deadlock.
The best way to deal with this is to not let mutexes lock within
other mutexes, but sometimes it's difficult to avoid such as in the
main video thread.
- Audio devices should now be functional, and the devices in the audio
settings can now be changed as desired.