1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-02-04 06:08:26 +02:00

108 Commits

Author SHA1 Message Date
Anton Khirnov
56ff01e6ec pthread_frame: use av_buffer_replace() to simplify code 2020-09-28 11:33:36 +02:00
Anton Khirnov
f1feb3bd9d pthread_frame: change the criterium for updating thread contexts
Currently the next thread's context is updated from the previous one's
if the codec descriptor is not marked as intra-only. That is not
entirely correct, since that property does not necessarily imply
anything about how a specific decoder implementation behaves.

Instead, use the presence of the update_thread_context() callback to
decide whether an update should be performed. Fixes races in CFHD,
should cause no behaviour change in any other decoders.
2020-07-07 11:03:09 +02:00
Anton Khirnov
6943ab688d pthread_frame: change the way delay is set
It is a constant known at codec init, so set it in
ff_frame_thread_init(). Also, only set it for video, since the meaning
of this field is not well-defined for audio with frame threading.

Fixes availability of delay in callbacks invoked from the per-thread
contexts after 1f4cf92cfbd3accbae582ac63126ed5570ddfd37.
2020-06-09 12:45:57 +02:00
Mark Thompson
2594f6a362 lavc: Rename hwaccel.h to hwconfig.h
This already applied to decoders as well as hwaccels, and adding encoder
support was going to make the name even more inaccurate.
2020-04-26 18:38:25 +01:00
Anton Khirnov
9d6785d426 lavc: do not implicitly share the frame pool between threads
Currently the frame pool used by the default get_buffer2()
implementation is a single struct, allocated when opening the decoder.
A pointer to it is simply copied to each frame thread and we assume that
no thread attempts to modify it at an unexpected time. This is rather
fragile and potentially dangerous.

With this commit, the frame pool is made refcounted, with the reference
being propagated across threads along with other context variables. The
frame pool is now also immutable - when the stream parameters change we
drop the old reference and create a new one.
2020-04-10 15:47:30 +02:00
Anton Khirnov
2944537430 pthread_frame: do not copy a range of AVCodecContext fields at once
This is extremely fragile against reordering and hides what is actually
being copied. Copy all the fields manually instead.
2020-04-10 15:46:09 +02:00
Anton Khirnov
b630a270f5 pthread_frame: do not embed full AVFrame structs into per-thread contexts
Use the AVFrame API to properly allocate and free frames for delayed
release.
2020-04-10 15:45:16 +02:00
Anton Khirnov
e40107c1ad pthread_frame: do not share priv_data between multiple codec contexts
Specifically, between the user-facing one and the first frame thread
one.

This is fragile and dangerous, allocate separate private data for each
per-thread context.
2020-04-10 15:44:15 +02:00
Anton Khirnov
1f4cf92cfb pthread_frame: merge the functionality for normal decoder init and init_thread_copy
The current design, where
- proper init is called for the first per-thread context
- first thread's private data is copied into private data for all the
  other threads
- a "fixup" function is called for all the other threads to e.g.
  allocate dynamically allocated data
is very fragile and hard to follow, so it is abandoned. Instead, the
same init function is used to init each per-thread context. Where
necessary, AVCodecInternal.is_copy can be used to differentiate between
the first thread and the other ones (e.g. for decoding the extradata
just once).
2020-04-10 15:24:54 +02:00
Anton Khirnov
665e5b0fba lavc: replace AVCodecInternal.allocate_progress with an internal cap
This is a constant codec property, so a capability flag is more appropriate.
2020-04-10 14:16:39 +02:00
Anton Khirnov
e923a35988 pthread_frame: make sure ff_thread_release_buffer always cleans the frame 2020-04-10 13:51:23 +02:00
Linjie Fu
091341f2ab lavc/pthread_frame: Update user context in ff_frame_thread_free
Resolution/format changes lead to re-initialization of hardware
accelerations(vaapi/dxva2/..) with new hwaccel_priv_data in
the worker-thread. But hwaccel_priv_data in user context won't
be updated until the resolution changing frame is output.

A termination with "-vframes" just after the reinit will lead to:
    1. memory leak in worker-thread.
    2. double free in user-thread.

Update user context in ff_frame_thread_free with the last thread
submit_packet() was called on.

