Commit graph

196 commits

Author SHA1 Message Date
0c237d6e8a
avcodec/ffv1: simplify version checks with combined_version
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-01-21 21:06:13 +01:00
5e4a510cce
ffv1dec: move slice decoding into a separate function
This simply movies all slice decoding code from decode_frame
to decode_slices; nothing more.
2025-01-22 00:09:38 +09:00
f75812e054
ffv1dec: move header parsing into a separate function 2025-01-22 00:09:38 +09:00
d987feae2a
ffv1dec: move slice start finding into a function
This also cleans up and gives the code some much needed comments.
2025-01-22 00:09:37 +09:00
7187eadf8c
ffv1dec: use dedicated pix_fmt field and call ff_get_format
Adding support for hwaccels means that avctx->pix_fmt will indicate
hardware formats.
2025-01-22 00:09:37 +09:00
Anton Khirnov
56ba57b672 lavc/refstruct: move to lavu and make public
It is highly versatile and generally useful.
2024-12-15 14:03:47 +01:00
967e5e8f6f
avcodec/ffv1: Support slice coding mode 1 with golomb rice
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-11-16 13:24:15 +01:00
2c71366d3b
avcodec/ffv1: Implement new slice tiling
This fixes corner cases (requires version 4 or a spec update)

Fixes: Ticket5548

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-10-24 23:01:14 +02:00
2542e9296c
avcodec/ffv1: RCT is only possible with RGB
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-10-16 21:41:18 +02:00
10e5af15bf
avcodec/ffv1dec: Fix end computation with ec=2
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-10-14 22:31:26 +02:00
7bb283aa7b
avcodec/ffv1: Implement CRC with non zero initial and final value
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-10-10 19:34:10 +02:00
747e1a26af
avcodec/ffv1dec: Blow up if user asks for explosion
Fixes: Ticket8403

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-09-25 19:45:28 +02:00
Anton Khirnov
8d5efc2182 lavc/ffv1dec: fix races in accessing FFV1SliceContext.slice_damaged
That variable is shared between frame threads in the same defective way
described in the previous commit. Fix it by adding a RefStruct-managed
arrays of flags that is propagated across frame threads in the standard
manner.

Remove now-unused FFV1Context.fsrc
2024-08-12 14:42:20 +02:00
Anton Khirnov
15bdca054f lavc/ffv1dec: drop code handling AV_PIX_FMT_FLAG_PAL
No paletted pixel formats are supported by the decoder.
2024-08-12 14:42:20 +02:00
Anton Khirnov
bcf08c1171 lavc/ffv1: change FFV1SliceContext.plane into a RefStruct object
Frame threading in the FFV1 decoder works in a very unusual way - the
state that needs to be propagated from the previous frame is not decoded
pixels(¹), but each slice's entropy coder state after decoding the slice.

For that purpose, the decoder's update_thread_context() callback stores
a pointer to the previous frame thread's private data. Then, when
decoding each slice, the frame thread uses the standard progress
mechanism to wait for the corresponding slice in the previous frame to
be completed, then copies the entropy coder state from the
previously-stored pointer.

This approach is highly dubious, as update_thread_context() should be
the only point where frame-thread contexts come into direct contact.
There are no guarantees that the stored pointer will be valid at all, or
will contain any particular data after update_thread_context() finishes.

More specifically, this code can break due to the fact that keyframes
reset entropy coder state and thus do not need to wait for the previous
frame. As an example, consider a decoder process with 2 frame threads -
thread 0 with its context 0, and thread 1 with context 1 - decoding a
previous frame P, current frame F, followed by a keyframe K. Then
consider concurrent execution consistent with the following sequence of
events:
* thread 0 starts decoding P
* thread 0 reads P's slice header, then calls
  ff_thread_finish_setup() allowing next frame thread to start
* main thread calls update_thread_context() to transfer state from
  context 0 to context 1; context 1 stores a pointer to context 0's private
  data
* thread 1 starts decoding F
* thread 1 reads F's slice header, then calls
  ff_thread_finish_setup() allowing the next frame thread to start
  decoding
* thread 0 finishes decoding P
* thread 0 starts decoding K; since K is a keyframe, it does not
  wait for F and reallocates the arrays holding entropy coder state
* thread 0 finishes decoding K
* thread 1 reads entropy coder state from its stored pointer to context
  0, however it finds state from K rather than from P

This execution is currently prevented by special-casing FFV1 in the
generic frame threading code, however that is supremely ugly. It also
involves unnecessary copies of the state arrays, when in fact they can
only be used by one thread at a time.

This commit addresses these deficiencies by changing the array of
PlaneContext (each of which contains the allocated state arrays)
embedded in FFV1SliceContext into a RefStruct object. This object can
then be propagated across frame threads in standard manner. Since the
code structure guarantees only one thread accesses it at a time, no
copies are necessary. It is also re-created for keyframes, solving the
above issue cleanly.

