Commit graph

824 commits

Author SHA1 Message Date
Marton Balint
ec4d3dc5b9 avcodec/mpegvideo_enc: use 64bit multiplication in dct_quantize_trellis_c and dct_quantize_c
Fixes corruption with:

ffmpeg -t 1 -filter_complex "sine=f=21,showwaves=scale=cbrt:mode=line:colors=white:draw=full" -c:v mpeg2video -non_linear_quant 1 -qmin 1 -qmax 1 -cpuflags 0 out.mpg

or

ffmpeg -t 1 -filter_complex "sine=f=21,showwaves=scale=cbrt:mode=line:colors=white:draw=full" -c:v mpeg2video -non_linear_quant 1 -qmin 1 -qmax 1 -trellis 1 out.mpg

Signed-off-by: Marton Balint <cus@passwd.hu>
2025-01-25 20:10:41 +01:00
Marton Balint
ed26812337 avcodec/mpegvideo_enc: fix qmat value comments
The comments supposed to track the possible value of the qmat and qmat16
matrices, but they were not updated properly in the long history of the
mpegvideo encoder. Also they wrongly assumed the usage of built-in quantizer
matrices and linear quantization.

Signed-off-by: Marton Balint <cus@passwd.hu>
2025-01-25 20:10:41 +01:00
Marton Balint
7d9f373984 avcodec/mpegvideo_enc: add checks for custom inter/intra/chroma matrices
Make the checker functions available for all codecs.

Signed-off-by: Marton Balint <cus@passwd.hu>
2025-01-25 20:10:41 +01:00
Michael Niedermayer
827c073154
avcodec/mpegvideo_enc: Check FLV1 resolution limits
Found-by: Elias Myllymäki <elias.myllymaki04p@gmail.com>
Reviewed-by: Alexander Strasser <eclipse7@gmx.net>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-01-15 01:27:46 +01: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
Michael Niedermayer
9c8881cb35
avcodec/mpegvideo_enc: Do not duplicate pictures on shifting
Fixes: out of array access
Fixes: 69098/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MPEG2VIDEO_fuzzer-6107989688778752
Fixes: 69599/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MPEG4_fuzzer-4848626296225792.fuzz

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2024-07-15 01:59:41 +02:00
Jiasheng Jiang
4065ff69a2 avcodec/mpegvideo_enc: Add check for av_packet_new_side_data()
Add check for av_packet_new_side_data() to avoid null pointer
dereference if allocation fails.