To reproduce:
ffmpeg -hwaccel vaapi(dxva2) -v verbose -i
    fate-suite/h264/reinit-large_420_8-to-small_420_8.h264 -pix_fmt nv12
    -f rawvideo -vsync passthrough -vframes 47 -y out.yuv

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2020-03-27 10:57:40 +01:00
James Almer
c666689491 avcodec: add an AVCodecContext field to signal types of packet, frame, and coded stream side data to export
Add an initial mvs flag to is, analog to the export_mvs flags2 one.

Signed-off-by: James Almer <jamrial@gmail.com>
2020-02-22 23:19:07 -03:00
Jun Zhao
3ad0e6724d lavc/pthread: use THREAD_SAFE_CALLBACKS() to simplifx more code
use THREAD_SAFE_CALLBACKS() to simplifx more code

Signed-off-by: Jun Zhao <mypopydev@gmail.com>
2018-08-31 11:08:24 +08:00
James Almer
23e1bf6e51 avcodec: remove unnecessary calls to ff_init_buffer_info()
And remove the function altogether while at it. It's a duplicate of
another.

Reviewed-by: wm4 <nfxjfg@googlemail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
2018-02-14 20:54:20 -03:00
wm4
9b121dfc32 w32pthreads: always use Vista+ API, drop XP support
This removes the XP compatibility code, and switches entirely to SWR
locks, which are available starting at Windows Vista.

This removes CRITICAL_SECTION use, which allows us to add
PTHREAD_MUTEX_INITIALIZER, which will be useful later.

Windows XP is hereby not a supported build target anymore. It was
decided in a project vote that this is OK.
2017-12-26 02:49:48 +01:00
James Almer
21add0c228 avcodec/pthread_frame: remove usage of AVCodecContext accessors
Signed-off-by: James Almer <jamrial@gmail.com>
2017-11-15 01:14:22 -03:00
James Almer
2ccd00dabd Merge commit '5182a28b5de060c51c21b36053ab205bfbbbbe31'
* commit '5182a28b5de060c51c21b36053ab205bfbbbbe31':
  lavc: Drop deprecated global afd field

Merged-by: James Almer <jamrial@gmail.com>
2017-10-23 16:31:50 -03:00
James Almer
8a0954dd51 avcodec: add missing FF_API_DEBUG_MV wrappers
Signed-off-by: James Almer <jamrial@gmail.com>
2017-08-25 13:44:52 -03:00
Wan-Teh Chang
58fbcf885d pthread_frame: revert 2e664b9c1e73c80aab91070c1eb7676f04bdd12d.
The patch does not fix the tsan warning it was intended to fix.
Reverting the patch moves the av_log() back to the outside of the lock.

Signed-off-by: Wan-Teh Chang <wtc@google.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
2017-07-27 17:14:17 -04:00
Wan-Teh Chang
15c41cb6ad pthread_frame: save the FF_DEBUG_THREADS option in PerThreadContext.
Add the debug_threads boolean field to PerThreadContext. For
PerThreadContext *p, p->debug_threads records whether the
FF_DEBUG_THREADS bit is set in p->avctx->debug, and p->debug_threads and
p->avctx->debug are kept in sync. The debug_threads field is defined as
an atomic_int to allow atomic read by another thread in
ff_thread_await_progress().

This fixes the tsan warning that
2e664b9c1e73c80aab91070c1eb7676f04bdd12d attempted to fix:

WARNING: ThreadSanitizer: data race (pid=452658)
  Write of size 4 at 0x7b640003f4fc by main thread (mutexes: write M248499):
    #0 update_context_from_user [..]/libavcodec/pthread_frame.c:335:19 (5ab42bb1a6f4b068d7863dabe9b2bacc+0xe73859)
[..]
  Previous read of size 4 at 0x7b640003f4fc by thread T130 (mutexes: write M248502, write M248500):
    #0 ff_thread_await_progress [..]/libavcodec/pthread_frame.c:591:26 (5ab42bb1a6f4b068d7863dabe9b2bacc+0xe749a1)

Signed-off-by: Wan-Teh Chang <wtc@google.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
2017-07-11 21:27:35 -04:00
Muhammad Faiz
d535e0c140 avcodec/pthread_frame, decode: allow errors to happen on draining
So, all frames and errors are correctly reported in order.
Also limit the numbers of error during draining to prevent infinite loop.

This fix fate failure with THREADS>=4:
  make fate-h264-attachment-631 THREADS=4
This also reverts a755b725ec1d657609c8bd726ce37e7cf193d03f.

