This fixes a bug where the new circular buffer code is hit by protocols
such as rist or srt although the buffer was meant for files.
Signed-off-by: pkv <pkv@obsproject.com>
This adds a circular buffer to ffmpeg-mux when writing to a file.
Output from ffmpeg is buffered so that slow disk I/O does not block
ffmpeg writes, as this causes the pipe to become full and OBS stops
sending frames with a misleading "Encoding overloaded!" warning. The
buffer may grow to 256 MB depending on the rate of data coming in and
out, if the buffer is full OBS will start waiting in ffmpeg writes.
A separate I/O thread is responsible for processing the contents of
the buffer and writing them to the output file. It tries to process 1 MB
at a time to minimize small I/O.
Complicating things considerably, some formats in ffmpeg require seeking
on the output, so we can't just treat everything as a stream of bytes.
To handle this, we record offsets of each write and try to buffer as
many contiguous writes as possible. This unfortunately makes the code
quite complicated, but hopefully well commented.
Previously SPEAKER_4POINT0 was assigned to AV_CH_LAYOUT_QUAD, but later
was changed to AV_CH_LAYOUT_4POINT0 [1]. The change was forgotten in
obs-ffmpeg-mux. This is remedied here.
[1] 67e48ecc2c
Signed-off-by: pkv <pkv@obsproject.com>
The channel_layout API was overhauled by FFmpeg [1-4]. The previous
bitmask channel_layout is replaced by a struct ch_layout which combines
the number of channels, a bitmask and other infos. This struct must now
be supplied to AVframes since avutil >= 57.24.100 and to
AVCodecContext since avcodec 59.24.100 per (1].
This commit provides the required info to ffmpeg-mux,
obs-ffmpeg-output & to obs-ffmpeg-audio-encoders.
[1] Bump minor versions after the channel layout changes
cdba98bb80
[2] lavc: switch to the new channel layout API
548aeb9383
[3] avutil/channel_layout: Add a new channel layout API
086a804806
[4] avframe: switch to the new channel layout API db6efa18
db6efa1815
Signed-off-by: pkv <pkv@obsproject.com>
Want to avoid receiver gamut remapping from Rec. 2100 to P3.
Fix min luminance appearing as NaN by switching from 0/0 to 0/1.
Also set max luminance for HLG because why not.
stdout on Windows from a subprocess requires that something read the
stdout buffer, and currently we don't do that. Due to newly introduced
printf/fprintf calls, the stdout buffer eventually fills up because
nothing is emptying it, thus the muxer locks up on an fprintf/printf
call and causes OBS itself to hang.
sizeof(AVPacket) being a part of the public ABI is deprecated. once
av_init_packet() is removed, new packets will only be able to be
allocated with av_packet_alloc().
In ffmpeg-mux, ffmpeg-vaapi, and obs-ffmpeg-nvenc, AVPacket is allocated
at the initialization to avoid frequent allocation of AVPacket.
Includes changes to win-dshow.
avcodec.h stopped including channel_layout.h per FFmpeg commit
1be3d8a0cb77 [1]. Fixes compilation error on macOS against
FFmpeg later than the mentioned commit.
[1] 1be3d8a0cb
This commit adds 3 new properties to split output file in the output
`ffmpeg_muxer`.
- `max_time_sec` specifies the limit in seconds.
- `max_size_mb` specifies the limit in megabytes.
- `allow_overwrite` specifies to test an existing file.
If both `max_time_sec` and `max_size_mb` are not positive, the split
file feature won't be enabled.
Another output ffmpeg_mpegts_muxer shares the code but is not affected
since the output is used only for streaming.
This commit fixes an issue that the last audio packet is sometimes not
written into mp4 format. Since libavformat internally calculates the
packet duration from the frame_size specified in the codec parameter, it
is necessary to set frame_size.
AVFormatContext::oformat was made const on April 27, 2021 [1]. If we
respect the constness of AVOutputFormat and do not cast results from
FFmpeg functions to non-const, we cannot modify the results after the
fact. Our choices are either to cast them to non-const (and presumably
have them implicitly casted back to const on later function calls), or
only try to modify the results in versions of FFmpeg where these are not
expected to be const.
Instead of relying on casts, we can set the encoder values in the
ffmpeg_cfg struct, which are later passed to new_stream.
Also modifies deps/media-playback. Removes compiler warnings.
Some avformat functions return const AV(In/Out)putFormat per [1], so
ifdef as needed.
[1]: 56450a0ee4
lavf 59.0.100 avformat.h
avformat: Constify the API wrt AV(In|Out)putFormat
Also constify AVProbeData.
FFmpeg commit e67e02d15672 [1] drops avcodec.h from avformat.h includes.
Therefore we need to include it explicitly.
[1]: e67e02d156
lavf/avformat.h: drop the avcodec.h include
This adds RIST to the list of protocols supported by the obs
ffmpeg_mpegts_muxer.
RIST is container and codec agnostic. But this implementation relies
on ffmpeg avformat integration and uses mpeg-ts container.
If DEBUG_FFMPEG_MUX is enabled, when starting a recording without
configuring global_stream_key, obs-ffmpeg-mux will hang. Apply same
check to global_stream_key as in init_params() to prevent this.
4f873376 as part of PR #3460 changed ffmpeg_mux_packet to
fail = !ffmpeg_mux_packet. ffe4c855 only reverted that one line
instead of the entire previous commit. When the change was
reintroduced in 6071098a as part of PR #3740, it became
fail = ffmpeg_mux_packet without the negation.
This commit reverts db1e6aa and fixes the logic check.
ffmpeg-mux does not notice if ffmpeg returns an error from
av_interleaved_write_frame() which means that OBS never knows if there
is a problem in ffmpeg.
This is the biggest issue for cases like srt:// or tcp:// streams that
can regularly fail. Without this change OBS never knows that something
went wrong.
Only network streams are checked to prevent impacting potential
transient errors in recordings.
This reverts commit 4f87337646f4db0d50a4ebb257faf0640a729805.
Reverting the line in 4f87337646f4d causing issues until it can be
properly investigated.
For some reason, currently unknown, FFmpeg logging has to be set to
something in order for HLS to not fail on Windows, even if it's just an
empty function.
(Author comment: I don't feel comfortable not knowing why, my theory is
that FFmpeg has an issue with this internally with HLS on Windows
related to logging or how it's trying to log, I have absolutely no idea
what's going on and if someone can enlighten me or debug FFmpeg itself
it'd be real nice to know why.)
Adds a cmake variable (DEBUG_FFMPEG_MUX) which enables FFmpeg debug
output in the ffmpeg-mux subprocess, and if on Windows, shows the
console window of the ffmpeg-mux subprocess so the current output can be
seen.
Add and register an obs_output_info struct called
ffmpeg_hls_muxer. It uses ffmpeg's HLS muxer to stream output.
Add threading and buffer to reduce skipped frames.
Also add frame drop logic when there are too many packets in the
buffer for congestion control.
(Jim) Allows the ability to use stream keys with ffmpeg-mux -- this will
enable the ability to use it with certain services (such as YouTube)
which allow different protocols (such as HLS)
(Jim) printable_file allows the ability to keep a separate string for
logging which will not contain things like stream keys when used with
outputs such as HLS.
ffmpeg-mux does not notice if ffmpeg returns an error from
av_interleaved_write_frame() which means that OBS never knows if there is a
problem in ffmpeg.
This is the biggest issue for cases like srt:// or tcp:// streams that can
regularly fail. Without this change OBS never knows that something went wrong.
Add support for VIDEO_CS_SRGB.
Use SMPTE 170M for 601 instead of undef/BT470BG. This is the
American/Chromium way of handling 601.
Add color metadata to the container file as well via ffmpeg-mux.
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.
Instead of having ffmpeg-mux stored in a data directory, install it to
the primary binary directory. On windows, this fixes ffmpeg-mux
potentially accessing the wrong FFmpeg libraries (some programs install
them to system32, foolishly), and instead ensures that it uses the ones
that come with the program. On Linux, ensures that a binary is in its
appropriate directory (/usr/bin or /usr/local/bin rather than a subset
of /usr/share or /usr/local/share).