Fixes: bdc1220eeb ("h263enc: Add an option for outputting info about MBs as side data")
Signed-off-by: Jiasheng Jiang <jiashengjiangcool@outlook.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2024-07-02 09:55:24 +02:00
Andreas Rheinhardt
390dbcb8b8 avcodec/mpegvideo_enc: Constify pointers to static storage
These must not be modified (even when they are initialized at runtime
and therefore modifiable).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:39 +02:00
Andreas Rheinhardt
594723ec38 avcodec/mpegvideo: Move quant_precision to Mpeg4DecContext
It is an MPEG-4-only value; it is always five for the MPEG-4
encoder, so just hardcode this value and move the MpegEncContext
field to Mpeg4DecContext.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:39 +02:00
Andreas Rheinhardt
f793074784 avcodec/h261dec: Unquantize coefficients while parsing them
This is beneficial for performance: When concatenating
the file from the vsynth1-h261 fate-test 100 times,
performance (measured by timing the codec's decode callback)
improved by 9.6%.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:39 +02:00
Andreas Rheinhardt
f8b8f16163 avcodec/mpegvideo_enc: Don't update qscale unnecessarily
The new value will be overwritten in ff_set_qscale() below.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
85cc6478b6 avcodec/mpegvideo_enc: Initialize qscale tab for all codecs
Calling it is the first thing ff_clean_h263_qscales() and
ff_clean_mpeg4_qscales() do anyway.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
3b67ab85ee avcodec/mpegvideo_enc: Only keep what is used from MECmpContext
A MECmpContext is quite big (792B here) and given
how ff_update_duplicate_context() works, it is (unfortunately)
copied quite frequently when using slice threading.
Therefore keep only what is needed from MECmpContext
and remove MECmpContext from MpegEncContext.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
eb3415912b avcodec/mpegvideo_enc: Avoid branch for sse vs nsse cmp
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
d163eefd47 avcodec/me_cmp, motion_est: Sanitize permissible cmp_funcs
Several of the potential choices of comparison functions
need an initialized MpegEncContext (initialized for encoding,
not only ff_mpv_common_init()) or they crash when called.
Modify ff_set_cmp() to check for this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
b1a31b32ab avcodec/me_cmp,dvenc,mpegvideo: Move ildct_cmp to its users
MECmpContext.ildct_cmp is an array of function pointers that
are not set by ff_me_cmp_init(), but that are set by users
to one of the other arrays via ff_set_cmp().

Remove these pointers from MECmpContext and add pointers
for the actually used functions to its users. (The DV encoder
already did so.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
cd2e46a350 avcodec/me_cmp, mpegvideo: Move frame_skip_cmp to MpegEncContext
MECmpContext has several arrays of function pointers that
are not set by ff_me_cmp_init(), but that are set by users
to one of the other arrays via ff_set_cmp().

One of these other users is mpegvideo_enc; it is the only user
of MECmpContext.frame_skip_cmp and it only uses one of these
function pointers at all.

This commit therefore moves this function pointer to MpegEncContext;
and removes the array from MECmpContext.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
bbd355355d avcodec/motion_est: Factor one-time initialization out of ff_init_me
The majority of the stuff performed in it needs to be done only
once; so factor it out into a function of its own to be called
in the user's init function.
Also avoid using MpegEncContext in it, to separate the two
a bit more.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
c46711d44f avcodec/mpegvideo_enc: Check for existence of ildct cmp functions
Not all compare functions are implemented for all compare function
types. Therefore check for the existence of the used functions.
Fixes issue #10245.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
415a3c32c9 avcodec/mpegvideo_enc: Avoid excessive inlining
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
80c2d7c890 avcodec/mpegvideo_enc: Avoid branches for flipping no_rounding
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-20 18:58:38 +02:00
Andreas Rheinhardt
89742b88c6 avcodec/mpegvideo_enc: Don't pretend ff_dct_encode_init() can fail
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:25:10 +02:00
Andreas Rheinhardt
1dc1b6c5af avcodec/mpegvideo: Remove fast_dct_quantize
It has been added in 3a87ac948f,
but there was never an implementation different from the ordinary
dct_quantize of it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:24:20 +02:00
Andreas Rheinhardt
e80bd068c5 avcodec/mpegvideo_enc: Always set c funcs in ff_dct_encode_init()
Use the common approach whereby the _c versions are set first
and then (potentially) overwritten by the arch-specific ones
instead of calling the arch-specific code first, followed by
setting the function pointers that have not already been set.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:24:09 +02:00
Andreas Rheinhardt
8327828205 avcodec/mips/mpegvideo: Set denoise_dct only for encoder
The C version is set in ff_dct_encode_init(), yet the MIPS version
is set in dct_init() (in ff_mpv_common_init() and therefore also
for decoders). This commit fixes this inconsistency.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:23:30 +02:00
Andreas Rheinhardt
adb1521385 avcodec/mpegvideo_enc: Move initializing H263DSP to ituh263enc.c
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:23:29 +02:00
Andreas Rheinhardt
bf8208d0cd avcodec/mpegvideo_enc: Make ff_dct_quantize_c() static
Only used here.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 13:20:47 +02:00
Andreas Rheinhardt
bf087a7e26 avcodec/mpegvideo_enc: Binarize reference
The H.264 decoder used reference to store its picture_structure
into it; yet it does not use mpegvideo any more since commit
2c54155407. Afterwards commit
629259bdb5 removed the last remnants.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 12:07:31 +02:00
Andreas Rheinhardt
b2ac792367 avcodec/mpegvideo: Use enum for msmpeg4_version
Improves readability.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 12:03:00 +02:00
Andreas Rheinhardt
4f2719a239 avcodec/mpegvideo_enc: Unify initializing PutBitContexts
This also rids us of the requirement to preserve the PutBitContext
in ff_update_duplicate_context().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:55:44 +02:00
Andreas Rheinhardt
a05eebee99 avcodec/mpegpicture: Avoid MotionEstContext in ff_mpeg_framesize_alloc()
Only set the ScratchpadContext and let the users that need it
(i.e. encoders) set the MotionEstContext stuff themselves.
Also add an explicit pointer to ScratchpadContext to point
to the allocated buffer so that none of the other scratchpad
pointers is singled out as being used for the allocations.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:54:57 +02:00
Andreas Rheinhardt
45cf0541cf avcodec/mpegpicture: Use ThreadProgress instead of ThreadFrame API
Given that MPVPictures are already directly shared between threads
in case of frame-threaded decoding, one can simply use it to
pass decoding progress information between threads. This allows
to avoid one level of indirection; it also means avoids allocations
(of the ThreadFrameProgress structure) in case of frame-threading
and indeed makes ff_thread_release_ext_buffer() decoder-only
(actually, H.264-decoder-only).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:53:49 +02:00
Andreas Rheinhardt
9ce56f91c0 avcodec/mpegpicture: Make MPVPicture refcounted
Up until now, an initialized MpegEncContext had an array of
MPVPictures (way more than were ever needed) and the MPVPicture*
contained in the MPVWorkPictures as well as the input_picture
and reordered_input_picture arrays (for the encoder) pointed
into this array. Several of the pointers could point to the
same slot and because there was no reference counting involved,
one had to check for aliasing before unreferencing.
Furthermore, given that these pointers were not ownership pointers
the pointers were often simply reset without unreferencing
the slot (happened e.g. for the RV30 and RV40 decoders) or
there were moved without resetting the src pointer (happened
for the encoders where the entries in the input_picture
and reordered_input_picture arrays were not reset).
Instead actually releasing these pictures was performed by looping
over the whole array and checking which one of the entries needed
to be kept. Given that the array had way too many slots (36),
this meant that more than 30 MPVPictures have been unnecessarily
unreferenced in every ff_mpv_frame_start(); something similar
happened for the encoder.

This commit changes this by making the MPVPictures refcounted
via the RefStruct API. The MPVPictures itself are part of a pool
so that this does not entail constant allocations; instead,
the amount of allocations actually goes down, because the
earlier code used such a large array of MPVPictures (36 entries) and
allocated an AVFrame for every one of these on every
ff_mpv_common_init(). In fact, the pool is only freed when closing
the codec, so that reinitializations don't lead to new allocations
(this avoids having to sync the pool in update_thread_context).

Making MPVPictures refcounted also has another key benefit:
It makes it possible to directly share them across threads
(when using frame-threaded decoding), eliminating ugly code
with underlying av_frame_ref()'s; sharing these pictures
can't fail any more.

The pool is allocated in ff_mpv_decode_init() for decoders,
which therefore can fail now. This and the fact that the pool
is not unreferenced in ff_mpv_common_end() also necessitated
to mark several mpegvideo-decoders with the FF_CODEC_CAP_INIT_CLEANUP
flag.

*: This also means that there is no good reason any more for
ff_mpv_common_frame_size_change() to exist.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:47:49 +02:00
Andreas Rheinhardt
dceb73a22d avcodec/mpegvideo_enc: Reindentation
Also try to use loop-scope for iterators.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:43:22 +02:00
Andreas Rheinhardt
b64dfe2bd1 avcodec/mpegvideo_enc: Return early when getting length of B frame chain
Possible now that this is a function of its own.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:43:14 +02:00
Andreas Rheinhardt
17b5fc2e51 avcodec/mpegvideo_enc: Factor setting length of B frame chain out
It already avoids a goto and will be useful in the future
to be able to specify each functions tasks and obligations.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:42:59 +02:00
Andreas Rheinhardt
fe6037fd04 avcodec/mpegpicture: Split MPVPicture into WorkPicture and ordinary Pic
There are two types of MPVPictures: Three (cur_pic, last_pic, next_pic)
that are directly part of MpegEncContext and an array of MPVPictures
that are separately allocated and are mostly accessed via pointers
(cur|last|next)_pic_ptr; they are also used to store AVFrames in the
encoder (necessary due to B-frames). As the name implies, each of the
former is directly associated with one of the _ptr pointers:
They actually share the same underlying buffers, but the ones
that are part of the context can have their data pointers offset
and their linesize doubled for field pictures.

Up until now, each of these had their own references; in particular,
there was an underlying av_frame_ref() to sync cur_pic and cur_pic_ptr
etc. This is wasteful.

This commit changes this relationship: cur_pic, last_pic and next_pic
now become MPVWorkPictures; this structure does not have an AVFrame
at all any more, but only the cached values of data and linesize.
It also contains a pointer to the corresponding MPVPicture, establishing
a more natural relationsship between the two.
This already means that creating the context-pictures from the pointers
can no longer fail.

What has not been changed is the fact that the MPVPicture* pointers
are not ownership pointers and that the MPVPictures are part of an
array of MPVPictures that is owned by a single AVCodecContext.
Doing so will be done in a latter commit.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:38:13 +02:00
Andreas Rheinhardt
59422955cf avcodec/mpegpicture: Rename Picture->MPVPicture
Picture is just too generic.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:36:09 +02:00
Andreas Rheinhardt
2dfe7c1e40 avcodec/mpegvideo_enc: Move copying properties to alloc_picture()
This way said function sets everything (except for the actual
contents of the frame's data). Also rename it to prepare_picture()
given its new role.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:32:35 +02:00
Andreas Rheinhardt
8225d2da73 avcodec/mpegvideo_enc: Pass AVFrame*, not Picture* to alloc_picture()
It now only deals with the AVFrame and no longer with the accessories.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:32:25 +02:00
Andreas Rheinhardt
89ca63cc9c avcodec/mpegpicture: Split ff_alloc_picture() into check and alloc part
ff_alloc_picture() currently does two things: It checks the
consistency of the linesize (which should not be necessary, but is)
and it allocates certain buffers. (It does not actually allocate
the picture buffers, so its name is misleading.)
This commit splits it into two separate functions. The rationale
for this is that for the encoders, every picture needs its linesizes
checked, but not every picture needs these extra buffers.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:27:25 +02:00
Andreas Rheinhardt
dda009b97d avcodec/mpegvideo: Add const where appropriate
Specifically, add const to the pointed-to-type of pointers
that point to something static or that belong to last_pic
or next_pic (because modifying these might lead to data races).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:26:51 +02:00
Andreas Rheinhardt
f1c4e8950e avcodec/rv30, rv34, rv40: Avoid indirection
Use the cached values from MpegEncContext.(cur|last|next)_pic
instead of the corresponding *_pic_ptr.
Also do the same in wmv2dec.c and mpegvideo_enc.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:22:41 +02:00
Andreas Rheinhardt
7814dd77aa avcodec/mpegpicture: Cache AVFrame.data and linesize values
This avoids an indirection and is in preparation for removing
the AVFrame from MpegEncContext.(cur|last|next)_pic altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:20:56 +02:00
Andreas Rheinhardt
1c40a17922 avcodec/mpegpicture: Reduce value of MAX_PLANES define
No mpegvideo based codec supports alpha.
While just at it, also make the define shorter.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:20:27 +02:00
Andreas Rheinhardt
ec1eba792a avcodec/mpegvideo: Shorten variable names
current_picture->cur_pic, last_picture->last_pic, similarly
for new_picture and next_picture.
Also rename the corresponding *_ptr fields.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:19:44 +02:00
Andreas Rheinhardt
2cbca73975 avcodec/h263: Move encoder-only part out of ff_h263_update_motion_val()
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:14:13 +02:00
Andreas Rheinhardt
788892d647 avcodec/mpegvideo, mpegpicture: Add buffer pool
This avoids constant allocations+frees and will also allow
to simply switch to the RefStruct API, thereby avoiding
the overhead of the AVBuffer API.
It also simplifies the code, because it removes the "needs_realloc"
field: It was added in 435c0b87d2,
before the introduction of the AVBuffer API: given that these buffers
may be used by different threads, they were not freed immediately
and instead were marked as being freed later by setting needs_realloc.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 11:08:19 +02:00
Andreas Rheinhardt
685cda26aa avcodec/mpegvideo, ratecontrol: Remove write-only skip_count
Write-only since 6cf0cb8935.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:37 +02:00
Andreas Rheinhardt
0c9e04b0e2 avcodec/ratecontrol: Pass RCContext directly in ff_rate_control_uninit()
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:16 +02:00