Suggested-by: wm4, Ronald S. Bultje, Marton Balint
Reviewed-by: w4 <nfxjfg@googlemail.com>
Reviewed-by: Ronald S. Bultje <rsbultje@gmail.com>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
2017-04-30 05:48:21 +07:00
James Almer
1fd7627770 Merge commit '549d0bdca53af7a6e0c612ab4b03baecf3a5878f'
* commit '549d0bdca53af7a6e0c612ab4b03baecf3a5878f':
  decode: be more explicit about storing the last packet properties

Also copy pkt->size in extract_packet_props(), as it's needed for
AVFrame.pkt_size

Merged-by: James Almer <jamrial@gmail.com>
2017-04-22 20:06:47 -03:00
Ronald S. Bultje
2e664b9c1e pthread_frame: make accesses to debug field be protected by owner lock.
The av_log() is done outside the lock, but this way the accesses to the
field (reads and writes) are always protected by a mutex. The av_log()
is not run inside the lock context because it may involve user callbacks
and doing that in performance-sensitive code is probably not a good idea.

This should fix occasional tsan warnings when running fate-h264, like:

WARNING: ThreadSanitizer: data race (pid=10916)
  Write of size 4 at 0x7d64000174fc by main thread (mutexes: write M2313):
    #0 update_context_from_user src/libavcodec/pthread_frame.c:335 (ffmpeg+0x000000df7b06)
[..]
  Previous read of size 4 at 0x7d64000174fc by thread T1 (mutexes: write M2311):
    #0 ff_thread_await_progress src/libavcodec/pthread_frame.c:592 (ffmpeg+0x000000df8b3e)
2017-04-07 13:29:45 -04:00
wm4
15a23a8332 pthread_frame: don't return stale error codes after flush
Consider the following sequence of events:

- open a codec without AV_CODEC_CAP_DELAY
- decode call fails with an error
- ff_thread_flush() is called
- drain packet is sent

Then the last step would make ff_thread_decode_frame() return an error,
because p->result can still be set to an error value. This is because
submit_packet returns immediately if AV_CODEC_CAP_DELAY is not set, and
no worker thread gets the chance to reset p->result, yet its value is
trusted by ff_thread_decode_frame().

Fix this by clearing the error fields on flush.
2017-04-06 17:46:53 +02:00
Ronald S. Bultje
083300bea9 pthread_frame: allow per-field ThreadFrame owners.
This tries to handle cases where separate invocations of decode_frame()
(each running in separate threads) write to respective fields in the
same AVFrame->data[]. Having per-field owners makes interaction between
readers (the referencing thread) and writers (the decoding thread)
slightly more optimal if both accesses are field-based, since they will
use the respective producer's thread objects (mutex/cond) instead of
sharing the thread objects of the first field's producer.

In practice, this fixes the following tsan-warning in fate-h264:

WARNING: ThreadSanitizer: data race (pid=21615)
  Read of size 4 at 0x7d640000d9fc by thread T2 (mutexes: write M1006):
    #0 ff_thread_report_progress pthread_frame.c:569 (ffmpeg:x86_64+0x100f7cf54)
[..]
  Previous write of size 4 at 0x7d640000d9fc by main thread (mutexes: write M1004):
    #0 update_context_from_user pthread_frame.c:335 (ffmpeg:x86_64+0x100f81abb)
2017-04-06 10:03:27 -04:00
Ronald S. Bultje
1269cd5b6f pthread_frame: call update_context_from_user() after acquiring lock.
Otherwise the thread may still be in the middle of decoding a previous
frame, which would effectively trigger a race condition on any field
concurrently read and written.

In practice, this fixes tsan warnings like the following:

WARNING: ThreadSanitizer: data race (pid=17380)
  Write of size 4 at 0x7d64000160fc by main thread:
    #0 update_context_from_user src/libavcodec/pthread_frame.c:335 (ffmpeg+0x000000dca515)
[..]
  Previous read of size 4 at 0x7d64000160fc by thread T2 (mutexes: write M1821):
    #0 ff_thread_report_progress src/libavcodec/pthread_frame.c:565 (ffmpeg+0x000000dcb08a)
2017-04-03 09:48:53 -04:00
Mark Thompson
ebce133228 pthread_frame: Propagate sw_pix_fmt across threads
This is required by the VP9 hwaccels (both DXVA2 and VAAPI) when
threads are enabled.

