Fixes the following warning:
warning C4505: 'operator ==' : unreferenced local function has been
removed
This function actually is used despite this warning, so the only way to
get rid of the warning is to disable the warning itself in this
particular case.
Currently creating new sources can cause a deadlock:
OBSBasicSourceSelect locks the scene mutex when adding a new source
(required to add invisible sources), and later OBSBasic tries to
lock the graphics mutex (via CreatePropertiesWindow); meanwhile the
graphics thread is holding the graphics mutex and tries to lock each
scene as it renders them, resulting in a (non-obvious from the code)
lock ordering conflict.
Moving the CreatePropertiesWindow call out of the locked scene mutex
restores the previous lock ordering; in addition, the requirement
for keeping sourceSceneRefs for opening that initial properties
window is removed
API removed:
--------------------
gs_effect_t *obs_get_default_effect(void);
gs_effect_t *obs_get_default_rect_effect(void);
gs_effect_t *obs_get_opaque_effect(void);
gs_effect_t *obs_get_solid_effect(void);
gs_effect_t *obs_get_bicubic_effect(void);
gs_effect_t *obs_get_lanczos_effect(void);
gs_effect_t *obs_get_bilinear_lowres_effect(void);
API added:
--------------------
gs_effect_t *obs_get_base_effect(enum obs_base_effect effect);
Summary:
--------------------
Combines multiple near-identical functions into a single function with
an enum parameter.
Use explicit UTF-8 byte sequence for the "no-break space" character.
Prevents issues with certain editors, and fixes the following compiler
warning on Visual C++:
warning C4819: The file contains a character that cannot be represented
in the current code page (X). Save the file in Unicode format to prevent
data loss
(Jim) For some reason a character outside of the standard ASCII
character set was used in this source file. "Eight Spoked Asterisk",
Unicode character 0x02733. Non-ASCII characters should probably not be
used directly in source files due to potential character encoding
issues that can occur depending on the operating system and compiler.
Closesjp9000/obs-studio#485
Note: This functionality should probably be considered as a temporary
solution. Ideally, sources should not be visible on creation until the
user presses "OK" in the initial properties dialog. Also, the problem
of initial visibility can additionally be solved by implementing the
preview/program functionality. Once preview/program is implemented the
need for this patch will be negated, and the option should probably be
removed.
Closesjp9000/obs-studio#483
RemoveScene would always remove the currently selected item from the
scenes list, even if that item didn't reference the actual scene being
removed; finding the proper item via its OBSRef fixes this issue.
How to reproduce the original issue:
Create two scenes "a" and "b", set a hotkey for switching to scene "a",
select scene "b" and press the remove scene button, then while the
confirmation dialog is up press the hotkey while the UI is out of focus.
The active scene should have switched to "a", while the dialog still
displays "b" as its target; now confirm the removal of "b". Note how "a"
was removed from the scenes list instead.
Reported at https://obsproject.com/mantis/view.php?id=333
This reverts commit 35b2ce565a.
There is far too much potential for issues to occur if the first-time
start creates a display capture by default on linux and windows.
Display capture on windows laptops will not be guaranteed to capture
properly, leaving the user with a blank screen. Display capture on
linux downloads its image off the graphics processor, so it's quite
inefficient to have on by default.
When an encoder has been removed (such as CoreAudio) and the audio
bitrates currently configured no longer are available to the current
audio encoders anymore, it would cause GetAACEncoderForBitrate to return
false with no encoder available.
To fix the issue, instead just choose the closest bitrate relative to
the current bitrate (rounded up).
After some more testing, utvideo not only gives better encoding
performance, but also better compression and better decoding
performance. It's pretty much superior all around over huffyuv.
So certain high-profile individuals were complaining that it was
difficult to configure recording settings for quality in OBS. So, I
decided to add a very easy-to-use auto-configuration for high quality
encoding -- including lossless encoding. This feature will
automatically configure ideal recording settings based upon a specified
quality level.
Recording quality presets added to simple output:
- Same as stream: Copies the encoded streaming data with no extra usage
hit.
- High quality: uses a higher CRF value (starting at 23) if using x264.
- Indistinguishable quality: uses a low CRF value (starting at 16) if
using x264.
- Lossless will spawn an FFmpeg output that uses huffyuv encoding. If a
user tries to select lossless, they will be warned both via a dialog
prompt and a warning message in the settings window to ensure they
understand that it requires tremendous amounts of free space. It will
always use the AVI file format.
Extra Notes:
- When High/Indistinguishable quality is set, it will allow you to
select the recording encoder. Currently, it just allows you to select
x264 (at either veryfast or ultrafast). Later on, it'll be useful to
be able to set up pre-configured presets for hardware encoders once
more are implemented and tested.
- I decided to allow the use of x264 at both veryfast or ultrafast
presets. The reasoning is two-fold:
1.) ultrafast is perfectly viable even for near indistinguishable
quality as long as it has the appropriate CRF value. It's nice if you
want to record but would like to or need to reduce the impact of
encoding on the CPU. It will automatically compensate for the preset at
the cost of larger file size.
2.) It was suggested to just always use ultrafast, but ultrafast
requires 2-4x as much disk space for the same CRF (most likely due to
x264 compensating for the preset). Providing veryfast is important if
you really want to reduce file size and/or reduce blocking at lower
quality levels.
- When a recording preset is used, a secondary audio encoder is also
spawned at 192 bitrate to ensure high quality audio. I chose 192
because that's the limit of the media foundation aac encoder on
windows, which I want to make sure is used if available due to its
high performance.
- The CRF calculation is based upon resolution, quality, and whether
it's set to ultrafast. First, quality sets the base CRF, 23 for
"good" quality, 16 for "very high" quality. If set to ultrafast,
it'll subtract 2 points from the CRF value to help compensate. Lower
resolutions will also lower the CRF value to help improve higher
details with a smaller pixel ratio.
Selecting any supported FFmpeg format where ff_format_desc_extensions
returns NULL would crash the std::string constructor, so we pass an
empty extension instead (rtsp is one candidate format that triggers
the crash, on my machine at least)
The user may not want their audio or their display to be captured when
creating a new scene collection. Make new scene collections default to
fully empty.
For the sake of consistency, always create a display capture source on
the very first run of the program, just to have something displayed.
(NOTE: The only exception here is on windows 7/vista, which isn't ideal
for display capture, so it'll continue to be left blank)
CBR is now always on by default for streaming, so there's no reason to
have a setting for this in particular. Still available in advanced
output settings of course, but simple output mode really should be kept
as simple as possible.
This is mostly just to remove the unnecessary clutter from the output
sections. The reconnect settings are generally rarely modified by users
as it is.
When stream delay is active, the "Start/Stop Streaming" button is
changed in to a menu button, which allows the user to select either the
option to stop the stream (which causes it to count down), or forcibly
stop the stream (which immediately stops the stream and cuts off all
delayed data).
If the user decides they want to start the stream again while in the
process of counting down, they can safely do so without having to wait
for it to stop, and it will schedule it to start up again with the same
delay after the stop.
On the status bar, it will now show whether delay is active, and its
duration. If the stream is in the process of stopping/starting, it will
count down to the stop/start.
If the option to preserve stream cutoff point on unexpected
disconnections/reconnections is enabled, it will update the current
delay duration accordingly.
I added stream delay options to advanced settings not just because I
feel it's an advanced option, but also to reduce clutter in the outputs
section and its sub-sections, which already have far too many options as
it is.
This reverts commit a508c17f0a.
I realized that this would become more of an annoyance for most people
rather than anything helpful. This has only happened only twice that I
am aware of in all the years that the program has been around.
Limits similar log entries (determined by a simple hash function that
sums the characters) to certain number of lines in a row. When a
different log entry occurs, it resets the repeat check and logs how many
times the last message was repeated.
Due to certain design changes for delay, it's better to simply determine
whether outputs are active via booleans rather than an activeRefs
variable, which could get decremented more than once if say, the signal
for stopping the stream gets called more than once for whatever reason
(which may happen in the case of delay due to the way delay works)
Replaces all the json/config loading/saving functions with safe
variants to reduce the chance of potential file corruption as much as
possible.
Also does a minor refactor of json writing by using
obs_data_save_json_safe for writing json files instead of manually using
obs_data_get_json and os_quick_write_utf8 each time.
API Changed:
---------------------------
From:
- bool obs_startup(const char *locale, profiler_name_store_t *store);
To:
- bool obs_startup(const char *locale, const char *module_config_path,
profiler_name_store_t *store);
Summary:
---------------------------
This allows plugin modules to store plugin-specific configuration data
(rather than only allowing objects to store configuration data). This
will be useful for things like caching data, for example looking up and
storing ingests from remote (rather than storing locally), or caching
font data (so it doesn't have to build a font cache each time), among
other things.
Also adds a module-specific directory for the UI
If a user was using FFmpeg output before pathc 0.12.0, they had to type
in the full file name to the FFmpeg output URL/Path box, which isn't
exactly compatible with the new settings.
This changes each profile's config file so that the FFmpeg output
detects whether files are used, and then extracts the file's directory
and extension and sets them accordingly to make it compatible with the
new FFmpeg file output handling.
This changes the way the advanced output section's FFmpeg output
settings work by allowing the user to select whether they want to output
to a file or output to a URL, and makes it so file names are
automatically generated like other recording outputs.
If they choose to output to a file, it'll only require an output
directory similarly to how other recording outputs work. They can
select a directory to output to rather than being required to type in a
full path and filename; the filename is automatically generated. The
extension is also automatically retrieved from libff depending on the
format selected.
Otherwise if they have Output to URL selected, it'll show a simple edit
box where they can type in the target URL.
Apparently using QPointer container for the QObject being given to the
connect function makes it so it can't find the actual function to use.
I'm guessing this is incomplete functionality or a bug that existed in
GCC 4.8. Doesn't happen in 4.9+.
When settings the base resolution, try to find the closest output
resolution to the old output resolution, and use that for its value. If
the aspect ratio is about the same, then don't modify the value. If the
aspect ratio is significantly different, then find the closest
approximation while keeping with the new aspect ratio.
This particular issue has been an annoyance for quite some time.
Due to all the threads in libobs it wouldn't be safe to make that
parameter reconfigurable after libobs is initialized without adding
even more synchronization. On the other hand, adding a function to set
the name store before calling obs_startup would solve the problem of
passing a name store into libobs, but it can lead to more complicated
semantics for obs_get_profiler_name_store (e.g., should it always return
the current name store even if libobs isn't initialized until someone
calls set_name_store(NULL)? should obs_shutdown call
set_name_store(NULL)? Passing it as obs_startup parameter avoids
these (and hopefully other) potential misunderstandings
Fixes a minor bug introduced by the windowless graphics context merge.
When setting a new base resolution, it would not recalculate the preview
size, and the preview would display the wrong size until the main window
was resized by the user. This patch makes it so that it calls the
recalculation function when the base resolution is changed to prevent
that from happening.
Now that we aren't dependent upon a window for our context, we can
safely move the obs context creation/destruction to obs-app.cpp, and use
the OBSContext helper class to automatically shut down obs.
(Non-compiling commit: windowless-context branch)
Now that all obs_display related code has been moved to OBSQTDisplay,
we can prune a whole bunch of boilerplate code that had to be repeated
for the displays of each window.
Affects:
- Properties
- Filters
- Interact
- Projector
(Non-compiling commit: windowless-context branch)
Gets rid of all functions/data related to setting up the main preview to
be associated with obs_reset_video and instead uses OBSQTDisplay for the
main window display (thus associating it with an obs_display object).
(Non-compiling commit: windowless-context branch)
This makes it so that OBSQTDisplay now uses/controls an obs_display
object directly (rather than having the owner have to associate an
OBSDisplay with it). It was separated before because the main window
for the basic UI would was using the "main preview" stuff before the
windowless context and had to be handled differently, so you couldn't
just associate an obs_display object with OBSQTDisplay, meaning that all
"secondary" previews such as properties/filters/etc had to handle the
obs_display alone, which caused a lot of needlessly duplicated code.
Also adds a DisplayCreated signal to allow owners to be able to add
callbacks and such on creation of the actual obs_display context.
Found via clang-3.6, actual warning:
window-basic-main.hpp:406:14: warning: 'GetProfilePath' overrides
a member function but is not marked 'override'
[-Winconsistent-missing-override]
Adds Microsoft Media Foundation AAC Encoder that supports
96k to 192k bitrates. This plugin is only enabled on Microsoft
Windows 8+ due to performance issues found on Windows 7.
I broke the save that happens on exit by making all project saves put on
the message queue. The save on exit would put the save on to the
message queue, then by the time the save occurred obs would already be
shut down.
This just calls the save function directly rather than deferring it to
the message queue.
This temporarily fixes an issue where potential (for whatever reason)
stray sources that aren't associated with any scenes could be saved and
then persist with the save data on load.
SaveProject calls obs functions that locks certain mutexes, and because
I made it so that SaveProject was being called inside of certain signal
handlers (which could already be locked in other mutexes), it could
cause a mutual deadlock with other threads.
This fix puts the main project saving code in to SaveProjectDeferred,
then pushes it on to the Qt message queue to safely save outside of
those locks. It's a function that's perfectly safe to put on the
message queue because it will automatically be disabled in certain
circumstances where it would be unsafe to call, such as on shutdown.
This code will also make it so that the project will not needlessly be
saved more than once if the SaveProjectDeferred call was pushed multiple
times on to the queue.
It currently says "Update check: latest version is x.x.x", which is a
bit confusion. It should say "Update check: last known remote version
is x.x.x" instead.
This makes it so that the log message for altering scene collections
and/or profiles is now below, and then the separator below that. This
makes it a bit more apparent that any loading/clearing/etc that happens
before the log message are associated with the log message.
Previously the sourceSceneRefs were being cleaned up in
OBSBasic::SceneItemRemoved; due to changes in
e82018579b the signal handler that called
OBSBasic::SceneItemRemoved is now being removed before the scene
triggers its item_remove signals
Adds setting profiles to the basic user interface. For each profile, a
subdirectory for the profile will be created in
[config_dir]/obs-studio/basic/profiles which will contain the settings
data for each profile.
Adds scene collections to the menu bar, which allows you to duplicate,
rename, remove, or add clean new scene collections.
Scene files are now stored in ./obs-studio/basic/scenes directory with
filesystem-safe names.
Originally this value defaulted to 1.5 downscaling, but on very high
resolution displays this would cause the default to be above 1280x720,
which is not ideal for streaming/recording due to the CPU usage
requirements.
Instead, it will now find the closest resolution with a pixel count
equivalent to or closest below 1280x720, and use that instead.
This prevents the weird stretching effect that occurs whenever a windows
is in the process of being resized by the user.
Originally it was intended as an optimization, but even on half-decent
computers it doesn't really have much benefit.
Apparently some raw lingering pointers to the item widgets may be
present inside of the QListView if you delete the item widgets directly,
and the only way to ensure those pointers are properly cleared is to
call ->clear() on the list widget instead of deleting each item
individually.
We were deleting each item individually because we thought that
->deleteLater might be also be called on other data within, but after
some testing, that turned out to not be the case, so it's safe to call
->clear() on the list widget.
As a note, deleting item widgets directly is dangerous due to the
potential for lingering raw internal pointers, and our case is unique
where we can get away with it; do not delete list item widgets directly
unless you intend on calling ->clear() or ->takeItem on the specific
item you do it to after.
Again, the reason why we are deleting list widget items manually is due
to the fact that Qt will always use ->deleteLater() on them if they are
not deleted manually, which puts their deletion on the queue. Only
problem is they cannot be removed from the queue once added, so
lingering references to sources will persist until the queue processes
them, which causes major problems if we need those objects deleted right
away.
When initializing with a default scene, save the data to ensure a file
is actually present when needed (such as for scene collections which may
need the file)
Add a central function for clearing all data: scenes, sources, widgets
such as lists that may contain source references in their sub-items,
dialogs which may contain source references. In certain circumstances
this data must be fully released and manually freed to ensure that there
are no outstanding references to obs data (such as on shutdown, where
all data should be properly freed).
These functions are designed to manually delete item widgets within
other widgets to prevent ->deleteLater from being called on them. This
prevents the item widgets from being stuck in the event queue, and
prevents references to things like sources from being stuck in the event
queue along with them if they're used in the item widget's class or
functions.
Right now, information about global audio sources is stored in both
scene files and in the config. These must be separated; there's no need
to store them in both when they can just be stored in the scenes file.
When using e.g. a color correction filter on any source and changing
any value (with slider enabled, e.g. contrast) to -0.10 the value would
get cycle between -0.07/-0.08 at some point when using the up arrow; it
would also get stuck on -0.69.
For the other direction, when starting from e.g. -0.02 the value would
jump from 0.05 to -0.08 when pressing the down arrow.
Problem was reported at https://obsproject.com/forum/threads/32450
The empty implementation for the QDataStream operators is necessary to fix
a Qt assertion: "QVariant::save: unable to save type
'std::vector<std::shared_ptr<OBSSignal> >' (type id: 1036)."
It doesn't seem like a full implementation of the stream operators would be
useful since the signal registration is very specific to the interaction
between the scenes and sources list, i.e. in case the scenes list ever accepts
scenes from sources (not 'obs_source's) other than itself (non InternalMove
drag&drop?) it would have to register those scenes with the libobs core which
should trigger the normal signal registration
Use the config button on volume controls to allow the ability for
filters/properties to be accessed via the mixer. Particularly useful
for the purpose of accessing filters/properties of global audio outputs
that are added via audio settings.
This simply saves/loads the actual list widget item order.
The reason why this is done is because internally, libobs doesn't have a
list of scenes, it only has a list of sources. The list of scenes is
actually something artificially implemented by the basic window user
interface.
Certain output formats don't support multiple tracks, so it's important
to warn the user if they select multiple tracks.
Also warn the user if they select no tracks.
The audio bitrate required is insignificant relative to the video
bitrate, and due to the fact that it's possible that a lower-quality
encoder may be in use (such as FFmpeg's AAC encoder), setting the
default to 160 is really more ideal to reducee any potential quality
loss.
Ensures that the "Show Recordings" an "Remux Recordings" file menu
items will open the recordings folder from the currently active
output mode rather than always the simple output mode.
On windows vista/7, you cannot really use display capture efficiently
without disabling aero, so this will add an option to settings to allow
it to be disabled and cause it to be disabled on startup.
Portable mode can be enabled via command line options (--portable or -p)
or by having any of the following files present in the base directory of
a portable install:
portable_mode
obs_portable_mode
portable_mode.txt
obs_portable_mode.txt
Portable mode is omitted when obs is built with a unix program
structure.
In my recent update to add a "show" button to the passworded text
property, I neglected to connect the edit widget to
WidgetInfo::ControlChanged, so it isn't able to detect when the text is
changed by the user.
The Qt5Network classes seem to only support OpenSSL, and because OpenSSL
isn't available on windows, we would have to distribute it with the
program to get SSL access working. The problem with that is that
OpenSSL is not GPL-compatible, so we cannot distribute OpenSSL with the
program, which means we have to find a better (and preferably superior)
library for accessing remote files that can use the windows SSPI for our
SSL needs, which comes with the operating system.
Fortunately, libcurl is probably the best library out there, and can be
compiled with SSPI instead of OpenSSL, so we're just going to switch to
libcurl instead. Originally I thought it didn't support SSPI, otherwise
I would have implemented it sooner.
As a side note, this will make it so we'll able to get files from the
internet via plugins, which will be quite useful.
The RemoteTextThread class is a QThread that is used to get text
remotely in a separate thread with libcurl. This is intended to replace
the Qt5Network classes because of their dependency on OpenSSL, which we
can't distribute.
Reduces required scrolling when lots of new audio sources are added
(e.g. aux devices being enabled in the same dialog) when the dialog
was opened with just a few audio sources being present. Unfortunately,
the "restart required" warning is pushed all the way to the bottom
even if the source list is empty
This should allow entering alt + numpad N (N > 0) on windows since there
doesn't seem to be a way to completely ignore input events generated
from "alt codes"
UI supplied per scene hotkey to allow switching between scenes; this
has to be done in the UI since it's up to the application to define
what exactly "changing/selecting a scene" means (changing the output
of channel 0 may not be enough for other applications)
OBSHotkeyEdit is similar to QKeySequenceEdit, except less terribad on OSX, while
OBSHotkeyWidget provides a container that automagically encapsulates multiple
bindings per hotkey
OBSHotkeyLabel in combination with OBSHotkeyWidget provides mechanisms for
dealing with hotkey pairs (see upcoming usage in window-basic-settings.cpp)
When a reconnect is occurring, the user doesn't really know that the
program is waiting to reconnect to the server or not, nor does the user
know how many seconds are remaining until that next attempt. This will
show the reconnect timeout countdown as it's occurring.