The recent changes in 88ae9af causes av_read_frame to check for
m->stopping, and fail with AVERROR_EXIT if true, which would happen
after each reset. Moving mp_media_prepare_frames to a line after
m->stopping is reset to false fixes the issue.
With certain media files (wmv in particular), the very last frame will
have a timestamp of AV_NOPTS_VALUE. This could cause the media to stick
on that frame indefinitely. Instead, use the estimated next timestamp
that was calculated in the previous frame.
Media files that have a very low framerate or very long interval between
frames would cause the media playback to stall indefinitely until the
next frame is played. This adds a 200ms timeout to ensure that the
media can be destroyed without being forced to wait indefinitely for the
next frame.
Certain functions such as avformat_open_input and av_read_frame can
block, causing the program to someone wait very long periods of time
when a network URL is used with the media source. The
interrupt_callback member variable in AVFormatContext allows safely
canceling IO operations when trying to shut down or stop the
media-playback interface.
(Note: This commit also modifies deps/media-playback)
Allows buffering network-based media sources where supported. Default
is two megabytes of buffering.
Currently, when media-playback is used with a network address, video has
to wait for the first keyframe before it starts decoding. This is
probably not wise because the first packet of video may contain
additional header information, and because audio is forced to wait and
buffer while waiting for a keyframe, potentially causing a lot of audio
to get backed up unnecessarily which could inadvertently cause sync or
audio playback issues.
So, instead of waiting for a keyframe before decoding starts, decode
right away, and make it wait for a keyframe before calling the video
callback instead.
When media returns frames with negative linesizes, it means they're
inverted RGB formats and start from the last line of the image and move
back to the top via the negative linesize number. This would cause a
crash because this wasn't being taken in to account, and it would
traverse in to invalid memory.
Fixes potential decoding errors with FFmpeg's new decode API. Because
avcodec_send_packet may process multiple packets, you must call
avcodec_receive_frame continually until no more frames are left.
Failure to decode is unfortunately quite common with certain file types,
and is most of the time safely recoverable. There's no reason to
actually output a log message for this unless really needed.
Intended to replace libff as the media playback library. Intended to
use less threads and be more extensible. It was nearly impossible to
modify libff without bursting a vein.
In some cases the result of the compatability check is wrong.
For example the format "mpegts" only shows "mpeg2video" as an
encoder even though other codecs such as h.264 are supported by
ffmpeg's muxer for that container and are used within that container
in some applications.
Closesjp9000/obs-studio#804
FFmpeg by default decodes VP8/VP9 via its internal encoders, however
those internal encoders do not support alpha. Encoded alpha is stored
via meta/side data in the container, so the only way to decode it
properly is via forcing FFmpeg to use libvpx for decoding.
(Note: This commit also modifies the ipc-util/seg-service modules)
When compiling the final project, always compile
ipc-util/get-graphics-offsets/graphics-hook/inject-helper/seg-service
with static MSVC runtimes to prevent the need of requiring the MSVC
runtimes for both architectures.
(Also modifies obs-ffmpeg to handle empty frames on EOF)
Previously the demuxer could hit EOF before the decoder threads are
finished, resulting in truncated output. In the worse case scenario the
demuxer could read small files before ff_decoder_refresh even has a chance
to start the clocks, resulting in no output at all.
How to crash:
1. Use recent ffmpeg shared libraries.
2. Add a ffmpeg_source, a small static picture (e.g. jpeg) with loop
3. After a while of high cpu usage, it crashed. Seems reproduced more
easily on faster computer
Closes#533
There's no need to duplicate the packet as the reference count will be 1
after the av_read_frame call. Duplicating causes heap corruption when a
synthetic clock packet is duplicated and assigned the buffer from the
stack-based temporary packet which is then double-freed by the decoder
thread.
avformat_free_context() only frees the memory used by an AVFormatContext
but it does not close the opened media file. This causes a leaked file
descriptor every time a media source frees a demuxer. Using
avformat_close_input() instead frees the context and closes the media
file.
Fixes warnings with deprecated packet functions (av_free_packet and
av_dup packet, which were replaced by av_packet_unref and av_packet_ref
respectively)
Just in case glSwapIntervalEXT and glSwapIntervalSGI aren't available
for whatever reason. This entire patch is most likely completely
redundant on modern mesa drivers.
This allows plugins to update and cache data files from a remote source.
Here are the steps that occur when the API initiates an update check:
1.) It checks to see if the local files are greater than the cached
files. If the local version is newer (for whatever reason), it
replaces the cached version(s) with the local version.
2.) A packages.json file is downloaded from the specified URL. That
packages.json file contains a version number and a list of files to
be updated.
3.) If the downloaded package version is greater than the cached
version, executes step 4-5 on each file.
4.) Checks the version for the file to update in packages.json, and if
the version is greater than the cached version, proceeds to step 5,
otherwise repeat step 4-5 for other files.
5.) Calls the callback given to the update function (if any) with the
file information (file name, buffer, etc), and if the callback
returns true, allows the cached file to be updated and replaced,
otherwise goes back to step 4-6 for the rest of the files.
NOTE: Files are never modified directly. All file saving/modification
is performed in a temporary directory, and then files are moved to their
destination. This should eliminate any possibility of file corruption
(or at least dramatically reduce the possibility).
If the first guessed pts is less than the start_pts, it could
lead to a negative PTS being returned.
Change the behavior so that the first frame's pts, if zero, is
set to the start_pts. If more than one frame is less than the
start_pts, the start_pts is determined invalid and set to 0.
Valid start_pts example:
start_pts = 500
first frame (pts = 0)
pts = 500 (< start_pts)
pts -= 500 (offset by start_pts)
ret 0
second frame (pts = 700)
pts = 700 (no change, > start_pts)
pts -= 500 (offset by start_pts)
ret 200
Invalid start_pts example:
start_pts = 500
first frame (pts = 0)
pts = 500 (< start_pts)
pts -= 500 (offset by start_pts)
ret 0
second frame (pts = 300)
pts = 300 (< start_pts, start_pts set to 0)
pts -= 0 (start_pts is now 0)
ret 300