Tested-by: Hendrik Leppkes <h.leppkes@gmail.com>
2017-03-31 00:23:02 +01:00
wm4
4cf1f68903 pthread_frame: minor simplification to error handling
Get rid of the "ret" variable, and always use err. Report the packet as
consumed if err is unset. This should be equivalent to the old code,
which obviously required err=0 for p->result>=0 (and otherwise,
p->result must have had the value err was last set to). The code block
added by commit 32a5b631267 is also not needed anymore, because the new
code strictly returns err if it's >=0.

Reviewed-by: "Ronald S. Bultje" <rsbultje@gmail.com>
2017-03-29 12:17:40 +02:00
Ronald S. Bultje
027ee9b3ed pthread_frame: don't sync items between threads for intra-only codecs.
Intra-only codecs should either be able to read these items from the
bitstream, or they should be set upon codec initialization. In both
cases, syncing these items at runtime is unnecessary.

In practice, this fixes race conditions for decoders that read these
values from the bitstream.
2017-03-28 18:04:27 -04:00
wm4
d7896e9b42 pthread_frame: fix uninitialized variable read
Could lead to random behavior. This possibly happened due to commit
32a5b631267. This should/could probably be simplified, but for no apply
a minimal fix to quell the errors.

Tested-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
2017-03-27 13:21:20 +02:00
wm4
9e703ae30f pthread_frame: do not attempt to unlock a mutex on the wrong thread
async_mutex has is used in a very strange but intentional way: it is
locked by default, and unlocked only in regions that can be run
concurrently.

If the user was calling API functions to the same context from different
threads (in a safe way), this could unintentionally unlock the mutex on
a different thread than the previous lock operation. It's not allowed by
the pthread API.

Fix this by emulating a binary semaphore using a mutex and condition
variable. (Posix semaphores are not available on all platforms.)

Tested-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
2017-03-27 13:21:15 +02:00
Vittorio Giovara
5182a28b5d lavc: Drop deprecated global afd field
Deprecated in 08/2014.
2017-03-23 10:09:16 +01:00
wm4
156bd8278f lavc: Add hwaccel_flags field to AVCodecContext
This "reuses" the flags introduced for the av_vdpau_bind_context() API
function, and makes them available to all hwaccels. This does not affect
the current vdpau API, as av_vdpau_bind_context() should obviously
override the AVCodecContext.hwaccel_flags flags for the sake of
compatibility.

Cherry-picked from Libav commit 16a163b5.

Reviewed-by: Mark Thompson <sw@jkqxz.net>
2017-03-23 09:34:21 +01:00
wm4
2e5c52896b pthread_frame: remove some dead code
Whatever it was supposed to do.
2017-03-21 06:17:43 +01:00
Anton Khirnov
e0cd598bc4 pthread_frame: do not run hwaccel decoding asynchronously unless it's safe
Certain hardware decoding APIs are not guaranteed to be thread-safe, so
having the user access decoded hardware surfaces while the decoder is
running in another thread can cause failures (this is mainly known to
happen with DXVA2).

For such hwaccels, only allow the decoding thread to run while the user
is inside a lavc decode call (avcodec_send_packet/receive_frame).

Merges Libav commit d4a91e65.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
Tested-by: Michael Niedermayer <michael@niedermayer.cc>
2017-03-21 06:17:28 +01:00
Anton Khirnov
14bb15bfd5 pthread_frame: ensure the threads don't run simultaneously with hwaccel
Merges Libav commit 8dfba25c.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
Wan-Teh Chang
c358c62550 pthread_frame: use better memory orders for frame progress
This improves commit 59c70227405c214b29971e6272f3a3ff6fcce3d0.

In ff_thread_report_progress(), the fast code path can load
progress[field] with the relaxed memory order, and the slow code path
can store progress[field] with the release memory order. These changes
are mainly intended to avoid confusion when one inspects the source code.
They are unlikely to have measurable performance improvement.

ff_thread_report_progress() and ff_thread_await_progress() form a pair.
ff_thread_await_progress() reads progress[field] with the acquire memory
order (in the fast code path). Therefore, one expects to see
ff_thread_report_progress() write progress[field] with the matching
release memory order.

In the fast code path in ff_thread_report_progress(), the atomic load of
progress[field] doesn't need the acquire memory order because the
calling thread is trying to make the data it just decoded visible to the
other threads, rather than trying to read the data decoded by other
threads.

In ff_thread_get_buffer(), initialize progress[0] and progress[1] using
atomic_init().

Signed-off-by: Wan-Teh Chang <wtc@google.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>