Special-casing of FFV1 in the generic frame threading code will be
removed in a later commit.

(¹) except in the case of a damaged slice, when previous frame's pixels
    are used directly
2024-08-01 10:09:26 +02:00
Anton Khirnov
c335218a81 lavc/ffv1dec: inline copy_fields() into update_thread_context()
It is now only called from a single place, so there is no point in it
being a separate function.
2024-08-01 10:09:26 +02:00
Anton Khirnov
d44812f7cf lavc/ffv1dec: stop using per-slice FFV1Context
All remaining accesses to them are for fields that have the same value
in the main encoder context.

Drop now-unused FFV1Context.slice_contexts.
2024-08-01 10:09:26 +02:00
Anton Khirnov
2b21cdff6e lavc/ffv1dec: move slice_damaged to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
f2aeba56c4 lavc/ffv1dec: move slice_reset_contexts to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
96e8af6c4d lavc/ffv1: move ac_byte_count to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
7b2bfba55d lavc/ffv1: move RangeCoder to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
28769f6bc1 lavc/ffv1: move FFV1Context.plane to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
9b86ba5a92 lavc/ffv1: always use the main context values of ac
It cannot change between slices.
2024-08-01 10:09:26 +02:00
Anton Khirnov
a57c88d67b lavc/ffv1: move FFV1Context.slice_{coding_mode,rct_.y_coef} to per-slice context 2024-08-01 10:09:26 +02:00
Anton Khirnov
39486a2b29 lavc/ffv1: always use the main context values of plane_count/transparency
They cannot change between slices.
2024-08-01 10:09:26 +02:00
Anton Khirnov
a411fc5a84 lavc/ffv1: drop redundant PlaneContext.quant_table
It is a copy of FFV1Context.quant_tables[quant_table_index].
2024-08-01 10:09:26 +02:00
Anton Khirnov
4b9f7c7e3a lavc/ffv1: drop redundant FFV1Context.quant_table
In all cases except decoding version 1 it's either not used, or contains
a copy of a table from quant_tables, which we can just as well use
directly.

When decoding version 1, we can just as well decode into
quant_tables[0], which would otherwise be unused.
2024-08-01 10:09:26 +02:00
Anton Khirnov
889faedd26 lavc/ffv1dec: move the bitreader to stack
There is no reason to place it in persistent state.
2024-08-01 10:09:25 +02:00
Anton Khirnov
19e9f3d5f2 lavc/ffv1: move run_index to the per-slice context 2024-08-01 10:09:25 +02:00
Anton Khirnov
91d3c1ac47 lavc/ffv1: move sample_buffer to the per-slice context 2024-08-01 10:09:25 +02:00
Anton Khirnov
54aa33f116 lavc/ffv1: add a per-slice context
FFV1 decoder and encoder currently use the same struct - FFV1Context -
both as codec private data and per-slice context. For this purpose
FFV1Context contains an array of pointers to per-slice FFV1Context
instances.

This pattern is highly confusing, as it is not clear which fields are
per-slice and which per-codec.

Address this by adding a new struct storing only per-slice data. Start
by moving slice_{x,y,width,height} to it.
2024-08-01 10:09:25 +02:00
Anton Khirnov
d845ea49c5 lavc/ffv1dec: move copy_fields() under HAVE_THREADS
It is unused otherwise
2024-08-01 10:09:25 +02:00
Anton Khirnov
3a5c814b19 lavc/ffv1dec: drop a pointless variable in decode_slice()
fsdst is by construction always equal to fs, there is even an
av_assert1() checking that. Just use fs directly.
2024-08-01 10:09:25 +02:00
Anton Khirnov
4da146ba83 lavc/ffv1dec: drop FFV1Context.cur
It is merely a pointer to FFV1Context.picture.f, which can just as well
be used directly.
2024-08-01 10:09:25 +02:00
Anton Khirnov
e1fa107fd1 lavc/ffv1dec: simplify slice index calculation 2024-08-01 10:09:25 +02:00
Anton Khirnov
d776fa4e4d lavc/ffv1dec: declare loop variables in the loop where possible 2024-08-01 10:09:25 +02:00
Andreas Rheinhardt
ac8288e288 avcodec/ffv1dec: Switch to ProgressFrames
Avoids implicit av_frame_ref() and therefore allocations
and error checks. It also avoids explicitly allocating
the AVFrames (done implicitly when getting the buffer).

