Sometimes when reconnecting the internal RTMP data is not cleared
(particularly the TLS data). This can cause TLS data to carry over from
one connection to another, causing issues with the secondary connection.
From Windows 7 onwards, dynamic send buffering is enabled. By setting
SO_SNDBUF explicitly, we actually disabled the dynamic send buffering
feature which results in reduced throughput. Thankfully this did not
affect the majority of users since the default send buffer is usually
already 64k.
This commit replaces the setting of SO_SNDBUF with log output showing
the current value of SO_SNDBUF at stream start and end. This will aid in
debugging throughput issues caused by a buffer that isn't big enough,
perhaps as a result of the user disabling dynamic send buffering
system-wide.
Since this is activated after starting the output, it assumes there is
no need to read anything from the connection as RTMP is send-only from
that point on. However with TLS, reading protocol messages is required
for proper operation, causing it to immediately fail on RTMPS
connections. This is a complex fix due to the way it interacts with
librtmp and mbedTLS so let's just disable it for now to avoid breaking
things for users.
Bug is caused by the internal connection variables not being reset on
reconnect, leading OBS to both be unable to parse valid packets from and
send valid packets to the remote end. This commit splits RTMP_Init off
into a new RTMP_Reset function, which resets these internal variables
without re-initing the rest of the library. The original RTMP_Init
calls the new function, perfectly preserving the old behaviour while
adding a new reset function to address the issue with.
Fixesobsproject/obs-studio#2865
RTMP authentication requires the curStreamIdx and nStreams be set
between the disconnect / reconnect that occurs in PublisherAuth. Now
that there's no good place to clean them up, zero the whole rtmp->Link
before starting a new stream.
Every addStream call would increment this counter. After merging the
mbedTLS fixes, we no longer have extraneous RTMP_Init calls which were
masking the prescence of this bug. This caused every stream after the
first stream to have the wrong channel index, and eventually OBS would
crash due to an out of bounds write if the counter reached
RTMP_MAX_STREAMS.
Though this should now be very rare, it's more helpful than "Failed to
connect to server". Other TLS error codes are now also stored for future
use instead of copying them on a case by case basis.
Per mbedtls documentation, "If you share a context between threads, you
need to call these functions only from the main thread, at the beginning
and end of the context's lifetime.". OBS violated this since librtmp
uses a global context and it was allocated and freed in different
threads such as the auto config test.
This commit attaches the mbedtls context to an RTMP structure so there
is no more global state. It also fixes a rare double-free crash that
could occur if RTMP_TLS_Free was called twice (this happened in rare
situations such as the auto config running followed by a mode change
from Advanced to Simple).
The dynamic bitrate operates based upon estimating the current bitrate
output, and then adjusting the bitrate on the fly as necessary when
congestion is detected as a replacement for dropping frames.
This may still need adjustment, as it is difficult to accurately emulate
real-world frame drop scenarios. This does not currently drop frames at
all, and because of that, very high congestion may cause additional
stream delay to viewers (because data will be buffered), but from
limited testing, most congestion will not cause that and it can safely
recover pretty quickly without adding significant delay.
When doing the bitrate limit test, it can be useful to have the ability
to change the current maximum bitrate limit. This adds the ability to
press keys on windows (numpad 0-6) to change between bitrates. Numpad 0
being no limit, 1 being 1000, 2 being 2000, etc.
Code submissions have continually suffered from formatting
inconsistencies that constantly have to be addressed. Using
clang-format simplifies this by making code formatting more consistent,
and allows automation of the code formatting so that maintainers can
focus more on the code itself instead of code formatting.
(This commit also modifies the UI, obs-ffmpeg, and obs-output modules)
Fixes a long-time regression where the program would lock up if an
encode call fails. Shuts down all outputs associated with the failing
encoder and displays an error message to the user.
Ideally, it would be best if a more detailed error could be displayed to
the user about the nature of the error, though the primary problem is
the encoder errors are typically not something the user would be able to
understand. The current message is a bit of a generic error message;
improvement is welcome.
Another suggestion is to try to have the encoder restart seamlessly,
though it would take a significant amount of work to be able to make it
do something like that properly, and it sort of assumes that encoder
failures are sporadic, which may not necessarily be the case with some
hardware encoders on some systems. It may be better just to use another
encoder in that case. For now, seamless restart is ruled out.
This diff adds mbedTLS support to the obs-outputs plugin. PolarSSL and
mbedTLS have grown so different between 2015-or-so when libRTMP was
written, and now it's no longer feasible to just use the USE_POLARSSL
flag.
This commit adds a WITH_RTMPS tri-state CMake variable (auto/on/off),
set to "Auto" by default. "Auto" will use RTMPS if mbedTLS is found,
otherwise will disable RTMPS. "On" will make it require mbedTLS,
otherwise fails configuration, and "Off" disables RTMPS support
altogether.
Closesobsproject/obs-studio#1360
The new code in 3032535f56 would signal that the output has stopped to
the back-end and front-end, but the event used in the outputs themselves
to shut down the send thread would still be signaled, causing the next
connection to immediately stop as soon as it had started. This fixes it
so that the event does not get signaled unless the thread is active.
(This commit also modifies the obs-outputs module)
The first video packet video offset (the value used to set the starting
point of video data) would be set to the DTS value of the first video
packet. However, when b-frames are used, the first DTS value will be
negative. This was originally done because FLV muxing requires that the
first packet's DTS start from 0. Unfortunately, this would also
effectively cause the first packet's PTS/DTS value to be shifted forward
by the negative amount, which would cause video sync to be off by a
video frame or two.
This fixes it to start at the PTS value instead and preserve any
negative offsets. Additionally, the FLV muxing code has been fixed to
ensure that it adjusts the starting video DTS to 0, and now correctly
adjusts the first audio packet's timestamp according to that DTS as well
(which it didn't do before).
Some encoders such as the AMD AMF encoder don't set their bitrate
property, so it gets returned as 0. This causes the new network code to
allocate a tiny buffer, resulting in output starvation and throttling
to the point of uselessness if low latency mode is also enabled.
x264 on ultrafast won't drop any b-frames, so it might buffer packets a
bit too much in that case.
The frame drop duration calculation now searches for the first valid
video frame within the packets buffer. Additionally, it no longer
prevents frame dropping for a specific time after dropping frames,
because the first case eliminates the need for that.
Clears/reinitializes RTMP structure to defaults, preventing data from
potentially persisting between different connections.
Closesjp9000/obs-studio#878
There are two variables used for 'priority', the general marked frame
priority, and the drop priority. They can sometimes be different
because some encoders don't always use the correct frame priority.
The maximum shutdown timeout value was added as a setting, but never
actually fully implemented. This implements it properly, and sets its
default timeout value to 30 seconds.