Merges Libav commit 343e2833.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
Mark Thompson
fb69a8e1f1 pthread_frame: Unreference hw_frames_ctx on per-thread codec contexts
When decoding with threads enabled, the get_format callback will be
called with one of the per-thread codec contexts rather than with the
outer context.  If a hwaccel is in use too, this will add a reference
to the hardware frames context on that codec context, which will then
propagate to all of the other per-thread contexts for decoding.  Once
the decoder finishes, however, the per-thread contexts are not freed
normally, so these references leak.

Merges Libav commit fd0fae60.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
Anton Khirnov
98f89d615b pthread_frame: properly propagate the hw frame context across frame threads
Merges Libav commit 84f22568.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
Anton Khirnov
b6587421c7 pthread_frame: use atomics for frame progress
Merges Libav commit 59c70227.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
Anton Khirnov
7492626932 pthread_frame: use atomics for PerThreadContext.state
Merges Libav commit 64a31b28.

Signed-off-by: wm4 <nfxjfg@googlemail.com>
2017-03-21 06:16:49 +01:00
wm4
16a163b55a lavc: Add hwaccel_flags field to AVCodecContext
This "reuses" the flags introduced for the av_vdpau_bind_context() API
function, and makes them available to all hwaccels. This does not affect
the current vdpau API, as av_vdpau_bind_context() should obviously
override the AVCodecContext.hwaccel_flags flags for the sake of
compatibility.
2017-03-20 23:15:43 +00:00
Michael Niedermayer
1e5cfad57e avcodec/pthread_frame: Check av_packet_ref() for failure
Fixes CID1396242
2017-02-06 01:01:33 +01:00
Clément Bœsch
a91c265f39 lavc/pthread_frame: protect read state access in setup finish function 2017-01-16 10:43:41 +01:00
Anton Khirnov
d4a91e6534 pthread_frame: do not run hwaccel decoding asynchronously unless it's safe
Certain hardware decoding APIs are not guaranteed to be thread-safe, so
having the user access decoded hardware surfaces while the decoder is
running in another thread can cause failures (this is mainly known to
happen with DXVA2).

For such hwaccels, only allow the decoding thread to run while the user
is inside a lavc decode call (avcodec_send_packet/receive_frame).
2016-12-19 08:10:22 +01:00
Anton Khirnov
8dfba25ce8 pthread_frame: ensure the threads don't run simultaneously with hwaccel 2016-12-19 08:09:19 +01:00
Wan-Teh Chang
343e283399 pthread_frame: use better memory orders for frame progress
This improves commit 59c70227405c214b29971e6272f3a3ff6fcce3d0.

In ff_thread_report_progress(), the fast code path can load
progress[field] with the relaxed memory order, and the slow code path
can store progress[field] with the release memory order. These changes
are mainly intended to avoid confusion when one inspects the source code.
They are unlikely to have measurable performance improvement.

ff_thread_report_progress() and ff_thread_await_progress() form a pair.
ff_thread_await_progress() reads progress[field] with the acquire memory
order (in the fast code path). Therefore, one expects to see
ff_thread_report_progress() write progress[field] with the matching
release memory order.

In the fast code path in ff_thread_report_progress(), the atomic load of
progress[field] doesn't need the acquire memory order because the
calling thread is trying to make the data it just decoded visible to the
other threads, rather than trying to read the data decoded by other
threads.

In ff_thread_get_buffer(), initialize progress[0] and progress[1] using
atomic_init().

Signed-off-by: Wan-Teh Chang <wtc@google.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2016-12-14 11:16:51 +01:00
Anton Khirnov
549d0bdca5 decode: be more explicit about storing the last packet properties
The current code stores a pointer to the packet passed to the decoder,
which is then used during get_buffer() for timestamps and side data
passthrough. However, since this is a pointer to user data which we do
not own, storing it is potentially dangerous. It is also ill defined for
the new decoding API with split input/output.

Fix this problem by making an explicit internally owned copy of the
packet properties.
2016-12-14 09:06:44 +01:00
Mark Thompson
fd0fae6037 pthread_frame: Unreference hw_frames_ctx on per-thread codec contexts
When decoding with threads enabled, the get_format callback will be
called with one of the per-thread codec contexts rather than with the
outer context.  If a hwaccel is in use too, this will add a reference
to the hardware frames context on that codec context, which will then
propagate to all of the other per-thread contexts for decoding.  Once
the decoder finishes, however, the per-thread contexts are not freed
normally, so these references leak.
2016-11-10 20:36:11 +00:00