It also fixes a data race: The AVFrame's sample_aspect_ratio
is currently updated after ff_thread_finish_setup()
and this write is unsynchronized with the read in av_frame_ref().
Removing the implicit av_frame_ref() fixed this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-04-19 13:18:04 +02:00
Andreas Rheinhardt
2b46ae6407 avcodec/codec_internal: Remove FF_CODEC_CAP_ALLOCATE_PROGRESS
Before commit f025b8e110,
every frame-threaded decoder used ThreadFrames, even when
they did not have any inter-frame dependencies at all.
In order to distinguish those decoders that need the AVBuffer
for progress communication from those that do not (to avoid
the allocation for the latter), the former decoders were marked
with the FF_CODEC_CAP_ALLOCATE_PROGRESS internal codec cap.

Yet distinguishing these two can be done in a more natural way:
Don't use ThreadFrames when not needed and split ff_thread_get_buffer()
into a core function that calls the user's get_buffer2 callback
and a wrapper around it that also allocates the progress AVBuffer.
This has been done in 02220b88fc
and since that commit the ALLOCATE_PROGRESS cap was nearly redundant.

The only exception was WebP and VP8. WebP can contain VP8
and uses the VP8 decoder directly (i.e. they share the same
AVCodecContext). Both decoders are frame-threaded and VP8
has inter-frame dependencies (in general, not in valid WebP)
and therefore the ALLOCATE_PROGRESS cap. In order to avoid
allocating progress in case of a frame-threaded WebP decoder
the cap and the check for the cap has been kept in place.

Yet now the VP8 decoder has been switched to use ProgressFrames
and therefore there is just no reason any more for this check
and the cap. This commit therefore removes both.

Also change the value of FF_CODEC_CAP_USES_PROGRESSFRAMES
to leave no gaps.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-04-19 13:18:04 +02:00
Andreas Rheinhardt
790f793844 avutil/common: Don't auto-include mem.h
There are lots of files that don't need it: The number of object
files that actually need it went down from 2011 to 884 here.

Keep it for external users in order to not cause breakages.

Also improve the other headers a bit while just at it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-03-31 00:08:43 +01:00
Andreas Rheinhardt
315c956cbd avcodec/pthread_frame: Remove ff_thread_release_buffer()
It is unnecessary since the removal of non-thread-safe callbacks
in e0786a8eeb. Since then, the
AVCodecContext has only been used as logcontext.

Removing ff_thread_release_buffer() allowed to remove AVCodecContext*
parameters from several other functions (not only unref functions,
but also e.g. ff_h264_ref_picture() which calls ff_h264_unref_picture()
on error).

Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-22 22:09:59 +02:00
Andreas Rheinhardt
bdbf9aa402 avcodec/ffv1dec: Reindent after the previous commit
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-09-30 23:05:42 +02:00
Andreas Rheinhardt
0cfc7418bb avcodec/ffv1dec: Fix data races emanating from copying whole context
When using frame threading, the FFV1 decoder's update_thread_context()
function copies the whole context and afterwards restores some allocated
fields with backups made earlier. Among these fields are the
ThreadFrames and the source context's ThreadFrames can change
concurrently without any synchronization, leading to data races which
are undefined behaviour even if they don't lead to problems in
practice (as the destination's own ThreadFrames are restored directly
thereafter).

Fix this by only copying the actually needed fields.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-09-30 23:05:42 +02:00
Paul B Mahol
3bbc7d799c avcodec/ffv1*: add GBRAP14, GRAY14, YUVA422P12, YUVA444P12 formats support 2023-09-29 18:59:08 +02:00
James Almer
dc7bd7c5a5 avcodec: use the new AVFrame key_frame flag in all decoders and encoders
Signed-off-by: James Almer <jamrial@gmail.com>
2023-05-04 18:48:22 -03:00
James Almer
2f561ba953 avcodec: use the new AVFrame interlace flags in all decoders and encoders
Signed-off-by: James Almer <jamrial@gmail.com>
2023-05-04 18:14:02 -03:00
Jerome Martinez
f0cd5610e0
avcodec/ffv1dec: reject unsupported ffv1 versions
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-04-06 00:50:01 +02:00
8ead0ae68e
avcodec/ffv1dec: Check that num h/v slices is supported
Fixes: out of array access
Fixes: 55597/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FFV1_fuzzer-4898293416329216

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-02-23 23:17:08 +01:00
74b6ac7ebb
avcodec/ffv1dec: restructure slice coordinate reading a bit
Fixes: signed integer overflow: -1094995528 * 8224 cannot be represented in type 'int'
Fixes: 53508/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FFV1_fuzzer-474551033462784

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2022-11-28 21:20:56 +01:00
4df91e2215
avcodec/ffv1dec: Fail earlier if prior context is corrupted
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2022-10-20 21:42:20 +02:00
Andreas Rheinhardt
e0c01a62ad avcodec/(ffv1|h264|png|snow)dec: Remove comment out DRAW_HORIZ_BAND cap
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-10-20 06:57:30 +02:00