Compare commits

...

141 Commits

Author SHA1 Message Date
Michael Niedermayer dc91b913b6 RELEASE_NOTES: Based on the version from 4.3
Name suggested by Lynne, Gyan, Reto, Zane, Jan, Derek

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-08 22:55:16 +02:00
Michael Niedermayer aeba1a4c20 avcodec/msp2dec: Check available space in RLE decoder
Fixes: out of array read
Fixes: 32968/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MSP2_fuzzer-5315296027082752

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit caaf463311)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-08 22:55:16 +02:00
Michael Niedermayer d22550dd61 avformat/mov: check offset for overflow in mov_probe()
Fixes: Invalid read of size 4
Fixes: ASAN_Deadlysignal.zip

Found-by: Hardik Shah <hardik05@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 0f6a3405e8)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-08 22:55:16 +02:00
Anton Khirnov 2a7f1bc282 lavc/pngdec: always create a copy for APNG_DISPOSE_OP_BACKGROUND
Calling av_frame_make_writable() from decoders is tricky, especially
when frame threading is used. It is much simpler and safer to just make
a private copy of the frame.
This is not expected to have a major performance impact, since
APNG_DISPOSE_OP_BACKGROUND is not used often and
av_frame_make_writable() would typically make a copy anyway.

Found-by: James Almer <jamrial@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit b593abda6c)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-08 22:55:16 +02:00
Marton Balint 25e794a1ea avformat/url: add ff_make_absolulte_url2 to be able to test windows path cases
Signed-off-by: Marton Balint <cus@passwd.hu>
(cherry picked from commit fb4da90fec)
2021-04-08 17:38:06 +02:00
Marton Balint d622923b36 avformat/url: fix ff_make_absolute_url with Windows file paths
Ugly, but a lot less broken than it was.

Fixes ticket #9166.

Signed-off-by: Marton Balint <cus@passwd.hu>
(cherry picked from commit 5dc5f289ce)
2021-04-08 17:35:09 +02:00
Anton Khirnov c64180fac8 lavc/pngdec: improve chunk length check
The length does not cover the chunk type or CRC.

(cherry picked from commit ae08eec6a1)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2021-04-08 14:15:30 +02:00
Anton Khirnov 8ee432dc23 lavc/pngdec: restructure exporting frame meta/side data
This data cannot be stored in PNGDecContext.picture, because the
corresponding chunks may be read after the call to
ff_thread_finish_setup(), at which point modifying shared context data
is a race.

Store intermediate state in the context and then write it directly to
the output frame.

Fixes exporting frame metadata after 5663301560
Fixes #8972

Found-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 8d74baccff)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2021-04-08 14:15:30 +02:00
Anton Khirnov 5f21bbed8a lavc/pngdec: remove unnecessary context variables
Do not store the image buffer pointer/linesize in the context, just
access them directly from the frame.
Stop assuming that linesize is the same for the current and last frame.

(cherry picked from commit 89ea5057bf)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2021-04-08 14:15:30 +02:00
Anton Khirnov 53ecdbfbe5 lavc/pngdec: perform APNG blending in-place
Saves an allocation+free and two frame copies per each frame.

(cherry picked from commit 5a50bd88db)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2021-04-08 14:15:30 +02:00
Andreas Rheinhardt 5c457c673f avcodec/mpegvideo_enc: Don't segfault on unorthodox mpeg_quant
The (deprecated) field AVCodecContext.mpeg_quant has no range
restriction; MpegEncContext.mpeg_quant is restricted to 0..1.
If the former is set, the latter is overwritten with it without
checking the range. This can trigger an av_assert2() with the MPEG-4
encoder when writing said field.

Fix this by just setting MpegEncContext.mpeg_quant to 1 if
AVCodecContext.mpeg_quant is set.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit d393c45051)
2021-04-08 11:59:08 +02:00
Andreas Rheinhardt fb7cd45977 avcodec/encode: Fix check for allowed LJPEG pixel formats
The pix_fmts of the LJPEG encoder already contain all supported pixel
formats (including the ones only supported when strictness is unofficial
or less); yet the check in ff_encode_preinit() ignored this list in case
strictness is unofficial or less. But the encoder presumed that it is
always applied and blacklists some of the entries in pix_fmts when
strictness is > unofficial. The result is that if one uses an entry not
on that list and sets strictness to unofficial, said entry passes both
checks and this can lead to segfaults lateron (e.g. when using gray).

Fix this by removing the exception for LJPEG in ff_encode_preinit().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 6e8e9b7633)
2021-04-08 11:58:59 +02:00
Andreas Rheinhardt 44d218e99a avformat/rmdec: Don't rely on unspecified order of evaluation
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 4666ce0aef)
2021-04-08 11:58:05 +02:00
Andreas Rheinhardt be5970fcaa avformat/rmdec: Fix memleaks upon read_header failure
For both the RealMedia as well as the IVR demuxer (which share the same
context) each AVStream's priv_data contains an AVPacket that might
contain data (even when reading the header) and therefore needs to be
unreferenced. Up until now, this has not always been done:

The RealMedia demuxer didn't do it when allocating a new stream's
priv_data failed although there might be other streams with packets to
unreference. (The reason for this was that until recently rm_read_close()
couldn't handle an AVStream without priv_data, so one had to choose
between a potential crash and a memleak.)

The IVR demuxer meanwhile never ever called read_close so that the data
already contained in packets leaks upon error.

This patch fixes both demuxers by adding the appropriate cleanup code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 9a471c5437)
2021-04-08 11:57:57 +02:00
Andreas Rheinhardt c72fca598c avcodec/vc1dec: Fix memleak upon allocation error
ff_vc1_decode_init_alloc_tables() had one error path that forgot to free
already allocated buffers; these would then be overwritten on the next
allocation attempt (or they would just not be freed in case this
happened during init, as the decoders for which it is used do not have
the FF_CODEC_CAP_INIT_CLEANUP set).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 98060a198e)
2021-04-08 11:57:07 +02:00
Andreas Rheinhardt b0997b8526 avcodec/rv34, mpegvideo: Fix segfault upon frame size change error
The RealVideo 3.0 and 4.0 decoders call ff_mpv_common_init() only during
their init function and not during decode_frame(); when the size of the
frame changes, they call ff_mpv_common_frame_size_change(). Yet upon
error, said function calls ff_mpv_common_end() which frees the whole
MpegEncContext and not only those parts that
ff_mpv_common_frame_size_change() reinits. As a result, the context will
never be usable again; worse, because decode_frame() contains no check
for whether the context is initialized or not, it is presumed that it is
initialized, leading to segfaults. Basically the same happens if
rv34_decoder_realloc() fails.

This commit fixes this by only resetting the parts that
ff_mpv_common_frame_size_change() changes upon error and by actually
checking whether the context is in need of reinitialization in
ff_rv34_decode_frame().

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 9abda1365c)
2021-04-08 11:56:44 +02:00
Andreas Rheinhardt 4562719c7d avcodec/rv10: Don't presume context to be initialized
In case of resolution changes rv20_decode_picture_header() closes and
reopens its MpegEncContext; it checks the latter for errors, yet when
an error happens, it might happen that no new attempt at
reinitialization is performed when decoding the next frame; this leads
to crashes lateron.

This commit fixes this by making sure that initialization will always
be attempted if the context is currently not initialized.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 8ffd3ef9d9)
2021-04-08 11:56:35 +02:00
Andreas Rheinhardt 6d7dfabfb0 avcodec/mpegvideo: Factor common freeing code out
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 9bab7de175)
2021-04-08 11:56:26 +02:00
Andreas Rheinhardt 63277aa98e avcodec/mpegvideo: Fix memleak upon allocation error
When slice-threading is used, ff_mpv_common_init() duplicates
the first MpegEncContext and allocates some buffers for each
MpegEncContext (the first as well as the copies). But the count of
allocated MpegEncContexts is not updated until after everything has
been allocated and if an error happens after the first one has been
allocated, only the first one is freed; the others leak.

This commit fixes this: The count is now set before the copies are
allocated. Furthermore, the copies are now created and initialized
before the first MpegEncContext, so that the buffers exclusively owned
by each MpegEncContext are still NULL in the src MpegEncContext so
that no double-free happens upon allocation failure.

Given that this effectively touches every line of the init code,
it has also been factored out in a function of its own in order to
remove code duplication with the same code in
ff_mpv_common_frame_size_change() (which was never called when using
more than one slice (and if it were, there would be potential
double-frees)).

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit ff0706cde8)
2021-04-08 11:56:17 +02:00
Andreas Rheinhardt 0155d5cd74 Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
This mostly reverts commit 4b2863ff01.
Said commit removed the freeing code from ff_mpv_common_init(),
ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and
instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use
ff_mpv_common_init(). This introduced several bugs:

a) Several decoders using ff_mpv_common_init() in their init function were
forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as
VC-1/WMV3.
b) ff_mpv_common_init() is not only called from the init function of
codecs, it is also called from AVCodec.decode functions. If an error
happens after an allocation has succeeded, it can lead to memleaks;
furthermore, it is now possible for the MpegEncContext to be marked as
initialized even when ff_mpv_common_init() returns an error and this can
lead to segfaults because decoders that call ff_mpv_common_init() when
decoding a frame can mistakenly think that the MpegEncContext has been
properly initialized. This can e.g. happen with H.261 or MPEG-4.
c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't
be called from any init function) can lead to segfaults because the
check for whether it needs to allocate consists of checking whether the
first of the buffers allocated there has been allocated. This part has
already been fixed in 76cea1d2ce.
d) ff_mpv_common_frame_size_change() can also not be reached from any
AVCodec.init function; yet the changes can e.g. lead to segfaults with
decoders using ff_h263_decode_frame() upon allocation failure, because
the MpegEncContext will upon return be flagged as both initialized and
not in need of reinitialization (granted, the fact that
ff_h263_decode_frame() clears context_reinit before the context has been
reinited is a bug in itself). With the earlier version, the context
would be cleaned upon failure and it would be attempted to initialize
the context again in the next call to ff_h263_decode_frame().

While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP,
keeping the current approach would entail adding cleanup code to several
other places because of b). Therefore ff_mpv_common_init() is again made
to clean up after itself; the changes to the wmv2 decoder and the SVQ1
encoder have not been reverted: The former fixed a memleak, the latter
allowed to remove cleanup code.

Fixes: double free
Fixes: ff_free_picture_tables.mp4
Fixes: ff_mpeg_update_thread_context.mp4
Fixes: decode_colskip.mp4
Fixes: memset.mp4

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit d4b9e117ce)
2021-04-08 11:56:07 +02:00
Andreas Rheinhardt ed7efbe3ab avcodec/wmavoice: Check operations that can fail
There might be segfaults on failure.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit e93875b756)
2021-04-08 11:55:32 +02:00
Andreas Rheinhardt 6aad0b1bb5 avcodec/mjpegdec: Fix leak in case ICC array allocations fail partially
If only one of the two arrays used for the ICC profile could be
successfully allocated, it might be overwritten and leak when
the next ICC entry is encountered. Fix this by using a common struct,
so that one has only one array to allocate.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit a5b2f06b0c)
2021-04-08 11:55:17 +02:00
Andreas Rheinhardt 5621d10b7a avcodec/tiff: Avoid forward declarations
In this case it also fixes a potential for compilation failures:
Not all compilers can handle the case in which a function with
a forward declaration declared with an attribute to always inline it
is called before the function body appears. E.g. GCC 4.2.1 on OS X 10.6
doesn't like it.

Reviewed-by: Pavel Koshevoy <pkoshevoy@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit e5d6af7b35)
2021-04-08 11:54:24 +02:00
Andreas Rheinhardt 1761cc0cb0 avcodec/pthread_frame: Reindentation
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 6599960940)
2021-04-08 11:53:16 +02:00
Andreas Rheinhardt 562ff3ee0e avcodec/pthread_frame: Check initializing mutexes/condition variables
Up until now, initializing the mutexes/condition variables wasn't
checked by ff_frame_thread_init(). This commit changes this.

Given that it is not documented to be save to destroy a zeroed but
otherwise uninitialized mutex/condition variable, one has to choose
between two approaches: Either one duplicates the code to free them
in ff_frame_thread_init() in case of errors or one records which have
been successfully initialized. This commit takes the latter approach:
For each of the two structures with mutexes/condition variables
an array containing the offsets of the members to initialize is added.
Said array is used both for initializing and freeing and the only thing
that needs to be recorded is how many of these have been successfully
initialized.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit c85fcc96b7)
2021-04-08 11:53:03 +02:00
Andreas Rheinhardt aa8f8748ca avcodec/pthread_frame: Fix cleanup during init
In case an error happened when setting up the child threads,
ff_frame_thread_init() would up until now call ff_frame_thread_free()
to clean up all threads set up so far, including the current, not
properly initialized one.
But a half-allocated context needs special handling which
ff_frame_thread_frame_free() doesn't provide.
Notably, if allocating the AVCodecInternal, the codec's private data
or setting the options fails, the codec's close function will be
called (if there is one); it will also be called if the codec's init
function fails, regardless of whether the FF_CODEC_CAP_INIT_CLEANUP
is set. This is not supported by all codecs; in ticket #9099 it led
to a crash.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit e9b6617579)
2021-04-08 11:52:52 +02:00
Andreas Rheinhardt 0401246845 avcodec/pthread_frame: Factor initializing single thread out
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 24ee151402)
2021-04-08 11:52:44 +02:00
Mark Plomer 76b5f726aa avcodec/dv_profile: PAL DV files with dsf flag 0 - detect via pal flag and buf_size
Some old DV AVI files have the DSF-Flag of frames set to 0, although it
is PAL (maybe rendered with an old Ulead Media Studio Pro) ... this causes
ffmpeg/VLC-player to produce/play corrupted video (other players/editors
like VirtualDub work fine).

Fixes ticket #8333 and replaces/extends hack for ticket #2177

Signed-off-by: Marton Balint <cus@passwd.hu>
(cherry picked from commit 6ef5d8ca86)
2021-04-03 20:05:15 +02:00
Michael Niedermayer 6a7a39878f avcodec/cfhd: Keep track of which subbands have been read
This avoids use of uninitialized data
also several checks are inside the band reading code
so it is important that it is run at least once

Fixes: out of array accesses
Fixes: 28209/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-5684714694377472
Fixes: 32124/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-5425980681355264
Fixes: 30519/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-4558757155700736

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit da8c86dd8b)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Michael Niedermayer a80b0ee981 avcodec/cfhd: Require valid setup before Lowpass coefficients, BandHeader and BandSecondPass
Previously the code skipped all security checks when these where encountered but prior data was incorrect.
Also replace an always true condition by an assert

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 3b88c88fa1)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Michael Niedermayer de40b2fe41 avcodec/cfhd: Check transform_type consistently
Fixes: out of array accesses
Fixes: 29754/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-6333598414274560
Fixes: 30519/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-6298424511168512
Fixes: 30739/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-5011292836462592

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 20473a93d2)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Alan Kelly 4aeedf4c2a libswscale/x86/yuv2yuvX: Removes unrolling for mmx and mmxext
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 3ce8d09244)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Alan Kelly 95aacf30e3 libswscale/x86/swscale: Only call ff_yuv2yuvX functions if the input size is > 0
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit dc57762cb4)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Alan Kelly 6bc2058d00 tests/checkasm/sw_scale: adds additional tests sizes for yux2yuvX
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit e1484bc455)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-03 19:43:39 +02:00
Andreas Rheinhardt 54dd729cee avcodec/mjpegdec: Check initializing Huffman tables
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit d5ddfec6c3)
2021-04-03 18:08:02 +02:00
Andreas Rheinhardt 1f3735892b avcodec/mjpegdec: Fix leak in case of invalid external Huffman tables
When using external Huffman tables fails during init, the decoder
reverts back to using the default Huffman tables; and when doing so,
the current VLC tables leak because init_default_huffman_tables()
doesn't free them before overwriting them.

Sample:
samples.ffmpeg.org/archive/all/avi+mjpeg+pcm_s16le++mjpeg-interlace.avi

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 3cc685b7bc)
2021-04-03 18:07:58 +02:00
Andreas Rheinhardt edbc26e38b avcodec/a64multienc: Don't use static buffers, fix potential races
render_charset() used static buffers that are always completely
initialized before every use, so that it is unnecessary for the
values in these arrays to be kept after leaving the function.
Given that this is not only unnecessary, but harmful due to the
possibility of data races if several instances of a64multi/a64multi5
run simultaneously these buffers have been replaced by ordinary buffers
on the stack (they are small enough for this).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 0ca09335aa)
2021-04-03 16:46:43 +02:00
Andreas Rheinhardt 8bc3cdf007 avcodec/rawdec: Free bitstream_buf
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 5c0f6d53da)
2021-04-03 13:29:30 +02:00
Andreas Rheinhardt 639c60f5aa avformat/vividas: Fix crash when seeking without audio stream
The current code tries the access the codecpar of a nonexistent
audio stream when seeking. Stop that. Fixes ticket #9121.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit af867e59d9)
2021-04-03 07:20:39 +02:00
Andreas Rheinhardt 0fe3383066 avcodec/ass_split: Don't presume strlen to be >= 2
Fixes potential heap-buffer-overflow.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit f38f791a23)
2021-04-02 21:44:25 +02:00
Andreas Rheinhardt eff72f86e2 avcodec/binkaudio: Check return value of functions that can fail
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 0062aca592)
2021-04-02 21:44:15 +02:00
Andreas Rheinhardt 632262f184 avcodec/binkaudio: Fix memleak upon init failure
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 85aed2e390)
2021-04-02 21:44:06 +02:00
Andreas Rheinhardt 236ddfbe1c avcodec/flacenc: Fix memleak upon init error
An AVMD5 struct would leak if an error happened after its allocation.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 56bd071e54)
2021-04-02 21:43:58 +02:00
Andreas Rheinhardt affb55d4b4 avcodec/proresenc_anatoliy: Fix memleak upon init error
A buffer may leak in case of YUVA444P10 with dimensions that are not
both divisible by 16.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit d789d72d30)
2021-04-02 21:43:27 +02:00
Andreas Rheinhardt 60433ae94f avcodec/bsf: Fix segfault when freeing half-allocated BSF
When allocating a BSF fails, it could happen that the BSF's close
function has been called despite a failure to allocate the private data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 9bf2b32da0)
2021-04-02 21:43:18 +02:00
Andreas Rheinhardt 82b9da7662 avcodec/av1_metadata_bsf: Check for the existence of units
Fixes a crash with ISOBMFF extradata containing no OBUs.

Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 8081a0b10f)
2021-04-02 21:43:08 +02:00
Andreas Rheinhardt 0ccd2540b0 avcodec/h264_metadata_bsf: Don't add AUD to extradata
This is a regression since switching to the generic CBS BSF code.

Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit b917218c35)
2021-04-02 21:43:00 +02:00
Andreas Rheinhardt 7f139498f5 avcodec/msmpeg4enc: Don't use code for static init that can fail
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit f0042e573e)
2021-04-02 21:42:49 +02:00
Andreas Rheinhardt b51d5b222e avformat/dss: Don't prematurely modify context variable
The DSS demuxer currently decrements a counter that should be positive
at the beginning of read_packet; should it become negative, it means
that the data to be read can't be read contiguosly, but has to be read
in two parts. In this case the counter is incremented again after the
first read if said read succeeded; if not, the counter stays negative.

This can lead to problems in further read_packet calls; in tickets #9020
and #9023 it led to segfaults if one tries to seek lateron if the seek
failed and generic seek tried to read from the beginning. But it could
also happen when av_new_packet() failed and the user attempted to read
again afterwards.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit afa511ad34)
2021-04-02 21:42:37 +02:00
Andreas Rheinhardt 70028ce7fd avformat/utils: Check allocations for failure
There would be leaks in case of failure.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 543e4a1942)
2021-04-02 21:42:29 +02:00
Andreas Rheinhardt ffb599458f avcodec/ac3enc: Use actual size of buffer in init_put_bits()
Since the very beginning (since de6d9b6404)
the AC-3 encoder used AC3_MAX_CODED_FRAME_SIZE (namely 3840) for the
size of the output buffer (without any check at all).
This causes problems when encoding EAC-3 for which the maximum is too small,
smaller than the actual size of the buffer: One can run into asserts used
by the PutBits API. Ticket #8513 is about such a case and this commit
fixes it by using the real size of the buffer.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 968c158abd)
2021-04-02 21:42:15 +02:00
Andreas Rheinhardt 55ad9ece31 avcodec/flashsv2enc: Fix undefined NULL + 0
Affected the vsynth*-flashsv2 FATE-tests.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit b7b73e83e3)
2021-04-02 21:41:55 +02:00
Andreas Rheinhardt 3d473a8925 avutil/pixdesc: Fix 1 << 32
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit b7565b65b8)
2021-04-02 21:41:47 +02:00
Andreas Rheinhardt b4b2f88cab avcodec/motion_est: Fix invalid left shift of negative numbers
Affected many FATE-tests.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 3ef65fd4d1)
2021-04-02 21:41:36 +02:00
Andreas Rheinhardt cc3b05e424 avfilter/vf_codecview: Fix undefined left shifts of negative numbers
Affected the filter-codecview-mvs FATE-test.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 3c151e7999)
2021-04-02 21:41:26 +02:00
Andreas Rheinhardt 195cce45cf avcodec/g2meet: Fix undefined NULL + 0
Affected the g2m4 FATE-test.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit a86f3e983e)
2021-04-02 21:41:14 +02:00
Andreas Rheinhardt c7a95509b3 avutil/base64: Fix undefined NULL + 0
Affected the base64 FATE test.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit bbf8431b1b)
2021-04-02 21:41:05 +02:00
Andreas Rheinhardt 6906a2b471 avcodec/vmdvideo: Fix NULL + 0
Affected the FATE tests filter-gradfun-sample and sierra-vmd-video.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 566bf56791)
2021-04-02 21:40:54 +02:00
Andreas Rheinhardt 4eb44966a6 avcodec/mss12: Don't apply non-zero offset to null pointer
Affected the FATE tests mss2-wmv and mss1-pal.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 8429661db8)
2021-04-02 21:40:40 +02:00
Andreas Rheinhardt 9a2b994a71 avcodec/lcldec: Fix undefined NULL + 0
Affected the FATE tests vsynth*-zlib, mszh and zlib.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit dd9cbd1cc3)
2021-04-02 21:40:27 +02:00
Andreas Rheinhardt 58b961d8bb avcodec/qtrleenc: Fix negative linesizes, don't use NULL + offset
Before commit f1e17eb446, the qtrle
encoder had undefined pointer arithmetic: Outside of a loop, two
pointers were set to point to the ith element (with index i-1) of
a line of a frame. At the end of each loop iteration, these pointers
were decremented, so that they pointed to the -1th element of the line
after the loop. Furthermore, one of these pointers can be NULL (in which
case all pointer arithmetic is automatically undefined behaviour).

Commit f1e17eb44 added a check in order to ensure that the elements
never point to the -1th element of the array: The pointers are only
decremented if they are bigger than the frame's base pointer
(i.e. AVFrame.data[0]). Yet this check does not work at all in case of
negative linesizes; furthermore in case the pointer that can be NULL is
NULL initializing it still involves undefined pointer arithmetic.

This commit fixes both of these issues: First, non-NULL pointers are
initialized to point to the element after the ith element and
decrementing is moved to the beginning of the loop. Second, if a pointer
is NULL, it is just made to point to the other pointer, as this allows
to avoid checks before decrementing it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 911fe69c5f)
2021-04-02 21:40:17 +02:00
Andreas Rheinhardt 6614f33a0b avcodec/qtrleenc: Use keyframe when no previous frame is available
If keeping a reference to an earlier frame failed, the next frame must
be an I frame for lack of reference frame. This commit implements this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit d5fc16a6a8)
2021-04-02 21:40:07 +02:00
Andreas Rheinhardt 67e401e3cb libswresample/audioconvert: Fix undefined NULL + 0
Affected 26 FATE tests like swr-resample_async-s16p-44100-8000.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 64977ed7ae)
2021-04-02 21:39:54 +02:00
Andreas Rheinhardt 789dadccc0 avcodec/proresdec2: Don't apply non-zero offset to null pointer
Affected ProRes without alpha; affected 32 FATE tests, e.g. prores-422,
prores-422_proxy, prores-422_lt or matroska-prores-header-insertion-bz2.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit f83976344e)
2021-04-02 21:39:47 +02:00
Andreas Rheinhardt 09510d9ffd avcodec/mpegvideo_enc: Don't apply non-zero offset to null pointer
Affected many FATE tests (mostly vsynth ones).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 4863671d88)
2021-04-02 21:39:37 +02:00
Andreas Rheinhardt 816d4bee4a avfilter/af_hdcd: Fix undefined shifts
Affected the filter-hdcd-* FATE tests.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 9eadd616b7)
2021-04-02 21:39:27 +02:00
Andreas Rheinhardt a8fb9c9d27 avcodec/dcaenc: Fix undefined left shift of negative numbers
Affected the acodec-dca and acodec-dca2 FATE tests.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 659a925939)
2021-04-02 21:39:19 +02:00
Andreas Rheinhardt 5e2e8e1b9e avcodec/mjpegenc: Fix segfault when freeing incomplete context
When allocating the MJpegContext fails (or if the dimensions run afoul
of the 65500x65500 limit), an attempt to free a subbuffer of said
context leads to a segfault in ff_mjpeg_encode_close().
Seems to be a regression since 467d9e27e0.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
(cherry picked from commit 84ac35ecb8)
2021-04-02 21:39:04 +02:00
Andreas Rheinhardt 28dd12c9b7 avfilter/vf_paletteuse: Fix left shift outside of range of int
by keeping the variable uint32_t which in this situation is the natural
type anyway. This affected the FATE-test filter-paletteuse-sierra2_4a.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 797c2ecc8f)
2021-04-02 21:38:30 +02:00
Andreas Rheinhardt da4b64ea02 avfilter/asrc_sine: Fix invalid left shift of negative number
by using a multiplication instead. The multiplication can never overflow
an int because the sin-factor is only an int16_t.

Affected the FATE-tests filter-concat and filter-concat-vfr.

Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 55b46902c1)
2021-04-02 21:38:21 +02:00
Andreas Rheinhardt 9f011f0876 avformat/webmdashenc: Don't pass NULL to memcmp
Affects the FATE-tests webm-dash-manifest-unaligned-video-streams,
webm-dash-manifest and webm-dash-manifest-representations.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit a42c47b77f)
2021-04-02 21:38:12 +02:00
Andreas Rheinhardt 955be73bc5 avformat/libmodplug: Fix memleaks on error
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit df6dc331dd)
2021-04-02 21:37:20 +02:00
Andreas Rheinhardt 3f94e061cb avformat/libgme: Fix memleaks on errors
Also free the gme_info_t structure immediately after its use.
This simplifies cleanup, because it might be unsafe to call
gme_free_info(NULL) (or even worse, gme_track_info() might even
on error set the pointer to the gme_info_t structure to something
else than NULL).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 05457a3661)
2021-04-02 21:37:09 +02:00
Andreas Rheinhardt a01cf1fe54 avformat/aadec: Fix leak on error
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 3ec3370dea)
2021-04-02 21:37:00 +02:00
Andreas Rheinhardt fe8ae68738 avformat/jacosubdec: Fix leak on error
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 4f11685e4c)
2021-04-02 21:36:51 +02:00
Andreas Rheinhardt 3f851a7719 avcodec/vc1dec: Postpone allocating sprite frame to avoid segfault
Up until now, the VC-1 decoders allocated an AVFrame for usage with
sprites during vc1_decode_init(); yet said AVFrame can be freed if
(re)initializing the context (which happens ordinarily during decoding)
fails. The AVFrame does not get allocated again lateron in this case,
leading to segfaults.

Fix this by moving the allocation of said frame immediately before it is
used (this also means that said frame won't be allocated at all any more
in case of a regular (i.e. non-image) stream).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit ea70c39dee)
2021-04-02 21:36:31 +02:00
Andreas Rheinhardt b4b3af795c avcodec/avcodec: Update check for identical colorspace/primaries/trc names
If the numerical constants for colorspace, transfer characteristics
and color primaries coincide, the current code presumes the
corresponding names to be identical and prints only one of them obtained
via av_get_colorspace_name(). There are two issues with this: The first
is that the underlying assumption is wrong: The names only coincide in
the 0-7 range, they differ for more recent additions. The second is that
av_get_colorspace_name() is outdated itself; it has not been updated
with the names of the newly defined colorspaces.

Fix both of this by using the names from
av_color_(space|primaries|transfer)_name() and comparing them via
strcmp; don't use av_get_colorspace_name() at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit e65a5df4fa)
2021-04-02 21:36:20 +02:00
Andreas Rheinhardt 0bbf1f4785 avcodec/avcodec: Don't use NULL for %s printf specifier
Our "get name" functions can return NULL for invalid/unknown
arguments. So check for this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 88b7d9fd36)
2021-04-02 21:35:55 +02:00
Andreas Rheinhardt a57ba45eb4 avformat/webpenc: Fix memleak when trailer is never written
When the trailer is never written (or when a stream switches from
non-animation mode to animation mode mid-stream), a cached packet
(if existing) would leak. Fix this by adding a deinit function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 3903c139a9)
2021-04-02 21:35:42 +02:00
Andreas Rheinhardt ceb5863d04 avformat/webpenc: Fix memleak when using invalid packets
The WebP muxer sometimes caches a packet it receives to write it later;
yet if a cached packet is too small (so small as to be invalid),
it is cached, but not written and not unreferenced. Such a packet leaks,
either by being overwritten by the next packet or because it is never
unreferenced at all.

Fix this by not caching unusable packets at all; and error out on
invalid packets.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit f9043de99a)
2021-04-02 21:35:29 +02:00
Zane van Iperen cc8eba0ab8 avcodec/adpcmenc: don't share a single AVClass between multiple AVCodecs.
Temporary fix until AVClass::child_class_next is gone.

Reviewed-By: James Almer <jamrial@gmail.com>
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit aa1cfe05a5)
2021-04-02 09:01:59 +10:00
Michael Niedermayer 829d4b009f avcodec/pnm_parser: Check image size addition for overflow
Fixes: assertion failure
Fixes: out of array access
Fixes: 32664/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_PGMYUV_fuzzer-6533642202513408.fuzz
Fixes: 32669/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_PGMYUV_fuzzer-6001928875147264

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 79ac8d5546)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 426c52c2ce avcodec/lscrdec: Check length in decode_idat()
Fixes: out of array access
Fixes: 32264/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_LSCR_fuzzer-6684504010915840

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit c01cd2a8b2)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 15f1648f7f tools/target_dem_fuzzer: Fix packet leak
Fixes: 32121/clusterfuzz-testcase-minimized-ffmpeg_IO_DEMUXER_fuzzer-4512973109460992

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 6055b93379)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 45f40cec3a avformat/imx: Check palette chunk size
Fixes: out of array write
Fixes: 32116/clusterfuzz-testcase-minimized-ffmpeg_dem_SIMBIOSIS_IMX_fuzzer-6702533894602752

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit f7a5150447)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer de9f4351fa avcodec/h265_metadata_bsf: Check nb_units before accessing the first in h265_metadata_update_fragment()
Fixes: null pointer dereference
Fixes: 32113/clusterfuzz-testcase-minimized-ffmpeg_BSF_HEVC_METADATA_fuzzer-4803262287052800

Same as 0c48c332ee

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 497ea04dbd)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 1ff644e509 avformat/rmdec: use larger intermediate type for audio_framesize * sub_packet_h check
Fixes: signed integer overflow: 65535 * 65535 cannot be represented in type 'int'
Fixes: 31406/clusterfuzz-testcase-minimized-ffmpeg_dem_IVR_fuzzer-5024692843970560

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit cf2fd9204b)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 698d768d21 avcodec/exr: Check oe in huf_decode() before use
Fixes: out of array access
Fixes: 31386/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_EXR_fuzzer-5773234709594112

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 9e8475c7c7)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:45 +02:00
Michael Niedermayer 137c998b48 avcodec/h264_slice: Check input SPS in ff_h264_update_thread_context()
Fixes: crash
Fixes: check_pkt.mp4

Found-by: Rafael Dutra <rafael.dutra@cispa.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit ceae92cb29)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer d416d7f061 avcodec/mpegpicture: Keep ff_mpeg_framesize_alloc() failure state consistent
Fixes: null pointer dereference
Fixes: ff_put_pixels16_sse2.mp4

Found-by: Rafael Dutra <rafael.dutra@cispa.de>
Regression-since: 4b2863ff01
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 76cea1d2ce)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 807b703a48 avformat/mpc8: check for size overflow in mpc8_get_chunk_header()
Fixes: signed integer overflow: -9223372036854775760 - 50 cannot be represented in type 'long'
Fixes: 31673/clusterfuzz-testcase-minimized-ffmpeg_dem_MPC8_fuzzer-580134751869337

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 6cc65d3d67)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 5978b8bd9c avformat/mov: Do not zero memory that is written too or unused
Fixes: OOM
Fixes: 31220/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-6033383962574848

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit c1fe1114bc)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer ac0e9506d0 avcodec/mpegvideo: Update chroma_?_shift in ff_mpv_common_frame_size_change()
Fixes: out of array access
Fixes: 31201/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MPEG4_fuzzer-4627865612189696.fuzz

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 87d87e6587)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer be3225153e avformat/mov: Ignore multiple STSC / STCO
Fixes: STSC / STCO inconsistency and assertion failure
Fixes: crbug1184666.mp4

Found-by: Chromium ASAN fuzzer
Reviewed-by: Matt Wolenetz <wolenetz@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 2611d20d35)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 9b25cf8b06 avformat/utils: Extend overflow check in dts wrap in compute_pkt_fields()
Fixes: signed integer overflow: -9223372032574480351 - 4294967296 cannot be represented in type 'long long'
Fixes: 30022/clusterfuzz-testcase-minimized-ffmpeg_dem_KUX_fuzzer-5568610275819520

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit b37ff29e0e)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer f8fc6416b2 avfilter/vf_scale: Fix adding 0 to NULL (which is UB) in scale_slice()
Found-by: Jeremy Leconte <jleconte@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 1cf96ce269)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 18bcfa81fc avutil/common: Add FF_PTR_ADD()
Suggested-by: Andreas Rheinhardt
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 522a5259e9)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 8c99a06c5c avcodec/setts_bsf: Check timebase
Fixes: Division by 0
Fixes: 30952/clusterfuzz-testcase-minimized-ffmpeg_BSF_SETTS_fuzzer-6601016202100736

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 7fc8ba9068)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 9179ab9227 avformat/wtvdec: Check size in SBE2_STREAM_DESC_EVENT / stream2_guid
Fixes: signed integer overflow: 539033600 - -1910497124 cannot be represented in type 'int'
Fixes: 30928/clusterfuzz-testcase-minimized-ffmpeg_dem_WTV_fuzzer-5922630966312960

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 1f74661543)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 6ef700dfb0 avformat/utils: Fix integer overflow with duration_gcd in ff_rfps_calculate()
Fixes: signed integer overflow: 136323327 * 281474976710656 cannot be represented in type 'long'
Fixes: 30913/clusterfuzz-testcase-minimized-ffmpeg_dem_IVF_fuzzer-5753392189931520

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 6dc6e1cce0)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 72a03b3c06 tools/target_dec_fuzzer: Adjust threshold for H264
Fixes: Timeout (too long -> 3sec)
Fixes: 28047/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_H264_fuzzer-4662727980875776

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 46c4f39307)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer ee059d8ef8 avformat/cafdec: Do not build an index if all packets are the same
Fixes: Timeout
Fixes: 28214/clusterfuzz-testcase-minimized-ffmpeg_dem_CAF_fuzzer-6495999421579264

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit ea12590c8e)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 419f62c902 avformat/vividas: Use equals check with n in read_sb_block()
Fixes: OOM
Fixes: 27780/clusterfuzz-testcase-minimized-ffmpeg_dem_VIVIDAS_fuzzer-5097985075314688

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit e44214a824)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 59c05f51d5 avcodec/sonic: Use unsigned temporary in predictor_calc_error()
Fixes: signed integer overflow: -2147471366 - 18638 cannot be represented in type 'int'
Fixes: 30157/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SONIC_fuzzer-5171199746506752

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 075d793ba8)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 79ff380da7 avformat/jacosubdec: Use 64bit intermediate for start/end timestamp shift
Fixes: signed integer overflow: -1957694447 + -1620425806 cannot be represented in type 'int'
Fixes: 30207/clusterfuzz-testcase-minimized-ffmpeg_dem_JACOSUB_fuzzer-5050791771635712

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 2c477be08a)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 81178db83b avformat/flvdec: Check array entry number
Fixes: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
Fixes: 30209/clusterfuzz-testcase-minimized-ffmpeg_dem_FLV_fuzzer-5724831658147840

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit b5d8fe1c87)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 039ecef275 avcodec/h264_slice: Check sps in h264_slice_header_init()
Fixes: null pointer dereference
Fixes: h264_slice_header_init.mp4

Found-by: Rafael Dutra <rafael.dutra@cispa.de>
Tested-by: Rafael Dutra <rafael.dutra@cispa.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 8047243899)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer c5a61adcca avformat/movenc: Avoid loosing cluster array on failure
Fixes: crash
Fixes: check_pkt.mp4

Found-by: Rafael Dutra <rafael.dutra@cispa.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 5c2ff44f91)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 095f50e06e avformat/avidec: Check for dv streams before using priv_data in parse ##dc/##wb
Fixes: null pointer dereference
Fixes: 31588/clusterfuzz-testcase-minimized-ffmpeg_dem_AVI_fuzzer-6165716135968768

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit f733688d30)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 2af5b3fa08 avformat/mov: Check sample size for overflow in mov_parse_stsd_audio()
Fixes: signed integer overflow: 2 * 1914708000 cannot be represented in type 'int'
Fixes: 31639/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-6303428239294464

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit d35677736a)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 5d1e309e67 avcodec/sga: Check for array end in lzss_decompress()
Fixes: out of array access
Fixes: 31640/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SGA_fuzzer-5630883286614016
Fixes: 31619/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SGA_fuzzer-5176667708456960

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit e8bd34fe4f)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer 9a3e525b7c avformat/sbgdec: Check for overflow in last loop in expand_timestamps()
Fixes: signed integer overflow: 9223372036854775807 + 86400000000 cannot be represented in type 'long'
Fixes: 31003/clusterfuzz-testcase-minimized-ffmpeg_dem_SBG_fuzzer-6256298771480576

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit f44068db1e)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Michael Niedermayer e42efdce95 avcodec/ffwavesynth: Avoid signed integer overflow in phi_at()
Fixes: signed integer overflow: 2314885530818453536 - -9070214327174160352 cannot be represented in type 'long'
Fixes: 31000/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FFWAVESYNTH_fuzzer-6558389742206976

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit be08b84f8b)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-04-01 11:38:44 +02:00
Gyan Doshi b26c6df919 rtpenc_mpegts: add AVClass to the muxer context 2021-04-01 09:36:26 +05:30
Gyan Doshi 7a74129fa9 avformat/rtpenc_mpegts: stop leaks
Fixes CID 1474460 & 1474461
2021-03-28 15:55:41 +05:30
Gyan Doshi fd80c0b95f avformat/rtpenc_mpegts: convey options for rtp muxer
Cherry-picked 2c806aa2b4
2021-03-26 14:44:31 +05:30
Gyan Doshi a6dc1e84d2 avformat/rtpenc_mpegts: relay streamid to mpegts muxer streams.
Cherry-picked 325bb04188
2021-03-26 14:44:06 +05:30
Gyan Doshi 390b6f0cba avformat/rtpenc_mpegts: convey options for mpeg-ts muxer
Fixes #5239

Cherry-picked affe911c65
2021-03-26 14:43:40 +05:30
Gyan Doshi 72389f7916 avformat/rtp_mpegts: typedef MuxChain struct
Cherry-picked 75fd3e1519
2021-03-26 14:43:08 +05:30
Gyan Doshi 9315b45dd2 configure: select child muxers for rtp_mpegts
Cherry-picked 36a5ae619a
2021-03-26 14:42:34 +05:30
Zane van Iperen df9fbc442d avformat/pp_bnk: allow seeking to start
Allows "ffplay -loop" to work.

Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 64fb63411d)
2021-03-25 16:34:42 +10:00
Zane van Iperen 2fd48331d5 avformat/alp: allow seeking to start
Allows "ffplay -loop" to work.

Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit ea9732c5d6)
2021-03-25 16:34:42 +10:00
Zane van Iperen a98413afb9 avformat/kvag: allow seeking to start
Allows "ffplay -loop" to work.

Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 3cc4a140ef)
2021-03-25 16:34:41 +10:00
Zane van Iperen 0cfea0581b avcodec/adpcm_ima_cunning: reset state on flush
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit e550667f61)
2021-03-25 16:34:41 +10:00
Zane van Iperen 0d00e151d1 avcodec/adpcm_ima_alp: reset state on flush
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 257d9f91fc)
2021-03-25 16:34:41 +10:00
Zane van Iperen 990bccfad6 avcodec/adpcm_ima_ssi: reset state on flush
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit ff7bbd6d88)
2021-03-25 16:34:40 +10:00
Zane van Iperen f0169e9d58 avcodec/adpcm_argo: reset state on flush
Commit 003b5c800f introduced seeking in argo_asf,
but this was missed, leading to non-deterministic output.

Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 660c14a9b9)
2021-03-25 16:34:40 +10:00
Zane van Iperen 2057068495 avcodec/adpcm_aica: reset state in flush callback
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit efb58ec8f9)
2021-03-25 16:34:40 +10:00
Zane van Iperen 0b9d7b6f8d avcodec/adpcm_zork: reset state in flush callback
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 95280cf3e7)
2021-03-25 16:34:39 +10:00
Zane van Iperen ebe065c177 avcodec/adpcm: add comment to has_status field
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
(cherry picked from commit 55a50885b9)
2021-03-25 16:34:39 +10:00
nyanmisaka 5f2018c490 avfilter/overlay_cuda: fix framesync with embedded PGS subtitle
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
2021-03-25 04:36:41 +01:00
nyanmisaka 3d79b9357d avfilter/hwupload_cuda: add YUVA420P format support
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
2021-03-25 04:36:39 +01:00
James Almer 0be265e9a1 Revert "lavf: move AVStream.*index_entries* to AVStreamInternal"
This reverts commit cea7c19cda.

Until an API is added to make index_entries public in a proper way, keeping
this here is harmless.
2021-03-23 14:09:27 -03:00
Andreas Rheinhardt 5996184bea avcodec/put_bits: Restore x64 ABI compatibility with releases <= 4.3
88d80cb975 changed the type of
PutBitContext.BitBuf to uint64_t; it used to be an uint32_t.
While said structure is not public, it is nevertheless used by
certain avpriv functions and therefore crosses library boundaries:
avpriv_align_put_bits and avpriv_copy_bits were used in other libraries
in release 4.3 (and at the time of 88d80cb9) and so this commit broke
ABI.

This commit mitigates the trouble caused by this by using an uint32_t
again, but only for the 4.4 release branch and not the master branch,
as doing so for master, would break the ABI of master again, although
it is very unlikely that anyone would be helped by this (there don't
seem to be any users that combine libavcodec built from master and
libavformat from an old release: otherwise we would have received bug
reports about said ABI break).

Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2021-03-23 01:21:29 +01:00
Andreas Rheinhardt 16af5236ae avcodec/avcodec: Sanitize options before using them
This is how it is supposed to happen, yet when using frame threading,
the codec's init function has been called before preinit. This can lead
to crashes when e.g. using unsupported lowres values for decoders
together with frame threading.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 746796ceb4)
2021-03-22 08:39:02 +01:00
Andreas Rheinhardt 2b114adcf4 avcodec/parser: Don't return pointer to stack buffer
When flushing, the parser receives a dummy buffer with padding
that lives on the stack of av_parser_parse2(). Certain parsers
(e.g. Dolby E) only analyze the input, but don't repack it. When
flushing, such parsers return a pointer to the stack buffer and
a size of 0. And this is also what av_parser_parse2() returns.

Fix this by always resetting poutbuf in case poutbuf_size is zero.

Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 9faf3f8bb0)
2021-03-22 08:17:33 +01:00
Andreas Rheinhardt 2a5c577ef3 avformat/pp_bnk: Fix memleaks when reading non-stereo tracks
Commit 6973df1122 added support
for music tracks by outputting its two containing tracks
together in one packet. But the actual data is not contiguous
in the file and therefore one can't simply use av_get_packet()
(which has been used before) for it. Therefore the packet was
now allocated via av_new_packet() and read via avio_read();
and this is also for non-music files.

This causes problems because one can now longer rely on things
done automatically by av_get_packet(): It automatically freed
the packet in case of errors; this lead to memleaks in several
FATE-tests covering this demuxer. Furthermore, in case the data
read is less than the data desired, the returned packet was not
zero-allocated (the packet's padding was uninitialized);
for music files the actual data could even be uninitialized.

The former problems are fixed by using av_get_packet() for
non-music files; the latter problem is handled by erroring out
unless both tracks could be fully read.

Reviewed-by: Zane van Iperen <zane@zanevaniperen.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 8a73313412)
2021-03-22 08:17:10 +01:00
Derek Buitenhuis 8f099e3a67 FATE: Add test for probing MOV/MP4 files with extended box sizes
The test sample has to have no file extension, otherwise probing
happens to work, based off file extension alone, and we want to
test the actual probing function.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
(cherry picked from commit e668c55649)
2021-03-21 23:22:06 -03:00
Derek Buitenhuis cfe614787d avformat/mov: Fix extended atom size buffer length check
When extended atom size support was added to probing in
fec4a2d232, the buffer
size check was backwards, but probing continued to work
because there was no minimum size check yet, so despite
size being 1 on these atoms, and failing to read the 64-bit
size, the tag was still correctly read.

When 0b78016b2d introduced a
minimum size check, this exposed the bug, and broke probing
any files with extended atom sizes, such as entirely valid
large files that start whith mdat atoms.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
(cherry picked from commit 85f397c828)
2021-03-21 23:21:48 -03:00
James Almer 7efe57ba11 avformat: remove FF_API_INIT_PACKET from AVStream.attached_pic
This field needs to be replaced altogether, not just its type changed.
This will be done in a separate change.

Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 34f4f57800)
2021-03-21 19:07:09 -03:00
Michael Niedermayer da4d578621 Update versions for 4.4
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2021-03-20 01:01:12 +01:00
137 changed files with 1792 additions and 1280 deletions
+1 -1
View File
@@ -1 +1 @@
4.4.git
4.4
+15
View File
@@ -0,0 +1,15 @@
┌────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 4.4 "Rao" │
└────────────────────────────────────┘
The FFmpeg Project proudly presents FFmpeg 4.4 "Rao", about 10
months after the release of FFmpeg 4.3.
A complete Changelog is available at the root of the project, and the
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
We hope you will like this release as much as we enjoyed working on it, and
as usual, if you have any questions about it, or any FFmpeg related topic,
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
on the mailing-lists.
Vendored
+1
View File
@@ -3364,6 +3364,7 @@ opus_muxer_select="ogg_muxer"
psp_muxer_select="mov_muxer"
rtp_demuxer_select="sdp_demuxer"
rtp_muxer_select="golomb jpegtables"
rtp_mpegts_muxer_select="mpegts_muxer rtp_muxer"
rtpdec_select="asf_demuxer jpegtables mov_demuxer mpegts_demuxer rm_demuxer rtp_protocol srtp"
rtsp_demuxer_select="http_protocol rtpdec"
rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain"
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER = 4.4
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
+7 -4
View File
@@ -107,13 +107,16 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset,
uint8_t pix;
int lowdiff, highdiff;
int *best_cb = c->mc_best_cb;
static uint8_t index1[256];
static uint8_t index2[256];
static uint8_t dither[256];
uint8_t index1[256];
uint8_t index2[256];
uint8_t dither[256];
int i;
int distance;
/* generate lookup-tables for dither and index before looping */
/* Generate lookup-tables for dither and index before looping.
* This code relies on c->mc_luma_vals[c->mc_pal_size - 1] being
* the maximum of all the mc_luma_vals values and on the minimum
* being zero; this ensures that dither is properly initialized. */
i = 0;
for (a=0; a < 256; a++) {
if(i < c->mc_pal_size -1 && a == c->mc_luma_vals[i + 1]) {
-1
View File
@@ -27,7 +27,6 @@
#ifndef AVCODEC_AC3_H
#define AVCODEC_AC3_H
#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */
#define EAC3_MAX_CHANNELS 16 /**< maximum number of channels in EAC3 */
#define AC3_MAX_CHANNELS 7 /**< maximum number of channels, including coupling channel */
#define CPL_CH 0 /**< coupling channel index */
+1 -1
View File
@@ -1729,7 +1729,7 @@ static void ac3_output_frame(AC3EncodeContext *s, unsigned char *frame)
{
int blk;
init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE);
init_put_bits(&s->pb, frame, s->frame_size);
s->output_frame_header(s);
+32 -14
View File
@@ -100,7 +100,7 @@ static const int8_t mtf_index_table[16] = {
typedef struct ADPCMDecodeContext {
ADPCMChannelStatus status[14];
int vqa_version; /**< VQA version. Used for ADPCM_IMA_WS */
int has_status;
int has_status; /**< Status flag. Reset to 0 after a flush. */
} ADPCMDecodeContext;
static av_cold int adpcm_decode_init(AVCodecContext * avctx)
@@ -1811,11 +1811,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
}
break;
case AV_CODEC_ID_ADPCM_AICA:
if (!c->has_status) {
for (channel = 0; channel < avctx->channels; channel++)
c->status[channel].step = 0;
c->has_status = 1;
}
for (channel = 0; channel < avctx->channels; channel++) {
samples = samples_p[channel];
for (n = nb_samples >> 1; n > 0; n--) {
@@ -2077,13 +2072,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
}
break;
case AV_CODEC_ID_ADPCM_ZORK:
if (!c->has_status) {
for (channel = 0; channel < avctx->channels; channel++) {
c->status[channel].predictor = 0;
c->status[channel].step_index = 0;
}
c->has_status = 1;
}
for (n = 0; n < nb_samples * avctx->channels; n++) {
int v = bytestream2_get_byteu(&gb);
*samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v);
@@ -2121,7 +2109,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
static void adpcm_flush(AVCodecContext *avctx)
{
ADPCMDecodeContext *c = avctx->priv_data;
c->has_status = 0;
switch(avctx->codec_id) {
case AV_CODEC_ID_ADPCM_AICA:
for (int channel = 0; channel < avctx->channels; channel++)
c->status[channel].step = 0;
break;
case AV_CODEC_ID_ADPCM_ARGO:
for (int channel = 0; channel < avctx->channels; channel++) {
c->status[channel].sample1 = 0;
c->status[channel].sample2 = 0;
}
break;
case AV_CODEC_ID_ADPCM_IMA_ALP:
case AV_CODEC_ID_ADPCM_IMA_CUNNING:
case AV_CODEC_ID_ADPCM_IMA_SSI:
case AV_CODEC_ID_ADPCM_ZORK:
for (int channel = 0; channel < avctx->channels; channel++) {
c->status[channel].predictor = 0;
c->status[channel].step_index = 0;
}
break;
default:
/* Other codecs may want to handle this during decoding. */
c->has_status = 0;
return;
}
c->has_status = 1;
}
+8 -8
View File
@@ -959,14 +959,14 @@ static const AVOption options[] = {
{ NULL }
};
static const AVClass adpcm_encoder_class = {
.class_name = "ADPCM Encoder",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
#define ADPCM_ENCODER(id_, name_, sample_fmts_, capabilities_, long_name_) \
static const AVClass name_ ## _encoder_class = { \
.class_name = #name_, \
.item_name = av_default_item_name, \
.option = options, \
.version = LIBAVUTIL_VERSION_INT, \
}; \
\
AVCodec ff_ ## name_ ## _encoder = { \
.name = #name_, \
.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
@@ -979,7 +979,7 @@ AVCodec ff_ ## name_ ## _encoder = { \
.sample_fmts = sample_fmts_, \
.capabilities = capabilities_, \
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \
.priv_class = &adpcm_encoder_class, \
.priv_class = &name_ ## _encoder_class, \
}
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games");
+1 -1
View File
@@ -376,7 +376,7 @@ ASSSplitContext *ff_ass_split(const char *buf)
ASSSplitContext *ctx = av_mallocz(sizeof(*ctx));
if (!ctx)
return NULL;
if (buf && !memcmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header
if (buf && !strncmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header
buf += 3;
ctx->current_section = -1;
if (ass_split(ctx, buf) < 0) {
+1 -1
View File
@@ -120,7 +120,7 @@ static int av1_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
}
// If a Temporal Delimiter is present, it must be the first OBU.
if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
if (frag->nb_units && frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
if (ctx->td == BSF_ELEMENT_REMOVE)
ff_cbs_delete_unit(frag, 0);
} else if (pkt && ctx->td == BSF_ELEMENT_INSERT) {
+30 -24
View File
@@ -318,6 +318,13 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
avctx->time_base.den = avctx->sample_rate;
}
if (av_codec_is_encoder(avctx->codec))
ret = ff_encode_preinit(avctx);
else
ret = ff_decode_preinit(avctx);
if (ret < 0)
goto free_and_end;
if (!HAVE_THREADS)
av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n");
@@ -339,13 +346,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS))
avctx->thread_count = 1;
if (av_codec_is_encoder(avctx->codec))
ret = ff_encode_preinit(avctx);
else
ret = ff_decode_preinit(avctx);
if (ret < 0)
goto free_and_end;
if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME)
|| avci->frame_thread_encoder)) {
ret = avctx->codec->init(avctx);
@@ -644,6 +644,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
}
static const char *unknown_if_null(const char *str)
{
return str ? str : "unknown";
}
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
{
const char *codec_type;
@@ -653,6 +658,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
int new_line = 0;
AVRational display_aspect_ratio;
const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", ";
const char *str;
if (!buf || buf_size <= 0)
return;
@@ -688,28 +694,27 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
av_strlcat(buf, separator, buf_size);
snprintf(buf + strlen(buf), buf_size - strlen(buf),
"%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" :
av_get_pix_fmt_name(enc->pix_fmt));
"%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" :
unknown_if_null(av_get_pix_fmt_name(enc->pix_fmt)));
if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE &&
enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth)
av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample);
if (enc->color_range != AVCOL_RANGE_UNSPECIFIED)
av_strlcatf(detail, sizeof(detail), "%s, ",
av_color_range_name(enc->color_range));
if (enc->color_range != AVCOL_RANGE_UNSPECIFIED &&
(str = av_color_range_name(enc->color_range)))
av_strlcatf(detail, sizeof(detail), "%s, ", str);
if (enc->colorspace != AVCOL_SPC_UNSPECIFIED ||
enc->color_primaries != AVCOL_PRI_UNSPECIFIED ||
enc->color_trc != AVCOL_TRC_UNSPECIFIED) {
if (enc->colorspace != (int)enc->color_primaries ||
enc->colorspace != (int)enc->color_trc) {
const char *col = unknown_if_null(av_color_space_name(enc->colorspace));
const char *pri = unknown_if_null(av_color_primaries_name(enc->color_primaries));
const char *trc = unknown_if_null(av_color_transfer_name(enc->color_trc));
if (strcmp(col, pri) || strcmp(col, trc)) {
new_line = 1;
av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ",
av_color_space_name(enc->colorspace),
av_color_primaries_name(enc->color_primaries),
av_color_transfer_name(enc->color_trc));
col, pri, trc);
} else
av_strlcatf(detail, sizeof(detail), "%s, ",
av_get_colorspace_name(enc->colorspace));
av_strlcatf(detail, sizeof(detail), "%s, ", col);
}
if (enc->field_order != AV_FIELD_UNKNOWN) {
@@ -727,9 +732,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
}
if (av_log_get_level() >= AV_LOG_VERBOSE &&
enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
av_strlcatf(detail, sizeof(detail), "%s, ",
av_chroma_location_name(enc->chroma_sample_location));
enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED &&
(str = av_chroma_location_name(enc->chroma_sample_location)))
av_strlcatf(detail, sizeof(detail), "%s, ", str);
if (strlen(detail) > 1) {
detail[strlen(detail) - 2] = 0;
@@ -787,9 +792,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
"%d Hz, ", enc->sample_rate);
}
av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout);
if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) {
if (enc->sample_fmt != AV_SAMPLE_FMT_NONE &&
(str = av_get_sample_fmt_name(enc->sample_fmt))) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %s", av_get_sample_fmt_name(enc->sample_fmt));
", %s", str);
}
if ( enc->bits_per_raw_sample > 0
&& enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8)
+7 -3
View File
@@ -70,7 +70,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
BinkAudioContext *s = avctx->priv_data;
int sample_rate = avctx->sample_rate;
int sample_rate_half;
int i;
int i, ret;
int frame_len_bits;
/* determine frame length */
@@ -132,11 +132,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->first = 1;
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
else if (CONFIG_BINKAUDIO_DCT_DECODER)
ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
else
av_assert0(0);
if (ret < 0)
return ret;
s->pkt = av_packet_alloc();
if (!s->pkt)
@@ -345,6 +347,7 @@ AVCodec ff_binkaudio_rdft_decoder = {
.close = decode_end,
.receive_frame = binkaudio_receive_frame,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
AVCodec ff_binkaudio_dct_decoder = {
@@ -357,4 +360,5 @@ AVCodec ff_binkaudio_dct_decoder = {
.close = decode_end,
.receive_frame = binkaudio_receive_frame,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
+20 -19
View File
@@ -45,14 +45,15 @@ void av_bsf_free(AVBSFContext **pctx)
return;
ctx = *pctx;
if (ctx->filter->close)
ctx->filter->close(ctx);
if (ctx->internal) {
if (ctx->filter->close)
ctx->filter->close(ctx);
av_packet_free(&ctx->internal->buffer_pkt);
av_freep(&ctx->internal);
}
if (ctx->filter->priv_class && ctx->priv_data)
av_opt_free(ctx->priv_data);
if (ctx->internal)
av_packet_free(&ctx->internal->buffer_pkt);
av_freep(&ctx->internal);
av_freep(&ctx->priv_data);
avcodec_parameters_free(&ctx->par_in);
@@ -110,20 +111,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
ret = AVERROR(ENOMEM);
goto fail;
}
bsfi = av_mallocz(sizeof(*bsfi));
if (!bsfi) {
ret = AVERROR(ENOMEM);
goto fail;
}
ctx->internal = bsfi;
bsfi->buffer_pkt = av_packet_alloc();
if (!bsfi->buffer_pkt) {
ret = AVERROR(ENOMEM);
goto fail;
}
/* allocate priv data and init private options */
if (filter->priv_data_size) {
ctx->priv_data = av_mallocz(filter->priv_data_size);
@@ -136,6 +123,20 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
av_opt_set_defaults(ctx->priv_data);
}
}
/* Allocate AVBSFInternal; must happen after priv_data has been allocated
* so that a filter->close needing priv_data is never called without. */
bsfi = av_mallocz(sizeof(*bsfi));
if (!bsfi) {
ret = AVERROR(ENOMEM);
goto fail;
}
ctx->internal = bsfi;
bsfi->buffer_pkt = av_packet_alloc();
if (!bsfi->buffer_pkt) {
ret = AVERROR(ENOMEM);
goto fail;
}
*pctx = ctx;
return 0;
+62 -14
View File
@@ -221,6 +221,7 @@ static void free_buffers(CFHDContext *s)
int i, j;
for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) {
Plane *p = &s->plane[i];
av_freep(&s->plane[i].idwt_buf);
av_freep(&s->plane[i].idwt_tmp);
s->plane[i].idwt_size = 0;
@@ -230,9 +231,16 @@ static void free_buffers(CFHDContext *s)
for (j = 0; j < 10; j++)
s->plane[i].l_h[j] = NULL;
for (j = 0; j < DWT_LEVELS_3D; j++)
p->band[j][0].read_ok =
p->band[j][1].read_ok =
p->band[j][2].read_ok =
p->band[j][3].read_ok = 0;
}
s->a_height = 0;
s->a_width = 0;
s->a_transform_type = INT_MIN;
}
static int alloc_buffers(AVCodecContext *avctx)
@@ -356,6 +364,7 @@ static int alloc_buffers(AVCodecContext *avctx)
}
}
s->a_transform_type = s->transform_type;
s->a_height = s->coded_height;
s->a_width = s->coded_width;
s->a_format = s->coded_format;
@@ -655,7 +664,8 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
s->coded_height = s->a_height;
if (s->a_width != s->coded_width || s->a_height != s->coded_height ||
s->a_format != s->coded_format) {
s->a_format != s->coded_format ||
s->transform_type != s->a_transform_type) {
free_buffers(s);
if ((ret = alloc_buffers(avctx)) < 0) {
free_buffers(s);
@@ -698,11 +708,18 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual];
/* Lowpass coefficients */
if (tag == BitstreamMarker && data == 0xf0f && s->a_width && s->a_height) {
int lowpass_height = s->plane[s->channel_num].band[0][0].height;
int lowpass_width = s->plane[s->channel_num].band[0][0].width;
int lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height;
int lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width;
if (tag == BitstreamMarker && data == 0xf0f) {
int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width;
if (!s->a_width || !s->a_height) {
ret = AVERROR_INVALIDDATA;
goto end;
}
lowpass_height = s->plane[s->channel_num].band[0][0].height;
lowpass_width = s->plane[s->channel_num].band[0][0].width;
lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height;
lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width;
if (lowpass_width < 3 ||
lowpass_width > lowpass_a_width) {
@@ -749,20 +766,30 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
lowpass_width * sizeof(*coeff_data));
}
s->plane[s->channel_num].band[0][0].read_ok = 1;
av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height);
}
if ((tag == BandHeader || tag == BandSecondPass) && s->subband_num_actual != 255 && s->a_width && s->a_height) {
int highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height;
int highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width;
int highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width;
int highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height;
int highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride;
av_assert0(s->subband_num_actual != 255);
if (tag == BandHeader || tag == BandSecondPass) {
int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected;
int expected;
int a_expected = highpass_a_height * highpass_a_width;
int level, run, coeff;
int count = 0, bytes;
if (!s->a_width || !s->a_height) {
ret = AVERROR_INVALIDDATA;
goto end;
}
highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height;
highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width;
highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width;
highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height;
highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride;
a_expected = highpass_a_height * highpass_a_width;
if (!got_buffer) {
av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n");
ret = AVERROR(EINVAL);
@@ -873,6 +900,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
bytestream2_seek(&gb, bytes, SEEK_CUR);
av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected);
s->plane[s->channel_num].band[s->level][s->subband_num].read_ok = 1;
finish:
if (s->subband_num_actual != 255)
s->codebook = 0;
@@ -888,6 +916,7 @@ finish:
ff_thread_finish_setup(avctx);
if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE ||
s->a_transform_type == INT_MIN ||
s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE) {
av_log(avctx, AV_LOG_ERROR, "Invalid dimensions\n");
ret = AVERROR(EINVAL);
@@ -900,6 +929,22 @@ finish:
goto end;
}
for (plane = 0; plane < s->planes; plane++) {
int o, level;
for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) {
if (s->transform_type == 2)
if (level == 2 || level == 5)
continue;
for (o = !!level; o < 4 ; o++) {
if (!s->plane[plane].band[level][o].read_ok) {
ret = AVERROR_INVALIDDATA;
goto end;
}
}
}
}
if (s->transform_type == 0 && s->sample_type != 1) {
for (plane = 0; plane < s->planes && !ret; plane++) {
/* level 1 */
@@ -1381,12 +1426,14 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
if (pdst->plane[0].idwt_size != psrc->plane[0].idwt_size ||
pdst->a_format != psrc->a_format ||
pdst->a_width != psrc->a_width ||
pdst->a_height != psrc->a_height)
pdst->a_height != psrc->a_height ||
pdst->a_transform_type != psrc->a_transform_type)
free_buffers(pdst);
pdst->a_format = psrc->a_format;
pdst->a_width = psrc->a_width;
pdst->a_height = psrc->a_height;
pdst->a_transform_type = psrc->a_transform_type;
pdst->transform_type = psrc->transform_type;
pdst->progressive = psrc->progressive;
pdst->planes = psrc->planes;
@@ -1395,6 +1442,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
pdst->coded_width = pdst->a_width;
pdst->coded_height = pdst->a_height;
pdst->coded_format = pdst->a_format;
pdst->transform_type = pdst->a_transform_type;
ret = alloc_buffers(dst);
if (ret < 0)
return ret;
+2
View File
@@ -114,6 +114,7 @@ typedef struct SubBand {
int width;
int a_height;
int height;
int8_t read_ok;
} SubBand;
typedef struct Plane {
@@ -165,6 +166,7 @@ typedef struct CFHDContext {
int a_width;
int a_height;
int a_format;
int a_transform_type;
int bpc; // bits per channel/component
int channel_cnt;
+4 -4
View File
@@ -925,10 +925,10 @@ static void fill_in_adpcm_bufer(DCAEncContext *c)
* But there are no proper value in decoder history, so likely result will be no good.
* Bitstream has "Predictor history flag switch", but this flag disables history for all subbands
*/
samples[0] = c->adpcm_history[ch][band][0] << 7;
samples[1] = c->adpcm_history[ch][band][1] << 7;
samples[2] = c->adpcm_history[ch][band][2] << 7;
samples[3] = c->adpcm_history[ch][band][3] << 7;
samples[0] = c->adpcm_history[ch][band][0] * (1 << 7);
samples[1] = c->adpcm_history[ch][band][1] * (1 << 7);
samples[2] = c->adpcm_history[ch][band][2] * (1 << 7);
samples[3] = c->adpcm_history[ch][band][3] * (1 << 7);
}
}
}
+4 -6
View File
@@ -261,24 +261,22 @@ const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile
const uint8_t *frame, unsigned buf_size)
{
#if CONFIG_DVPROFILE
int i, dsf, stype;
int i, dsf, stype, pal;
if(buf_size < DV_PROFILE_BYTES)
return NULL;
dsf = (frame[3] & 0x80) >> 7;
stype = frame[80 * 5 + 48 + 3] & 0x1f;
pal = !!(frame[80 * 5 + 48 + 3] & 0x20);
/* 576i50 25Mbps 4:1:1 is a special case */
if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) ||
(stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576))
return &dv_profiles[2];
if( stype == 0
&& codec
&& (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC"))
&& codec->coded_width ==720
&& codec->coded_height==576)
/* hack for trac issues #8333 and #2177, PAL DV files with dsf flag 0 - detect via pal flag and buf_size */
if (dsf == 0 && pal == 1 && stype == dv_profiles[1].video_stype && buf_size == dv_profiles[1].frame_size)
return &dv_profiles[1];
for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
+1 -1
View File
@@ -565,7 +565,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (avctx->pix_fmt == avctx->codec->pix_fmts[i])
break;
if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE
&& !((avctx->codec_id == AV_CODEC_ID_MJPEG || avctx->codec_id == AV_CODEC_ID_LJPEG)
&& !(avctx->codec_id == AV_CODEC_ID_MJPEG
&& avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) {
char buf[128];
snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt);
+6 -1
View File
@@ -422,7 +422,12 @@ static int huf_decode(VLC *vlc, GetByteContext *gb, int nbits, int run_sym,
if (x == run_sym) {
int run = get_bits(&gbit, 8);
uint16_t fill = out[oe - 1];
uint16_t fill;
if (oe == 0 || oe + run > no)
return AVERROR_INVALIDDATA;
fill = out[oe - 1];
while (run-- > 0)
out[oe++] = fill;
+1 -1
View File
@@ -188,7 +188,7 @@ static uint64_t frac64(uint64_t a, uint64_t b)
static uint64_t phi_at(struct ws_interval *in, int64_t ts)
{
uint64_t dt = ts - in->ts_start;
uint64_t dt = ts - (uint64_t)in->ts_start;
uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */
dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1);
return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi;
+1
View File
@@ -1513,4 +1513,5 @@ AVCodec ff_flac_encoder = {
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE },
.priv_class = &flac_encoder_class,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
+1 -1
View File
@@ -159,7 +159,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks,
b->enc = encbuf;
b->data = databuf;
encbuf += b->width * b->height * 3;
databuf += !databuf ? 0 : b->width * b->height * 6;
databuf = databuf ? databuf + b->width * b->height * 6 : NULL;
}
}
}
+1 -1
View File
@@ -1029,7 +1029,7 @@ static int kempf_restore_buf(const uint8_t *src, int len,
else if (npal <= 16) nb = 4;
else nb = 8;
for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) {
for (j = 0; j < height; j++, dst += stride, jpeg_tile = FF_PTR_ADD(jpeg_tile, tile_stride)) {
if (get_bits(&gb, 8))
continue;
for (i = 0; i < width; i++) {
+1 -1
View File
@@ -678,6 +678,6 @@ AVCodec ff_h261_decoder = {
.close = h261_decode_end,
.decode = h261_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.max_lowres = 3,
};
+2 -2
View File
@@ -771,7 +771,7 @@ AVCodec ff_h263_decoder = {
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
@@ -789,7 +789,7 @@ AVCodec ff_h263p_decoder = {
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
+1 -1
View File
@@ -466,7 +466,7 @@ static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
if (ctx->aud == BSF_ELEMENT_REMOVE)
ff_cbs_delete_unit(au, 0);
} else {
if (ctx->aud == BSF_ELEMENT_INSERT) {
if (pkt && ctx->aud == BSF_ELEMENT_INSERT) {
err = h264_metadata_insert_aud(bsf, au);
if (err < 0)
return err;
+7 -3
View File
@@ -304,9 +304,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
if (dst == src)
return 0;
// We can't fail if SPS isn't set at it breaks current skip_frame code
//if (!h1->ps.sps)
// return AVERROR_INVALIDDATA;
if (inited && !h1->ps.sps)
return AVERROR_INVALIDDATA;
if (inited &&
(h->width != h1->width ||
@@ -922,6 +921,11 @@ static int h264_slice_header_init(H264Context *h)
const SPS *sps = h->ps.sps;
int i, ret;
if (!sps) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
ff_set_sar(h->avctx, sps->sar);
av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
&h->chroma_x_shift, &h->chroma_y_shift);
+1 -1
View File
@@ -335,7 +335,7 @@ static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
int err, i;
// If an AUD is present, it must be the first NAL unit.
if (au->units[0].type == HEVC_NAL_AUD) {
if (au->nb_units && au->units[0].type == HEVC_NAL_AUD) {
if (ctx->aud == BSF_ELEMENT_REMOVE)
ff_cbs_delete_unit(au, 0);
} else {
+5 -3
View File
@@ -173,7 +173,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
int uqvq, ret;
unsigned int mthread_inlen, mthread_outlen;
unsigned int len = buf_size;
int linesize;
int linesize, offset;
if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
return ret;
@@ -373,8 +373,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
/* Convert colorspace */
y_out = frame->data[0] + (height - 1) * frame->linesize[0];
u_out = frame->data[1] + (height - 1) * frame->linesize[1];
v_out = frame->data[2] + (height - 1) * frame->linesize[2];
offset = (height - 1) * frame->linesize[1];
u_out = FF_PTR_ADD(frame->data[1], offset);
offset = (height - 1) * frame->linesize[2];
v_out = FF_PTR_ADD(frame->data[2], offset);
switch (c->imgtype) {
case IMGTYPE_YUV111:
for (row = 0; row < height; row++) {
+4
View File
@@ -76,6 +76,10 @@ static int decode_idat(LSCRContext *s, int length)
int ret;
s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
s->zstream.next_in = s->gb.buffer;
if (length <= 0)
return AVERROR_INVALIDDATA;
bytestream2_skip(&s->gb, length);
/* decode one line if possible */
+16 -16
View File
@@ -76,6 +76,7 @@ static int init_default_huffman_tables(MJpegDecodeContext *s)
int i, ret;
for (i = 0; i < FF_ARRAY_ELEMS(ht); i++) {
ff_free_vlc(&s->vlcs[ht[i].class][ht[i].index]);
ret = ff_mjpeg_build_vlc(&s->vlcs[ht[i].class][ht[i].index],
ht[i].bits, ht[i].values,
ht[i].class == 1, s->avctx);
@@ -153,7 +154,8 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
if (ff_mjpeg_decode_dht(s)) {
av_log(avctx, AV_LOG_ERROR,
"error using external huffman table, switching back to internal\n");
init_default_huffman_tables(s);
if ((ret = init_default_huffman_tables(s)) < 0)
return ret;
}
}
if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
@@ -2085,28 +2087,26 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
/* Allocate if this is the first APP2 we've seen. */
if (s->iccnum == 0) {
s->iccdata = av_mallocz(nummarkers * sizeof(*(s->iccdata)));
s->iccdatalens = av_mallocz(nummarkers * sizeof(*(s->iccdatalens)));
if (!s->iccdata || !s->iccdatalens) {
if (!FF_ALLOCZ_TYPED_ARRAY(s->iccentries, nummarkers)) {
av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data arrays\n");
return AVERROR(ENOMEM);
}
s->iccnum = nummarkers;
}
if (s->iccdata[seqno - 1]) {
if (s->iccentries[seqno - 1].data) {
av_log(s->avctx, AV_LOG_WARNING, "Duplicate ICC sequence number\n");
goto out;
}
s->iccdatalens[seqno - 1] = len;
s->iccdata[seqno - 1] = av_malloc(len);
if (!s->iccdata[seqno - 1]) {
s->iccentries[seqno - 1].length = len;
s->iccentries[seqno - 1].data = av_malloc(len);
if (!s->iccentries[seqno - 1].data) {
av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data buffer\n");
return AVERROR(ENOMEM);
}
memcpy(s->iccdata[seqno - 1], align_get_bits(&s->gb), len);
memcpy(s->iccentries[seqno - 1].data, align_get_bits(&s->gb), len);
skip_bits(&s->gb, len << 3);
len = 0;
s->iccread++;
@@ -2315,11 +2315,11 @@ static void reset_icc_profile(MJpegDecodeContext *s)
{
int i;
if (s->iccdata)
if (s->iccentries) {
for (i = 0; i < s->iccnum; i++)
av_freep(&s->iccdata[i]);
av_freep(&s->iccdata);
av_freep(&s->iccdatalens);
av_freep(&s->iccentries[i].data);
av_freep(&s->iccentries);
}
s->iccread = 0;
s->iccnum = 0;
@@ -2835,7 +2835,7 @@ the_end:
/* Sum size of all parts. */
for (i = 0; i < s->iccnum; i++)
total_size += s->iccdatalens[i];
total_size += s->iccentries[i].length;
sd = av_frame_new_side_data(frame, AV_FRAME_DATA_ICC_PROFILE, total_size);
if (!sd) {
@@ -2845,8 +2845,8 @@ the_end:
/* Reassemble the parts, which are now in-order. */
for (i = 0; i < s->iccnum; i++) {
memcpy(sd->data + offset, s->iccdata[i], s->iccdatalens[i]);
offset += s->iccdatalens[i];
memcpy(sd->data + offset, s->iccentries[i].data, s->iccentries[i].length);
offset += s->iccentries[i].length;
}
}
+6 -2
View File
@@ -44,6 +44,11 @@
#define MAX_COMPONENTS 4
typedef struct ICCEntry {
uint8_t *data;
int length;
} ICCEntry;
typedef struct MJpegDecodeContext {
AVClass *class;
AVCodecContext *avctx;
@@ -138,8 +143,7 @@ typedef struct MJpegDecodeContext {
const AVPixFmtDescriptor *pix_desc;
uint8_t **iccdata;
int *iccdatalens;
ICCEntry *iccentries;
int iccnum;
int iccread;
+4 -2
View File
@@ -312,8 +312,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
av_cold void ff_mjpeg_encode_close(MpegEncContext *s)
{
av_freep(&s->mjpeg_ctx->huff_buffer);
av_freep(&s->mjpeg_ctx);
if (s->mjpeg_ctx) {
av_freep(&s->mjpeg_ctx->huff_buffer);
av_freep(&s->mjpeg_ctx);
}
}
/**
+23 -23
View File
@@ -109,8 +109,8 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co
me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){
MotionEstContext * const c= &s->me;
const int stride= c->stride;
const int hx= subx + (x<<(1+qpel));
const int hy= suby + (y<<(1+qpel));
const int hx = subx + x * (1 << (1 + qpel));
const int hy = suby + y * (1 << (1 + qpel));
uint8_t * const * const ref= c->ref[ref_index];
uint8_t * const * const src= c->src[src_index];
int d;
@@ -599,7 +599,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
if (P_LEFT[0] > c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift);
/* special case for first line */
if (s->first_slice_line && block<2) {
@@ -610,10 +610,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
if (P_TOP[1] > c->ymax * (1 << shift)) P_TOP[1] = c->ymax * (1 << shift);
if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift);
if (P_TOPRIGHT[1] > c->ymax * (1 << shift)) P_TOPRIGHT[1] = c->ymax * (1 << shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
@@ -629,8 +629,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
continue;
if (i>4 && i<9)
continue;
if(P[i][0] > (c->xmax<<shift)) P[i][0]= (c->xmax<<shift);
if(P[i][1] > (c->ymax<<shift)) P[i][1]= (c->ymax<<shift);
if (P[i][0] > c->xmax * (1 << shift)) P[i][0] = c->xmax * (1 << shift);
if (P[i][1] > c->ymax * (1 << shift)) P[i][1] = c->ymax * (1 <<shift );
}
dmin4 = epzs_motion_search2(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift, 1);
@@ -785,7 +785,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0];
P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1];
if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1);
if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1);
if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1);
if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1);
if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1);
@@ -839,7 +839,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
dmin_sum += best_dmin;
}
c->ymin<<=1;
c->ymin *= 2;
c->ymax<<=1;
c->stride>>=1;
c->uvstride>>=1;
@@ -981,8 +981,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
if(mx || my)
mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference
}else{
mx <<=shift;
my <<=shift;
mx *= 1 << shift;
my *= 1 << shift;
}
if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
&& !c->skip && varc>50<<8 && vard>10<<8){
@@ -1143,7 +1143,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];
P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1];
if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift);
if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift);
if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift);
P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
@@ -1155,7 +1155,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
if(mv_table == s->b_forw_mv_table){
mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);
}else{
mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift);
mv_scale = ((s->pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<<shift);
}
dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);
@@ -1255,8 +1255,8 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
const int flags= c->sub_flags;
const int qpel= flags&FLAG_QPEL;
const int shift= 1+qpel;
const int xmin= c->xmin<<shift;
const int ymin= c->ymin<<shift;
const int xmin= c->xmin * (1 << shift);
const int ymin= c->ymin * (1 << shift);
const int xmax= c->xmax<<shift;
const int ymax= c->ymax<<shift;
#define HASH(fx,fy,bx,by) ((fx)+17*(fy)+63*(bx)+117*(by))
@@ -1454,15 +1454,15 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
c->pred_x=0;
c->pred_y=0;
P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift);
P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift);
P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin * (1 << shift), xmax << shift);
P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin * (1 << shift), ymax << shift);
/* special case for first line */
if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped
P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift);
P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift);
P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift);
P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift);
P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin * (1 << shift), xmax << shift);
P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin * (1 << shift), ymax << shift);
P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1][0], xmin * (1 << shift), xmax << shift);
P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1][1], ymin * (1 << shift), ymax << shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
+9 -8
View File
@@ -82,7 +82,7 @@ static int hpel_motion_search(MpegEncContext * s,
if (mx > xmin && mx < xmax &&
my > ymin && my < ymax) {
int d= dmin;
const int index= (my<<ME_MAP_SHIFT) + mx;
const int index = my * (1 << ME_MAP_SHIFT) + mx;
const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
+ (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor;
const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]
@@ -95,13 +95,13 @@ static int hpel_motion_search(MpegEncContext * s,
#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
unsigned key;
unsigned map_generation= c->map_generation;
key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
key = (my - 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation;
av_assert2(c->map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
key = (my + 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation;
av_assert2(c->map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation;
key = (my) * (1 << ME_MAP_MV_BITS) + (mx + 1) + map_generation;
av_assert2(c->map[(index+1)&(ME_MAP_SIZE-1)] == key);
key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation;
key = (my) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation;
av_assert2(c->map[(index-1)&(ME_MAP_SIZE-1)] == key);
#endif
if(t<=b){
@@ -246,7 +246,7 @@ static int qpel_motion_search(MpegEncContext * s,
int bx=4*mx, by=4*my;
int d= dmin;
int i, nx, ny;
const int index= (my<<ME_MAP_SHIFT) + mx;
const int index = my * (1 << ME_MAP_SHIFT) + mx;
const int t= score_map[(index-(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)];
const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)];
const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)];
@@ -299,7 +299,8 @@ static int qpel_motion_search(MpegEncContext * s,
const int cy2= b + t - 2*c;
int cxy;
if(map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)] == ((my-1)<<ME_MAP_MV_BITS) + (mx-1) + map_generation){
if (map[(index - (1 << ME_MAP_SHIFT) - 1) & (ME_MAP_SIZE - 1)] ==
(my - 1) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation) {
tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
}else{
tl= cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);//FIXME wrong if chroma me is different
@@ -328,7 +329,7 @@ static int qpel_motion_search(MpegEncContext * s,
for(i=0; i<8; i++){
if(score < best[i]){
memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
memmove(best_pos[i + 1], best_pos[i], sizeof(best_pos[0]) * (7 - i));
best[i]= score;
best_pos[i][0]= nx + 4*mx;
best_pos[i][1]= ny + 4*my;
+5 -4
View File
@@ -2880,7 +2880,8 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
ff_mpv_common_end(&s->mpeg_enc_ctx);
if (s->mpeg_enc_ctx_allocated)
ff_mpv_common_end(&s->mpeg_enc_ctx);
av_buffer_unref(&s->a53_buf_ref);
return 0;
}
@@ -2897,7 +2898,7 @@ AVCodec ff_mpeg1video_decoder = {
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = flush,
.max_lowres = 3,
@@ -2931,7 +2932,7 @@ AVCodec ff_mpeg2video_decoder = {
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = flush,
.max_lowres = 3,
@@ -2976,7 +2977,7 @@ AVCodec ff_mpegvideo_decoder = {
.close = mpeg_decode_end,
.decode = mpeg_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = flush,
.max_lowres = 3,
+1 -2
View File
@@ -3579,8 +3579,7 @@ AVCodec ff_mpeg4_decoder = {
AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
FF_CODEC_CAP_ALLOCATE_PROGRESS |
FF_CODEC_CAP_INIT_CLEANUP,
FF_CODEC_CAP_ALLOCATE_PROGRESS,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
+4 -1
View File
@@ -79,8 +79,11 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
// linesize * interlaced * MBsize
// we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines
if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) ||
!FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2))
!FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) {
av_freep(&sc->edge_emu_buffer);
return AVERROR(ENOMEM);
}
me->temp = me->scratchpad;
sc->rd_scratchpad = me->scratchpad;
sc->b_scratchpad = me->scratchpad;
+74 -79
View File
@@ -366,13 +366,6 @@ static int init_duplicate_context(MpegEncContext *s)
if (s->mb_height & 1)
yc_size += 2*s->b8_stride + 2*s->mb_stride;
s->sc.edge_emu_buffer =
s->me.scratchpad =
s->me.temp =
s->sc.rd_scratchpad =
s->sc.b_scratchpad =
s->sc.obmc_scratchpad = NULL;
if (s->encoding) {
if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) ||
!FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE))
@@ -413,6 +406,35 @@ static int init_duplicate_context(MpegEncContext *s)
return 0;
}
/**
* Initialize an MpegEncContext's thread contexts. Presumes that
* slice_context_count is already set and that all the fields
* that are freed/reset in free_duplicate_context() are NULL.
*/
static int init_duplicate_contexts(MpegEncContext *s)
{
int nb_slices = s->slice_context_count, ret;
/* We initialize the copies before the original so that
* fields allocated in init_duplicate_context are NULL after
* copying. This prevents double-frees upon allocation error. */
for (int i = 1; i < nb_slices; i++) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i])
return AVERROR(ENOMEM);
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
return ret;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i ) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
s->start_mb_y = 0;
s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices
: s->mb_height;
return init_duplicate_context(s);
}
static void free_duplicate_context(MpegEncContext *s)
{
if (!s)
@@ -435,6 +457,15 @@ static void free_duplicate_context(MpegEncContext *s)
s->block = NULL;
}
static void free_duplicate_contexts(MpegEncContext *s)
{
for (int i = 1; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
av_freep(&s->thread_context[i]);
}
free_duplicate_context(s);
}
static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
{
#define COPY(a) bak->a = src->a
@@ -524,7 +555,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
}
if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
s->context_reinit = 0;
s->height = s1->height;
s->width = s1->width;
if ((ret = ff_mpv_common_frame_size_change(s)) < 0)
@@ -932,53 +962,42 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
s->picture[i].f = av_frame_alloc();
if (!s->picture[i].f)
return AVERROR(ENOMEM);
goto fail_nomem;
}
if (!(s->next_picture.f = av_frame_alloc()) ||
!(s->last_picture.f = av_frame_alloc()) ||
!(s->current_picture.f = av_frame_alloc()) ||
!(s->new_picture.f = av_frame_alloc()))
return AVERROR(ENOMEM);
goto fail_nomem;
if ((ret = init_context_frame(s)))
return AVERROR(ENOMEM);
goto fail;
s->parse_context.state = -1;
s->context_initialized = 1;
memset(s->thread_context, 0, sizeof(s->thread_context));
s->thread_context[0] = s;
s->slice_context_count = nb_slices;
// if (s->width && s->height) {
if (nb_slices > 1) {
for (i = 0; i < nb_slices; i++) {
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i])
return AVERROR(ENOMEM);
}
if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
return ret;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
} else {
if ((ret = init_duplicate_context(s)) < 0)
return ret;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
s->slice_context_count = nb_slices;
ret = init_duplicate_contexts(s);
if (ret < 0)
goto fail;
// }
return 0;
fail_nomem:
ret = AVERROR(ENOMEM);
fail:
ff_mpv_common_end(s);
return ret;
}
/**
* Frees and resets MpegEncContext fields depending on the resolution.
* Frees and resets MpegEncContext fields depending on the resolution
* as well as the slice thread contexts.
* Is used during resolution changes to avoid a full reinitialization of the
* codec.
*/
@@ -986,6 +1005,8 @@ static void free_context_frame(MpegEncContext *s)
{
int i, j, k;
free_duplicate_contexts(s);
av_freep(&s->mb_type);
av_freep(&s->p_mv_table_base);
av_freep(&s->b_forw_mv_table_base);
@@ -1038,16 +1059,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
if (!s->context_initialized)
return AVERROR(EINVAL);
if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
for (i = 1; i < s->slice_context_count; i++) {
av_freep(&s->thread_context[i]);
}
} else
free_duplicate_context(s);
free_context_frame(s);
if (s->picture)
@@ -1067,42 +1078,33 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
if ((s->width || s->height) &&
(err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
return err;
goto fail;
/* set chroma shifts */
err = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
&s->chroma_x_shift,
&s->chroma_y_shift);
if (err < 0)
goto fail;
if ((err = init_context_frame(s)))
return err;
goto fail;
memset(s->thread_context, 0, sizeof(s->thread_context));
s->thread_context[0] = s;
if (s->width && s->height) {
int nb_slices = s->slice_context_count;
if (nb_slices > 1) {
for (i = 0; i < nb_slices; i++) {
if (i) {
s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
if (!s->thread_context[i]) {
return AVERROR(ENOMEM);
}
}
if ((err = init_duplicate_context(s->thread_context[i])) < 0)
return err;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
} else {
err = init_duplicate_context(s);
if (err < 0)
return err;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
s->slice_context_count = nb_slices;
err = init_duplicate_contexts(s);
if (err < 0)
goto fail;
}
s->context_reinit = 0;
return 0;
fail:
free_context_frame(s);
s->context_reinit = 1;
return err;
}
/* init common structure for both encoder and decoder */
@@ -1113,15 +1115,9 @@ void ff_mpv_common_end(MpegEncContext *s)
if (!s)
return;
if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
for (i = 1; i < s->slice_context_count; i++) {
av_freep(&s->thread_context[i]);
}
free_context_frame(s);
if (s->slice_context_count > 1)
s->slice_context_count = 1;
} else free_duplicate_context(s);
av_freep(&s->parse_context.buffer);
s->parse_context.buffer_size = 0;
@@ -1153,9 +1149,8 @@ void ff_mpv_common_end(MpegEncContext *s)
ff_mpeg_unref_picture(s->avctx, &s->new_picture);
av_frame_free(&s->new_picture.f);
free_context_frame(s);
s->context_initialized = 0;
s->context_reinit = 0;
s->last_picture_ptr =
s->next_picture_ptr =
s->current_picture_ptr = NULL;
+4 -4
View File
@@ -627,7 +627,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
#if FF_API_PRIVATE_OPT
FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->mpeg_quant)
s->mpeg_quant = avctx->mpeg_quant;
s->mpeg_quant = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
@@ -1008,8 +1008,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (CONFIG_H263_ENCODER && s->out_format == FMT_H263)
ff_h263_encode_init(s);
if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)
if ((ret = ff_msmpeg4_encode_init(s)) < 0)
return ret;
ff_msmpeg4_encode_init(s);
if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
&& s->out_format == FMT_MPEG1)
ff_mpeg1_encode_init(s);
@@ -1696,7 +1695,8 @@ no_output_pic:
// input is not a shared pix -> reuse buffer for current_pix
s->current_picture_ptr = s->reordered_input_picture[0];
for (i = 0; i < 4; i++) {
s->new_picture.f->data[i] += INPLACE_OFFSET;
if (s->new_picture.f->data[i])
s->new_picture.f->data[i] += INPLACE_OFFSET;
}
}
ff_mpeg_unref_picture(s->avctx, &s->current_picture);
+1 -1
View File
@@ -50,7 +50,7 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n,
uint8_t **coded_block_ptr);
int ff_msmpeg4_encode_init(MpegEncContext *s);
void ff_msmpeg4_encode_init(MpegEncContext *s);
void ff_msmpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
+4 -4
View File
@@ -870,7 +870,7 @@ AVCodec ff_msmpeg4v1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -888,7 +888,7 @@ AVCodec ff_msmpeg4v2_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -906,7 +906,7 @@ AVCodec ff_msmpeg4v3_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -924,7 +924,7 @@ AVCodec ff_wmv1_decoder = {
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
+8 -15
View File
@@ -32,7 +32,6 @@
#include "libavutil/attributes.h"
#include "libavutil/avutil.h"
#include "libavutil/mem.h"
#include "mpegvideo.h"
#include "h263.h"
#include "internal.h"
@@ -46,13 +45,11 @@
static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
/* build the table which associate a (x,y) motion vector to a vlc */
static av_cold int init_mv_table(MVTable *tab)
static av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096])
{
int i, x, y;
tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096);
if (!tab->table_mv_index)
return AVERROR(ENOMEM);
tab->table_mv_index = table_mv_index;
/* mark all entries as not used */
for(i=0;i<4096;i++)
@@ -63,8 +60,6 @@ static av_cold int init_mv_table(MVTable *tab)
y = tab->table_mvy[i];
tab->table_mv_index[(x << 6) | y] = i;
}
return 0;
}
void ff_msmpeg4_code012(PutBitContext *pb, int n)
@@ -118,10 +113,10 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run,
return size;
}
av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
av_cold void ff_msmpeg4_encode_init(MpegEncContext *s)
{
static int init_done=0;
int i, ret;
int i;
ff_msmpeg4_common_init(s);
if(s->msmpeg4_version>=4){
@@ -130,12 +125,12 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
}
if (!init_done) {
static uint16_t mv_index_tables[2][4096];
/* init various encoding tables */
init_done = 1;
if ((ret = init_mv_table(&ff_mv_tables[0])) < 0)
return ret;
if ((ret = init_mv_table(&ff_mv_tables[1])) < 0)
return ret;
init_mv_table(&ff_mv_tables[0], mv_index_tables[0]);
init_mv_table(&ff_mv_tables[1], mv_index_tables[1]);
for(i=0;i<NB_RL_TABLES;i++)
ff_rl_init(&ff_rl_table[i], ff_static_rl_table_store[i]);
@@ -152,8 +147,6 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s)
}
}
}
return 0;
}
static void find_best_tables(MpegEncContext * s)
+1
View File
@@ -71,6 +71,7 @@ static int msp2_decode_frame(AVCodecContext *avctx,
while (bytestream2_get_bytes_left(&gb) && x < width) {
int size = bytestream2_get_byte(&gb);
if (size) {
size = FFMIN(size, bytestream2_get_bytes_left(&gb));
memcpy(p->data[0] + y * p->linesize[0] + x, gb.buffer, FFMIN(size, width - x));
bytestream2_skip(&gb, size);
} else {
+10 -7
View File
@@ -291,14 +291,15 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
return decode_pixel(acoder, pctx, ref_pix, nlen, 1);
}
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_dst,
int x, int y, int width, int height, ptrdiff_t stride,
ptrdiff_t rgb_stride, PixContext *pctx,
const uint32_t *pal)
{
int i, j, p;
uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride;
rgb_stride = rgb_dst ? rgb_stride : 0;
rgb_dst = rgb_dst ? rgb_dst + x * 3 + y * rgb_stride : NULL;
dst += x + y * stride;
for (j = 0; j < height; j++) {
@@ -312,11 +313,11 @@ static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
return p;
dst[i] = p;
if (rgb_pic)
if (rgb_dst)
AV_WB24(rgb_dst + i * 3, pal[p]);
}
dst += stride;
rgb_dst += rgb_stride;
rgb_dst = FF_PTR_ADD(rgb_dst, rgb_stride);
}
return 0;
@@ -476,17 +477,19 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder,
ptrdiff_t stride = c->pal_stride;
ptrdiff_t rgb_stride = c->rgb_stride;
uint8_t *dst = c->pal_pic + x + y * stride;
uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride;
uint8_t *rgb_dst = c->rgb_pic ? c->rgb_pic + x * 3 + y * rgb_stride : NULL;
pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0);
if (pix < 0)
return pix;
rgb_pix = c->pal[pix];
for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) {
for (i = 0; i < height; i++, dst += stride) {
memset(dst, pix, width);
if (c->rgb_pic)
if (rgb_dst) {
for (j = 0; j < width * 3; j += 3)
AV_WB24(rgb_dst + j, rgb_pix);
rgb_dst += rgb_stride;
}
}
} else {
return decode_region(acoder, c->pal_pic, c->rgb_pic,
+3
View File
@@ -179,6 +179,9 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,
/* offset of the next frame */
s->next_frame_offset = s->cur_offset + index;
s->fetch_timestamp = 1;
} else {
/* Don't return a pointer to dummy_buf. */
*poutbuf = NULL;
}
if (index < 0)
index = 0;
+173 -90
View File
@@ -57,6 +57,18 @@ typedef struct PNGDecContext {
ThreadFrame last_picture;
ThreadFrame picture;
AVDictionary *frame_metadata;
uint8_t iccp_name[82];
uint8_t *iccp_data;
size_t iccp_data_len;
int stereo_mode;
int have_chrm;
uint32_t white_point[2];
uint32_t display_primaries[3][2];
enum PNGHeaderState hdr_state;
enum PNGImageState pic_state;
int width, height;
@@ -77,8 +89,8 @@ typedef struct PNGDecContext {
int has_trns;
uint8_t transparent_color_be[6];
uint8_t *image_buf;
int image_linesize;
uint8_t *background_buf;
unsigned background_buf_allocated;
uint32_t palette[256];
uint8_t *crow_buf;
uint8_t *last_row;
@@ -330,27 +342,27 @@ static int percent_missing(PNGDecContext *s)
}
/* process exactly one decompressed row */
static void png_handle_row(PNGDecContext *s)
static void png_handle_row(PNGDecContext *s, uint8_t *dst, ptrdiff_t dst_stride)
{
uint8_t *ptr, *last_row;
int got_line;
if (!s->interlace_type) {
ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp;
ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp;
if (s->y == 0)
last_row = s->last_row;
else
last_row = ptr - s->image_linesize;
last_row = ptr - dst_stride;
ff_png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
last_row, s->row_size, s->bpp);
/* loco lags by 1 row so that it doesn't interfere with top prediction */
if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
if (s->bit_depth == 16) {
deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2,
deloco_rgb16((uint16_t *)(ptr - dst_stride), s->row_size / 2,
s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
} else {
deloco_rgb8(ptr - s->image_linesize, s->row_size,
deloco_rgb8(ptr - dst_stride, s->row_size,
s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
}
}
@@ -370,7 +382,7 @@ static void png_handle_row(PNGDecContext *s)
} else {
got_line = 0;
for (;;) {
ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp;
ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp;
if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
/* if we already read one row, it is time to stop to
* wait for the next one */
@@ -411,7 +423,8 @@ the_end:;
}
}
static int png_decode_idat(PNGDecContext *s, int length)
static int png_decode_idat(PNGDecContext *s, int length,
uint8_t *dst, ptrdiff_t dst_stride)
{
int ret;
s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
@@ -427,7 +440,7 @@ static int png_decode_idat(PNGDecContext *s, int length)
}
if (s->zstream.avail_out == 0) {
if (!(s->pic_state & PNG_ALLIMAGE)) {
png_handle_row(s);
png_handle_row(s, dst, dst_stride);
}
s->zstream.avail_out = s->crow_size;
s->zstream.next_out = s->crow_buf;
@@ -509,8 +522,7 @@ static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
return out;
}
static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
AVDictionary **dict)
static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed)
{
int ret, method;
const uint8_t *data = s->gb.buffer;
@@ -552,7 +564,7 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
return AVERROR(ENOMEM);
}
av_dict_set(dict, kw_utf8, txt_utf8,
av_dict_set(&s->frame_metadata, kw_utf8, txt_utf8,
AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
return 0;
}
@@ -732,8 +744,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
}
ff_dlog(avctx, "row_size=%d crow_size =%d\n",
s->row_size, s->crow_size);
s->image_buf = p->data[0];
s->image_linesize = p->linesize[0];
/* copy the palette if needed */
if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
@@ -764,7 +775,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
s->bpp -= byte_depth;
ret = png_decode_idat(s, length);
ret = png_decode_idat(s, length, p->data[0], p->linesize[0]);
if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
s->bpp += byte_depth;
@@ -851,21 +862,21 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f)
{
int ret, cnt = 0;
uint8_t *data, profile_name[82];
AVBPrint bp;
AVFrameSideData *sd;
while ((profile_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81);
while ((s->iccp_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81);
if (cnt > 80) {
av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid name!\n");
return AVERROR_INVALIDDATA;
ret = AVERROR_INVALIDDATA;
goto fail;
}
length = FFMAX(length - cnt, 0);
if (bytestream2_get_byte(&s->gb) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid compression!\n");
return AVERROR_INVALIDDATA;
ret = AVERROR_INVALIDDATA;
goto fail;
}
length = FFMAX(length - 1, 0);
@@ -873,24 +884,19 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f)
if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0)
return ret;
ret = av_bprint_finalize(&bp, (char **)&data);
av_freep(&s->iccp_data);
ret = av_bprint_finalize(&bp, (char **)&s->iccp_data);
if (ret < 0)
return ret;
sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len);
if (!sd) {
av_free(data);
return AVERROR(ENOMEM);
}
av_dict_set(&sd->metadata, "name", profile_name, 0);
memcpy(sd->data, data, bp.len);
av_free(data);
s->iccp_data_len = bp.len;
/* ICC compressed data and CRC */
bytestream2_skip(&s->gb, length + 4);
return 0;
fail:
s->iccp_name[0] = 0;
return ret;
}
static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
@@ -913,7 +919,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
pd[8*i + 1]= (pd[i]>>6) & 1;
pd[8*i + 0]= pd[i]>>7;
}
pd += s->image_linesize;
pd += p->linesize[0];
}
} else if (s->bits_per_pixel == 2) {
int i, j;
@@ -941,7 +947,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
pd[4*i + 0]= ( pd[i]>>6 )*0x55;
}
}
pd += s->image_linesize;
pd += p->linesize[0];
}
} else if (s->bits_per_pixel == 4) {
int i, j;
@@ -961,7 +967,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
pd[2*i + 0] = (pd[i] >> 4) * 0x11;
}
}
pd += s->image_linesize;
pd += p->linesize[0];
}
}
}
@@ -1056,8 +1062,8 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
for (j = 0; j < s->height; j++) {
for (i = 0; i < ls; i++)
pd[i] += pd_last[i];
pd += s->image_linesize;
pd_last += s->image_linesize;
pd += p->linesize[0];
pd_last += s->last_picture.f->linesize[0];
}
}
@@ -1068,8 +1074,12 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
AVFrame *p)
{
uint8_t *dst = p->data[0];
ptrdiff_t dst_stride = p->linesize[0];
const uint8_t *src = s->last_picture.f->data[0];
ptrdiff_t src_stride = s->last_picture.f->linesize[0];
size_t x, y;
uint8_t *buffer;
if (s->blend_op == APNG_BLEND_OP_OVER &&
avctx->pix_fmt != AV_PIX_FMT_RGBA &&
@@ -1083,32 +1093,39 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
// need to reset a rectangle to background:
// create a new writable copy
if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) {
int ret = av_frame_make_writable(s->last_picture.f);
if (ret < 0)
return ret;
av_fast_malloc(&s->background_buf, &s->background_buf_allocated,
src_stride * p->height);
if (!s->background_buf)
return AVERROR(ENOMEM);
memcpy(s->background_buf, src, src_stride * p->height);
for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; y++) {
memset(s->last_picture.f->data[0] + s->image_linesize * y +
memset(s->background_buf + src_stride * y +
s->bpp * s->last_x_offset, 0, s->bpp * s->last_w);
}
src = s->background_buf;
}
buffer = av_memdup(s->last_picture.f->data[0], s->image_linesize * s->height);
if (!buffer)
return AVERROR(ENOMEM);
// copy unchanged rectangles from the last frame
for (y = 0; y < s->y_offset; y++)
memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp);
for (y = s->y_offset; y < s->y_offset + s->cur_h; y++) {
memcpy(dst + y * dst_stride, src + y * src_stride, s->x_offset * s->bpp);
memcpy(dst + y * dst_stride + (s->x_offset + s->cur_w) * s->bpp,
src + y * src_stride + (s->x_offset + s->cur_w) * s->bpp,
(p->width - s->cur_w - s->x_offset) * s->bpp);
}
for (y = s->y_offset + s->cur_h; y < p->height; y++)
memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp);
// Perform blending
if (s->blend_op == APNG_BLEND_OP_SOURCE) {
if (s->blend_op == APNG_BLEND_OP_OVER) {
// Perform blending
for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) {
size_t row_start = s->image_linesize * y + s->bpp * s->x_offset;
memcpy(buffer + row_start, p->data[0] + row_start, s->bpp * s->cur_w);
}
} else { // APNG_BLEND_OP_OVER
for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) {
uint8_t *foreground = p->data[0] + s->image_linesize * y + s->bpp * s->x_offset;
uint8_t *background = buffer + s->image_linesize * y + s->bpp * s->x_offset;
uint8_t *foreground = dst + dst_stride * y + s->bpp * s->x_offset;
const uint8_t *background = src + src_stride * y + s->bpp * s->x_offset;
for (x = s->x_offset; x < s->x_offset + s->cur_w; ++x, foreground += s->bpp, background += s->bpp) {
size_t b;
uint8_t foreground_alpha, background_alpha, output_alpha;
@@ -1135,18 +1152,17 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
break;
}
if (foreground_alpha == 0)
if (foreground_alpha == 255)
continue;
if (foreground_alpha == 255) {
memcpy(background, foreground, s->bpp);
if (foreground_alpha == 0) {
memcpy(foreground, background, s->bpp);
continue;
}
if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
// TODO: Alpha blending with PAL8 will likely need the entire image converted over to RGBA first
avpriv_request_sample(avctx, "Alpha blending palette samples");
background[0] = foreground[0];
continue;
}
@@ -1164,15 +1180,11 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
}
}
output[b] = output_alpha;
memcpy(background, output, s->bpp);
memcpy(foreground, output, s->bpp);
}
}
}
// Copy blended buffer into the frame and free
memcpy(p->data[0], buffer, s->image_linesize * s->height);
av_free(buffer);
return 0;
}
@@ -1180,7 +1192,6 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
AVFrame *p, const AVPacket *avpkt)
{
const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE);
AVDictionary **metadatap = NULL;
uint32_t tag, length;
int decode_next_dat = 0;
int i, ret;
@@ -1209,7 +1220,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
}
length = bytestream2_get_be32(&s->gb);
if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
if (length > 0x7fffffff || length + 8 > bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
ret = AVERROR_INVALIDDATA;
goto fail;
@@ -1248,7 +1259,6 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
}
}
metadatap = &p->metadata;
switch (tag) {
case MKTAG('I', 'H', 'D', 'R'):
if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0)
@@ -1290,26 +1300,20 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
goto skip_tag;
break;
case MKTAG('t', 'E', 'X', 't'):
if (decode_text_chunk(s, length, 0, metadatap) < 0)
if (decode_text_chunk(s, length, 0) < 0)
av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n");
bytestream2_skip(&s->gb, length + 4);
break;
case MKTAG('z', 'T', 'X', 't'):
if (decode_text_chunk(s, length, 1, metadatap) < 0)
if (decode_text_chunk(s, length, 1) < 0)
av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
bytestream2_skip(&s->gb, length + 4);
break;
case MKTAG('s', 'T', 'E', 'R'): {
int mode = bytestream2_get_byte(&s->gb);
AVStereo3D *stereo3d = av_stereo3d_create_side_data(p);
if (!stereo3d) {
ret = AVERROR(ENOMEM);
goto fail;
}
if (mode == 0 || mode == 1) {
stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
stereo3d->flags = mode ? 0 : AV_STEREO3D_FLAG_INVERT;
s->stereo_mode = mode;
} else {
av_log(avctx, AV_LOG_WARNING,
"Unknown value in sTER chunk (%d)\n", mode);
@@ -1323,22 +1327,17 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
break;
}
case MKTAG('c', 'H', 'R', 'M'): {
AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(p);
if (!mdm) {
ret = AVERROR(ENOMEM);
goto fail;
}
s->have_chrm = 1;
mdm->white_point[0] = av_make_q(bytestream2_get_be32(&s->gb), 100000);
mdm->white_point[1] = av_make_q(bytestream2_get_be32(&s->gb), 100000);
s->white_point[0] = bytestream2_get_be32(&s->gb);
s->white_point[1] = bytestream2_get_be32(&s->gb);
/* RGB Primaries */
for (i = 0; i < 3; i++) {
mdm->display_primaries[i][0] = av_make_q(bytestream2_get_be32(&s->gb), 100000);
mdm->display_primaries[i][1] = av_make_q(bytestream2_get_be32(&s->gb), 100000);
s->display_primaries[i][0] = bytestream2_get_be32(&s->gb);
s->display_primaries[i][1] = bytestream2_get_be32(&s->gb);
}
mdm->has_primaries = 1;
bytestream2_skip(&s->gb, 4); /* crc */
break;
}
@@ -1353,7 +1352,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
if (ret < 0)
return ret;
av_dict_set(&p->metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL);
av_dict_set(&s->frame_metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL);
bytestream2_skip(&s->gb, 4); /* crc */
break;
@@ -1396,7 +1395,7 @@ exit_loop:
av_assert0(s->bit_depth > 1);
for (y = 0; y < s->height; ++y) {
uint8_t *row = &s->image_buf[s->image_linesize * y];
uint8_t *row = &p->data[0][p->linesize[0] * y];
if (s->bpp == 2 && byte_depth == 1) {
uint8_t *pixel = &row[2 * s->width - 1];
@@ -1456,6 +1455,77 @@ fail:
return ret;
}
static void clear_frame_metadata(PNGDecContext *s)
{
av_freep(&s->iccp_data);
s->iccp_data_len = 0;
s->iccp_name[0] = 0;
s->stereo_mode = -1;
s->have_chrm = 0;
av_dict_free(&s->frame_metadata);
}
static int output_frame(PNGDecContext *s, AVFrame *f,
const AVFrame *src)
{
int ret;
ret = av_frame_ref(f, src);
if (ret < 0)
return ret;
if (s->iccp_data) {
AVFrameSideData *sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, s->iccp_data_len);
if (!sd) {
ret = AVERROR(ENOMEM);
goto fail;
}
memcpy(sd->data, s->iccp_data, s->iccp_data_len);
av_dict_set(&sd->metadata, "name", s->iccp_name, 0);
}
if (s->stereo_mode >= 0) {
AVStereo3D *stereo3d = av_stereo3d_create_side_data(f);
if (!stereo3d) {
ret = AVERROR(ENOMEM);
goto fail;
}
stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
stereo3d->flags = s->stereo_mode ? 0 : AV_STEREO3D_FLAG_INVERT;
}
if (s->have_chrm) {
AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(f);
if (!mdm) {
ret = AVERROR(ENOMEM);
goto fail;
}
mdm->white_point[0] = av_make_q(s->white_point[0], 100000);
mdm->white_point[1] = av_make_q(s->white_point[1], 100000);
/* RGB Primaries */
for (int i = 0; i < 3; i++) {
mdm->display_primaries[i][0] = av_make_q(s->display_primaries[i][0], 100000);
mdm->display_primaries[i][1] = av_make_q(s->display_primaries[i][1], 100000);
}
mdm->has_primaries = 1;
}
FFSWAP(AVDictionary*, f->metadata, s->frame_metadata);
return 0;
fail:
av_frame_unref(f);
return ret;
}
#if CONFIG_PNG_DECODER
static int decode_frame_png(AVCodecContext *avctx,
void *data, int *got_frame,
@@ -1464,10 +1534,13 @@ static int decode_frame_png(AVCodecContext *avctx,
PNGDecContext *const s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AVFrame *dst_frame = data;
AVFrame *p = s->picture.f;
int64_t sig;
int ret;
clear_frame_metadata(s);
bytestream2_init(&s->gb, buf, buf_size);
/* check signature */
@@ -1501,7 +1574,8 @@ static int decode_frame_png(AVCodecContext *avctx,
goto the_end;
}
if ((ret = av_frame_ref(data, s->picture.f)) < 0)
ret = output_frame(s, dst_frame, s->picture.f);
if (ret < 0)
goto the_end;
if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
@@ -1525,9 +1599,12 @@ static int decode_frame_apng(AVCodecContext *avctx,
AVPacket *avpkt)
{
PNGDecContext *const s = avctx->priv_data;
AVFrame *dst_frame = data;
int ret;
AVFrame *p = s->picture.f;
clear_frame_metadata(s);
if (!(s->hdr_state & PNG_IHDR)) {
if (!avctx->extradata_size)
return AVERROR_INVALIDDATA;
@@ -1559,7 +1636,9 @@ static int decode_frame_apng(AVCodecContext *avctx,
ret = AVERROR_INVALIDDATA;
goto end;
}
if ((ret = av_frame_ref(data, s->picture.f)) < 0)
ret = output_frame(s, dst_frame, s->picture.f);
if (ret < 0)
goto end;
if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
@@ -1662,6 +1741,10 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
s->last_row_size = 0;
av_freep(&s->tmp_row);
s->tmp_row_size = 0;
av_freep(&s->background_buf);
av_freep(&s->iccp_data);
av_dict_free(&s->frame_metadata);
return 0;
}
+1 -1
View File
@@ -111,7 +111,7 @@ retry:
} else {
int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
next = pnmctx.bytestream - pnmctx.bytestream_start + skip;
if (ret >= 0)
if (ret >= 0 && next + (uint64_t)ret <= INT_MAX)
next += ret;
}
if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
+8 -6
View File
@@ -623,8 +623,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
AVFrame *pic = ctx->frame;
int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
int luma_stride, chroma_stride;
int y_data_size, u_data_size, v_data_size, a_data_size;
uint8_t *dest_y, *dest_u, *dest_v, *dest_a;
int y_data_size, u_data_size, v_data_size, a_data_size, offset;
uint8_t *dest_y, *dest_u, *dest_v;
LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]);
LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]);
int mb_x_shift;
@@ -676,16 +676,16 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
log2_chroma_blocks_per_mb = 1;
}
dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
dest_y = pic->data[0] + offset;
dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
dest_y += pic->linesize[0];
dest_u += pic->linesize[1];
dest_v += pic->linesize[2];
dest_a += pic->linesize[3];
offset += pic->linesize[3];
}
ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
@@ -722,10 +722,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
}
/* decode alpha plane if available */
if (ctx->alpha_info && pic->data[3] && a_data_size)
if (ctx->alpha_info && pic->data[3] && a_data_size) {
uint8_t *dest_a = pic->data[3] + offset;
decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride,
buf + y_data_size + u_data_size + v_data_size,
a_data_size, slice->mb_count);
}
slice->ret = 0;
return 0;
+2
View File
@@ -957,6 +957,7 @@ AVCodec ff_prores_aw_encoder = {
.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.priv_class = &proresaw_enc_class,
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
AVCodec ff_prores_encoder = {
@@ -972,4 +973,5 @@ AVCodec ff_prores_encoder = {
.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.priv_class = &prores_enc_class,
.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
+183 -129
View File
@@ -64,6 +64,12 @@ enum {
STATE_SETUP_FINISHED,
};
enum {
UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called
NEEDS_CLOSE, ///< AVCodec->close needs to be called
INITIALIZED, ///< Thread has been properly set up
};
/**
* Context used by codec threads and stored in their AVCodecInternal thread_ctx.
*/
@@ -72,6 +78,7 @@ typedef struct PerThreadContext {
pthread_t thread;
int thread_init;
unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions
pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
@@ -120,6 +127,7 @@ typedef struct FrameThreadContext {
PerThreadContext *threads; ///< The contexts for each thread.
PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
/**
* This lock is used for ensuring threads run in serial when hwaccel
@@ -674,6 +682,59 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count
async_lock(fctx);
}
#define SENTINEL 0 // This forbids putting a mutex/condition variable at the front.
#define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL
#define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \
static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\
OFFSET_ARRAY mutexes, \
OFFSET_ARRAY conds }
#define OFF(member) offsetof(FrameThreadContext, member)
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx,
(OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
(OFF(async_cond)));
#undef OFF
#define OFF(member) offsetof(PerThreadContext, member)
DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread,
(OFF(progress_mutex), OFF(mutex)),
(OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
#undef OFF
static av_cold void free_pthread(void *obj, const unsigned offsets[])
{
unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
const unsigned *cur_offset = offsets;
for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
}
static av_cold int init_pthread(void *obj, const unsigned offsets[])
{
const unsigned *cur_offset = offsets;
unsigned cnt = 0;
int err;
#define PTHREAD_INIT_LOOP(type) \
for (; *(++cur_offset) != SENTINEL; cnt++) { \
pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
err = pthread_ ## type ## _init(dst, NULL); \
if (err) { \
err = AVERROR(err); \
goto fail; \
} \
}
PTHREAD_INIT_LOOP(mutex)
PTHREAD_INIT_LOOP(cond)
fail:
*(unsigned*)((char*)obj + offsets[0]) = cnt;
return err;
}
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
{
FrameThreadContext *fctx = avctx->internal->thread_ctx;
@@ -698,63 +759,49 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
for (i = 0; i < thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
AVCodecContext *ctx = p->avctx;
pthread_mutex_lock(&p->mutex);
p->die = 1;
pthread_cond_signal(&p->input_cond);
pthread_mutex_unlock(&p->mutex);
if (ctx->internal) {
if (p->thread_init == INITIALIZED) {
pthread_mutex_lock(&p->mutex);
p->die = 1;
pthread_cond_signal(&p->input_cond);
pthread_mutex_unlock(&p->mutex);
if (p->thread_init)
pthread_join(p->thread, NULL);
p->thread_init=0;
if (codec->close && p->avctx)
codec->close(p->avctx);
pthread_join(p->thread, NULL);
}
if (codec->close && p->thread_init != UNINITIALIZED)
codec->close(ctx);
#if FF_API_THREAD_SAFE_CALLBACKS
release_delayed_buffers(p);
release_delayed_buffers(p);
for (int j = 0; j < p->released_buffers_allocated; j++)
av_frame_free(&p->released_buffers[j]);
av_freep(&p->released_buffers);
#endif
if (ctx->priv_data) {
if (codec->priv_class)
av_opt_free(ctx->priv_data);
av_freep(&ctx->priv_data);
}
av_freep(&ctx->slice_offset);
av_buffer_unref(&ctx->internal->pool);
av_freep(&ctx->internal);
av_buffer_unref(&ctx->hw_frames_ctx);
}
av_frame_free(&p->frame);
}
for (i = 0; i < thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
pthread_mutex_destroy(&p->mutex);
pthread_mutex_destroy(&p->progress_mutex);
pthread_cond_destroy(&p->input_cond);
pthread_cond_destroy(&p->progress_cond);
pthread_cond_destroy(&p->output_cond);
free_pthread(p, per_thread_offsets);
av_packet_free(&p->avpkt);
#if FF_API_THREAD_SAFE_CALLBACKS
for (int j = 0; j < p->released_buffers_allocated; j++)
av_frame_free(&p->released_buffers[j]);
av_freep(&p->released_buffers);
#endif
if (p->avctx) {
if (codec->priv_class)
av_opt_free(p->avctx->priv_data);
av_freep(&p->avctx->priv_data);
av_freep(&p->avctx->slice_offset);
}
if (p->avctx) {
av_buffer_unref(&p->avctx->internal->pool);
av_freep(&p->avctx->internal);
av_buffer_unref(&p->avctx->hw_frames_ctx);
}
av_freep(&p->avctx);
}
av_freep(&fctx->threads);
pthread_mutex_destroy(&fctx->buffer_mutex);
pthread_mutex_destroy(&fctx->hwaccel_mutex);
pthread_mutex_destroy(&fctx->async_mutex);
pthread_cond_destroy(&fctx->async_cond);
free_pthread(fctx, thread_ctx_offsets);
av_freep(&avctx->internal->thread_ctx);
@@ -763,13 +810,89 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
avctx->codec = NULL;
}
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
FrameThreadContext *fctx, AVCodecContext *avctx,
AVCodecContext *src, const AVCodec *codec, int first)
{
AVCodecContext *copy;
int err;
atomic_init(&p->state, STATE_INPUT_READY);
copy = av_memdup(src, sizeof(*src));
if (!copy)
return AVERROR(ENOMEM);
copy->priv_data = NULL;
/* From now on, this PerThreadContext will be cleaned up by
* ff_frame_thread_free in case of errors. */
(*threads_to_free)++;
p->parent = fctx;
p->avctx = copy;
copy->internal = av_memdup(src->internal, sizeof(*src->internal));
if (!copy->internal)
return AVERROR(ENOMEM);
copy->internal->thread_ctx = p;
copy->delay = avctx->delay;
if (codec->priv_data_size) {
copy->priv_data = av_mallocz(codec->priv_data_size);
if (!copy->priv_data)
return AVERROR(ENOMEM);
if (codec->priv_class) {
*(const AVClass **)copy->priv_data = codec->priv_class;
err = av_opt_copy(copy->priv_data, src->priv_data);
if (err < 0)
return err;
}
}
err = init_pthread(p, per_thread_offsets);
if (err < 0)
return err;
if (!(p->frame = av_frame_alloc()) ||
!(p->avpkt = av_packet_alloc()))
return AVERROR(ENOMEM);
copy->internal->last_pkt_props = p->avpkt;
if (!first)
copy->internal->is_copy = 1;
if (codec->init) {
err = codec->init(copy);
if (err < 0) {
if (codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP)
p->thread_init = NEEDS_CLOSE;
return err;
}
}
p->thread_init = NEEDS_CLOSE;
if (first)
update_context_from_thread(avctx, copy, 1);
atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
if (err < 0)
return err;
p->thread_init = INITIALIZED;
return 0;
}
int ff_frame_thread_init(AVCodecContext *avctx)
{
int thread_count = avctx->thread_count;
const AVCodec *codec = avctx->codec;
AVCodecContext *src = avctx;
FrameThreadContext *fctx;
int i, err = 0;
int err, i = 0;
if (!thread_count) {
int nb_cpus = av_cpu_count();
@@ -789,107 +912,38 @@ int ff_frame_thread_init(AVCodecContext *avctx)
if (!fctx)
return AVERROR(ENOMEM);
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
if (!fctx->threads) {
err = init_pthread(fctx, thread_ctx_offsets);
if (err < 0) {
free_pthread(fctx, thread_ctx_offsets);
av_freep(&avctx->internal->thread_ctx);
return AVERROR(ENOMEM);
return err;
}
pthread_mutex_init(&fctx->buffer_mutex, NULL);
pthread_mutex_init(&fctx->hwaccel_mutex, NULL);
pthread_mutex_init(&fctx->async_mutex, NULL);
pthread_cond_init(&fctx->async_cond, NULL);
fctx->async_lock = 1;
fctx->delaying = 1;
if (codec->type == AVMEDIA_TYPE_VIDEO)
avctx->delay = src->thread_count - 1;
for (i = 0; i < thread_count; i++) {
AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
if (!fctx->threads) {
err = AVERROR(ENOMEM);
goto error;
}
for (; i < thread_count; ) {
PerThreadContext *p = &fctx->threads[i];
int first = !i;
pthread_mutex_init(&p->mutex, NULL);
pthread_mutex_init(&p->progress_mutex, NULL);
pthread_cond_init(&p->input_cond, NULL);
pthread_cond_init(&p->progress_cond, NULL);
pthread_cond_init(&p->output_cond, NULL);
p->frame = av_frame_alloc();
if (!p->frame) {
av_freep(&copy);
err = AVERROR(ENOMEM);
goto error;
}
p->avpkt = av_packet_alloc();
if (!p->avpkt) {
av_freep(&copy);
err = AVERROR(ENOMEM);
goto error;
}
p->parent = fctx;
p->avctx = copy;
if (!copy) {
err = AVERROR(ENOMEM);
goto error;
}
*copy = *src;
copy->internal = av_malloc(sizeof(AVCodecInternal));
if (!copy->internal) {
copy->priv_data = NULL;
err = AVERROR(ENOMEM);
goto error;
}
*copy->internal = *src->internal;
copy->internal->thread_ctx = p;
copy->internal->last_pkt_props = p->avpkt;
copy->delay = avctx->delay;
if (codec->priv_data_size) {
copy->priv_data = av_mallocz(codec->priv_data_size);
if (!copy->priv_data) {
err = AVERROR(ENOMEM);
goto error;
}
if (codec->priv_class) {
*(const AVClass **)copy->priv_data = codec->priv_class;
err = av_opt_copy(copy->priv_data, src->priv_data);
if (err < 0)
goto error;
}
}
if (i)
copy->internal->is_copy = 1;
if (codec->init)
err = codec->init(copy);
if (err) goto error;
if (!i)
update_context_from_thread(avctx, copy, 1);
atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
p->thread_init= !err;
if(!p->thread_init)
err = init_thread(p, &i, fctx, avctx, src, codec, first);
if (err < 0)
goto error;
}
return 0;
error:
ff_frame_thread_free(avctx, i+1);
ff_frame_thread_free(avctx, i);
return err;
}
-7
View File
@@ -35,16 +35,9 @@
#include "version.h"
#if ARCH_X86_64
// TODO: Benchmark and optionally enable on other 64-bit architectures.
typedef uint64_t BitBuf;
#define AV_WBBUF AV_WB64
#define AV_WLBUF AV_WL64
#else
typedef uint32_t BitBuf;
#define AV_WBBUF AV_WB32
#define AV_WLBUF AV_WL32
#endif
static const int BUF_BITS = 8 * sizeof(BitBuf);
+13 -9
View File
@@ -155,10 +155,14 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
int sec_lowest_bulk_cost;
int sec_lowest_bulk_cost_index;
uint8_t *this_line = p-> data[0] + line*p-> linesize[0] +
(width - 1)*s->pixel_size;
uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] +
(width - 1)*s->pixel_size;
const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size;
/* There might be no earlier frame if the current frame is a keyframe.
* So just use a pointer to the current frame to avoid a check
* to avoid NULL - s->pixel_size (which is undefined behaviour). */
const uint8_t *prev_line = s->key_frame ? this_line
: s->previous_frame->data[0]
+ line * s->previous_frame->linesize[0]
+ width * s->pixel_size;
s->length_table[width] = 0;
skipcount = 0;
@@ -175,6 +179,9 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
int prev_bulk_cost;
this_line -= s->pixel_size;
prev_line -= s->pixel_size;
/* If our lowest bulk cost index is too far away, replace it
* with the next lowest bulk cost */
if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
@@ -259,10 +266,6 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
/* These bulk costs increase every iteration */
lowest_bulk_cost += s->pixel_size;
sec_lowest_bulk_cost += s->pixel_size;
if (this_line >= p->data[0] + s->pixel_size)
this_line -= s->pixel_size;
if (prev_line >= s->previous_frame->data[0] + s->pixel_size)
prev_line -= s->pixel_size;
}
/* Good! Now we have the best sequence for this line, let's output it. */
@@ -369,7 +372,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0)
return ret;
if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
if (avctx->gop_size == 0 || !s->previous_frame->data[0] ||
(s->avctx->frame_number % avctx->gop_size) == 0) {
/* I-Frame */
s->key_frame = 1;
} else {
+1
View File
@@ -493,6 +493,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx)
RawVideoContext *context = avctx->priv_data;
av_buffer_unref(&context->palette);
av_freep(&context->bitstream_buf);
return 0;
}
+1 -3
View File
@@ -226,7 +226,7 @@ static int rv20_decode_picture_header(RVDecContext *rv)
new_w = rv->orig_width;
new_h = rv->orig_height;
}
if (new_w != s->width || new_h != s->height) {
if (new_w != s->width || new_h != s->height || !s->context_initialized) {
AVRational old_aspect = s->avctx->sample_aspect_ratio;
av_log(s->avctx, AV_LOG_DEBUG,
"attempting to change resolution to %dx%d\n", new_w, new_h);
@@ -687,7 +687,6 @@ AVCodec ff_rv10_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
@@ -705,7 +704,6 @@ AVCodec ff_rv20_decoder = {
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
+9 -4
View File
@@ -1383,6 +1383,7 @@ static int rv34_decoder_alloc(RV34DecContext *r)
if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs &&
r->intra_types_hist && r->mb_type)) {
r->s.context_reinit = 1;
rv34_decoder_free(r);
return AVERROR(ENOMEM);
}
@@ -1530,7 +1531,7 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte
if (dst == src || !s1->context_initialized)
return 0;
if (s->height != s1->height || s->width != s1->width) {
if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
s->height = s1->height;
s->width = s1->width;
if ((err = ff_mpv_common_frame_size_change(s)) < 0)
@@ -1667,11 +1668,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
if (s->mb_num_left > 0 && s->current_picture_ptr) {
av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
s->mb_num_left);
ff_er_frame_end(&s->er);
if (!s->context_reinit)
ff_er_frame_end(&s->er);
ff_mpv_frame_end(s);
}
if (s->width != si.width || s->height != si.height) {
if (s->width != si.width || s->height != si.height || s->context_reinit) {
int err;
av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
@@ -1689,7 +1691,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
err = ff_set_dimensions(s->avctx, s->width, s->height);
if (err < 0)
return err;
if ((err = ff_mpv_common_frame_size_change(s)) < 0)
return err;
if ((err = rv34_decoder_realloc(r)) < 0)
@@ -1744,6 +1745,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
}
s->mb_x = s->mb_y = 0;
ff_thread_finish_setup(s->avctx);
} else if (s->context_reinit) {
av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to "
"reinitialize (start MB is %d).\n", si.start);
return AVERROR_INVALIDDATA;
} else if (HAVE_THREADS &&
(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame "
+1 -1
View File
@@ -152,7 +152,7 @@ static int setts_filter(AVBSFContext *ctx, AVPacket *pkt)
s->var_values[VAR_PREV_OUTDTS] = s->prev_outdts;
s->var_values[VAR_STARTPTS] = s->start_pts;
s->var_values[VAR_STARTDTS] = s->start_dts;
s->var_values[VAR_TB] = av_q2d(ctx->time_base_out);
s->var_values[VAR_TB] = ctx->time_base_out.den ? av_q2d(ctx->time_base_out) : 0;
s->var_values[VAR_SR] = ctx->par_in->sample_rate;
new_ts = llrint(av_expr_eval(s->ts_expr, s->var_values, NULL));
+1 -1
View File
@@ -232,7 +232,7 @@ static int lzss_decompress(AVCodecContext *avctx,
if (offset <= 0)
offset = 1;
if (oi < offset)
if (oi < offset || oi + count * 2 > dst_size)
return AVERROR_INVALIDDATA;
for (int j = 0; j < count * 2; j++) {
dst[oi] = dst[oi - offset];
+2 -2
View File
@@ -475,13 +475,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error)
for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--)
{
int k_value = *k_ptr, state_value = *state_ptr;
x -= shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT);
x -= (unsigned)shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT);
state_ptr[1] = state_value + shift_down(k_value * (unsigned)x, LATTICE_SHIFT);
}
#else
for (i = order-2; i >= 0; i--)
{
x -= shift_down(k[i] * state[i], LATTICE_SHIFT);
x -= (unsigned)shift_down(k[i] * state[i], LATTICE_SHIFT);
state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT);
}
#endif
+195 -199
View File
@@ -275,9 +275,101 @@ static int add_metadata(int count, int type,
};
}
/**
* Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5)
*/
static uint16_t av_always_inline dng_process_color16(uint16_t value,
const uint16_t *lut,
uint16_t black_level,
float scale_factor)
{
float value_norm;
// Lookup table lookup
if (lut)
value = lut[value];
// Black level subtraction
value = av_clip_uint16_c((unsigned)value - black_level);
// Color scaling
value_norm = (float)value * scale_factor;
value = av_clip_uint16_c(value_norm * 65535);
return value;
}
static uint16_t av_always_inline dng_process_color8(uint16_t value,
const uint16_t *lut,
uint16_t black_level,
float scale_factor)
{
return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
}
static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
const uint8_t *src, int src_stride, int width, int height,
int is_single_comp, int is_u16);
int is_single_comp, int is_u16)
{
int line, col;
float scale_factor;
scale_factor = 1.0f / (s->white_level - s->black_level);
if (is_single_comp) {
if (!is_u16)
return; /* <= 8bpp unsupported */
/* Image is double the width and half the height we need, each row comprises 2 rows of the output
(split vertically in the middle). */
for (line = 0; line < height / 2; line++) {
uint16_t *dst_u16 = (uint16_t *)dst;
uint16_t *src_u16 = (uint16_t *)src;
/* Blit first half of input row row to initial row of output */
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
/* Advance the destination pointer by a row (source pointer remains in the same place) */
dst += dst_stride * sizeof(uint16_t);
dst_u16 = (uint16_t *)dst;
/* Blit second half of input row row to next row of output */
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride * sizeof(uint16_t);
src += src_stride * sizeof(uint16_t);
}
} else {
/* Input and output image are the same size and the MJpeg decoder has done per-component
deinterleaving, so blitting here is straightforward. */
if (is_u16) {
for (line = 0; line < height; line++) {
uint16_t *dst_u16 = (uint16_t *)dst;
uint16_t *src_u16 = (uint16_t *)src;
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride * sizeof(uint16_t);
src += src_stride * sizeof(uint16_t);
}
} else {
for (line = 0; line < height; line++) {
uint8_t *dst_u8 = dst;
const uint8_t *src_u8 = src;
for (col = 0; col < width; col++)
*dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride;
src += src_stride;
}
}
}
}
static void av_always_inline horizontal_fill(TiffContext *s,
unsigned int bpp, uint8_t* dst,
@@ -553,7 +645,108 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
return ret;
}
static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
int tile_byte_count, int dst_x, int dst_y, int w, int h)
{
TiffContext *s = avctx->priv_data;
uint8_t *dst_data, *src_data;
uint32_t dst_offset; /* offset from dst buffer in pixels */
int is_single_comp, is_u16, pixel_size;
int ret;
if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb))
return AVERROR_INVALIDDATA;
/* Prepare a packet and send to the MJPEG decoder */
av_packet_unref(s->jpkt);
s->jpkt->data = (uint8_t*)s->gb.buffer;
s->jpkt->size = tile_byte_count;
if (s->is_bayer) {
MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
/* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded
image or not from its own data (and we need that information when decoding it). */
mjpegdecctx->bayer = 1;
}
ret = avcodec_send_packet(s->avctx_mjpeg, s->jpkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
return ret;
}
ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret));
/* Normally skip, error if explode */
if (avctx->err_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
else
return 0;
}
is_u16 = (s->bpp > 8);
/* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */
if (s->jpgframe->width != s->avctx_mjpeg->width ||
s->jpgframe->height != s->avctx_mjpeg->height ||
s->jpgframe->format != s->avctx_mjpeg->pix_fmt)
return AVERROR_INVALIDDATA;
/* See dng_blit for explanation */
if (s->avctx_mjpeg->width == w * 2 &&
s->avctx_mjpeg->height == h / 2 &&
s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) {
is_single_comp = 1;
} else if (s->avctx_mjpeg->width >= w &&
s->avctx_mjpeg->height >= h &&
s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8)
) {
is_single_comp = 0;
} else
return AVERROR_INVALIDDATA;
pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t));
if (is_single_comp && !is_u16) {
av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n");
av_frame_unref(s->jpgframe);
return AVERROR_PATCHWELCOME;
}
dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
dst_data = frame->data[0] + dst_offset * pixel_size;
src_data = s->jpgframe->data[0];
dng_blit(s,
dst_data,
frame->linesize[0] / pixel_size,
src_data,
s->jpgframe->linesize[0] / pixel_size,
w,
h,
is_single_comp,
is_u16);
av_frame_unref(s->jpgframe);
return 0;
}
static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
{
TiffContext *s = avctx->priv_data;
s->jpgframe->width = s->width;
s->jpgframe->height = s->height;
s->avctx_mjpeg->width = s->width;
s->avctx_mjpeg->height = s->height;
return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height);
}
static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
const uint8_t *src, int size, int strip_start, int lines)
@@ -780,190 +973,6 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
return 0;
}
/**
* Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5)
*/
static uint16_t av_always_inline dng_process_color16(uint16_t value,
const uint16_t *lut,
uint16_t black_level,
float scale_factor) {
float value_norm;
// Lookup table lookup
if (lut)
value = lut[value];
// Black level subtraction
value = av_clip_uint16_c((unsigned)value - black_level);
// Color scaling
value_norm = (float)value * scale_factor;
value = av_clip_uint16_c(value_norm * 65535);
return value;
}
static uint16_t av_always_inline dng_process_color8(uint16_t value,
const uint16_t *lut,
uint16_t black_level,
float scale_factor) {
return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
}
static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
const uint8_t *src, int src_stride,
int width, int height, int is_single_comp, int is_u16)
{
int line, col;
float scale_factor;
scale_factor = 1.0f / (s->white_level - s->black_level);
if (is_single_comp) {
if (!is_u16)
return; /* <= 8bpp unsupported */
/* Image is double the width and half the height we need, each row comprises 2 rows of the output
(split vertically in the middle). */
for (line = 0; line < height / 2; line++) {
uint16_t *dst_u16 = (uint16_t *)dst;
uint16_t *src_u16 = (uint16_t *)src;
/* Blit first half of input row row to initial row of output */
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
/* Advance the destination pointer by a row (source pointer remains in the same place) */
dst += dst_stride * sizeof(uint16_t);
dst_u16 = (uint16_t *)dst;
/* Blit second half of input row row to next row of output */
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride * sizeof(uint16_t);
src += src_stride * sizeof(uint16_t);
}
} else {
/* Input and output image are the same size and the MJpeg decoder has done per-component
deinterleaving, so blitting here is straightforward. */
if (is_u16) {
for (line = 0; line < height; line++) {
uint16_t *dst_u16 = (uint16_t *)dst;
uint16_t *src_u16 = (uint16_t *)src;
for (col = 0; col < width; col++)
*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride * sizeof(uint16_t);
src += src_stride * sizeof(uint16_t);
}
} else {
for (line = 0; line < height; line++) {
uint8_t *dst_u8 = dst;
const uint8_t *src_u8 = src;
for (col = 0; col < width; col++)
*dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor);
dst += dst_stride;
src += src_stride;
}
}
}
}
static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
int tile_byte_count, int dst_x, int dst_y, int w, int h)
{
TiffContext *s = avctx->priv_data;
uint8_t *dst_data, *src_data;
uint32_t dst_offset; /* offset from dst buffer in pixels */
int is_single_comp, is_u16, pixel_size;
int ret;
if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb))
return AVERROR_INVALIDDATA;
/* Prepare a packet and send to the MJPEG decoder */
av_packet_unref(s->jpkt);
s->jpkt->data = (uint8_t*)s->gb.buffer;
s->jpkt->size = tile_byte_count;
if (s->is_bayer) {
MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
/* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded
image or not from its own data (and we need that information when decoding it). */
mjpegdecctx->bayer = 1;
}
ret = avcodec_send_packet(s->avctx_mjpeg, s->jpkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
return ret;
}
ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret));
/* Normally skip, error if explode */
if (avctx->err_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
else
return 0;
}
is_u16 = (s->bpp > 8);
/* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */
if (s->jpgframe->width != s->avctx_mjpeg->width ||
s->jpgframe->height != s->avctx_mjpeg->height ||
s->jpgframe->format != s->avctx_mjpeg->pix_fmt)
return AVERROR_INVALIDDATA;
/* See dng_blit for explanation */
if (s->avctx_mjpeg->width == w * 2 &&
s->avctx_mjpeg->height == h / 2 &&
s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) {
is_single_comp = 1;
} else if (s->avctx_mjpeg->width >= w &&
s->avctx_mjpeg->height >= h &&
s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8)
) {
is_single_comp = 0;
} else
return AVERROR_INVALIDDATA;
pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t));
if (is_single_comp && !is_u16) {
av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n");
av_frame_unref(s->jpgframe);
return AVERROR_PATCHWELCOME;
}
dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
dst_data = frame->data[0] + dst_offset * pixel_size;
src_data = s->jpgframe->data[0];
dng_blit(s,
dst_data,
frame->linesize[0] / pixel_size,
src_data,
s->jpgframe->linesize[0] / pixel_size,
w,
h,
is_single_comp,
is_u16);
av_frame_unref(s->jpgframe);
return 0;
}
static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame,
const AVPacket *avpkt)
{
@@ -1040,19 +1049,6 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame,
return avpkt->size;
}
static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
{
TiffContext *s = avctx->priv_data;
s->jpgframe->width = s->width;
s->jpgframe->height = s->height;
s->avctx_mjpeg->width = s->width;
s->avctx_mjpeg->height = s->height;
return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height);
}
static int init_image(TiffContext *s, ThreadFrame *frame)
{
int ret;
+8 -14
View File
@@ -384,7 +384,7 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
for (i = 0; i < 4; i++)
if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width)))
return AVERROR(ENOMEM);
goto error;
}
ret = ff_intrax8_common_init(s->avctx, &v->x8, &s->idsp,
@@ -539,12 +539,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
ff_h264chroma_init(&v->h264chroma, 8);
ff_qpeldsp_init(&s->qdsp);
// Must happen after calling ff_vc1_decode_end
// to avoid de-allocating the sprite_output_frame
v->sprite_output_frame = av_frame_alloc();
if (!v->sprite_output_frame)
return AVERROR(ENOMEM);
avctx->has_b_frames = !!avctx->max_b_frames;
if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6)
@@ -577,20 +571,15 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
v->sprite_height > 1 << 14 ||
v->output_width > 1 << 14 ||
v->output_height > 1 << 14) {
ret = AVERROR_INVALIDDATA;
goto error;
return AVERROR_INVALIDDATA;
}
if ((v->sprite_width&1) || (v->sprite_height&1)) {
avpriv_request_sample(avctx, "odd sprites support");
ret = AVERROR_PATCHWELCOME;
goto error;
return AVERROR_PATCHWELCOME;
}
}
return 0;
error:
av_frame_free(&v->sprite_output_frame);
return ret;
}
/** Close a VC1/WMV3 decoder
@@ -1147,6 +1136,11 @@ image:
avctx->height = avctx->coded_height = v->output_height;
if (avctx->skip_frame >= AVDISCARD_NONREF)
goto end;
if (!v->sprite_output_frame &&
!(v->sprite_output_frame = av_frame_alloc())) {
ret = AVERROR(ENOMEM);
goto err;
}
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
if ((ret = vc1_decode_sprites(v, &s->gb)) < 0)
goto err;
+12 -7
View File
@@ -194,7 +194,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
unsigned char len;
int ofs;
int frame_x, frame_y;
int frame_x, frame_y, prev_linesize;
int frame_width, frame_height;
frame_x = AV_RL16(&s->buf[6]);
@@ -282,7 +282,13 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
}
dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
if (s->prev_frame->data[0]) {
prev_linesize = s->prev_frame->linesize[0];
pp = s->prev_frame->data[0] + frame_y * prev_linesize + frame_x;
} else {
pp = NULL;
prev_linesize = 0;
}
switch (meth) {
case 1:
for (i = 0; i < frame_height; i++) {
@@ -298,7 +304,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
ofs += len;
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
if (ofs + len + 1 > frame_width || !pp)
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
@@ -311,7 +317,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
pp = FF_PTR_ADD(pp, prev_linesize);
}
break;
@@ -319,7 +325,6 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
for (i = 0; i < frame_height; i++) {
bytestream2_get_buffer(&gb, dp, frame_width);
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
}
break;
@@ -347,7 +352,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
}
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
if (ofs + len + 1 > frame_width || !pp)
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
@@ -360,7 +365,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
pp += s->prev_frame->linesize[0];
pp = FF_PTR_ADD(pp, prev_linesize);
}
break;
}
+6 -5
View File
@@ -367,7 +367,7 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx)
static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
int n, flags, pitch_range, lsp16_flag;
int n, flags, pitch_range, lsp16_flag, ret;
WMAVoiceContext *s = ctx->priv_data;
ff_thread_once(&init_static_once, wmavoice_init_static_data);
@@ -395,10 +395,11 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align);
s->do_apf = flags & 0x1;
if (s->do_apf) {
ff_rdft_init(&s->rdft, 7, DFT_R2C);
ff_rdft_init(&s->irdft, 7, IDFT_C2R);
ff_dct_init(&s->dct, 6, DCT_I);
ff_dct_init(&s->dst, 6, DST_I);
if ((ret = ff_rdft_init(&s->rdft, 7, DFT_R2C)) < 0 ||
(ret = ff_rdft_init(&s->irdft, 7, IDFT_C2R)) < 0 ||
(ret = ff_dct_init (&s->dct, 6, DCT_I)) < 0 ||
(ret = ff_dct_init (&s->dst, 6, DST_I)) < 0)
return ret;
ff_sine_window_init(s->cos, 256);
memcpy(&s->sin[255], s->cos, 256 * sizeof(s->cos[0]));
+4 -4
View File
@@ -1053,7 +1053,7 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in
for (j = result - 1; j >= 0; j--) {
for (i = 0; i < channels; i++)
bits[i] |= (*(samples++) & 1) << j;
bits[i] |= (*(samples++) & 1U) << j;
samples += stride - channels;
}
@@ -1210,7 +1210,7 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t
int32_t *samples_end = samples + stride * count;
for (i = 0; i < count; i++) {
samples[i * stride] <<= 15;
samples[i * stride] *= 1 << 15;
if (mode == HDCD_ANA_PE) {
int pel = (samples[i * stride] >> 16) & 1;
int32_t sample = samples[i * stride];
@@ -1284,13 +1284,13 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int
av_assert0(asample <= max_asample);
sample = sample >= 0 ? peaktab[asample] : -peaktab[asample];
} else
sample <<= shft;
sample *= (1 << shft);
samples[i * stride] = sample;
}
} else {
for (i = 0; i < count; i++)
samples[i * stride] <<= shft;
samples[i * stride] *= (1 << shft);
}
if (gain <= target_gain) {
+1 -1
View File
@@ -247,7 +247,7 @@ static int request_frame(AVFilterLink *outlink)
samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)];
sine->phi += sine->dphi;
if (sine->beep_index < sine->beep_length) {
samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << 1;
samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] * 2;
sine->phi_beep += sine->dphi_beep;
}
if (++sine->beep_index == sine->beep_period)
+4 -4
View File
@@ -141,7 +141,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
}
buf += sx + sy * stride;
ex -= sx;
f = ((ey - sy) << 16) / ex;
f = ((ey - sy) * (1 << 16)) / ex;
for (x = 0; x <= ex; x++) {
y = (x * f) >> 16;
fr = (x * f) & 0xFFFF;
@@ -156,7 +156,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
buf += sx + sy * stride;
ey -= sy;
if (ey)
f = ((ex - sx) << 16) / ey;
f = ((ex - sx) * (1 << 16)) / ey;
else
f = 0;
for(y= 0; y <= ey; y++){
@@ -199,8 +199,8 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
int length = sqrt((rx * rx + ry * ry) << 8);
// FIXME subpixel accuracy
rx = ROUNDED_DIV(rx * 3 << 4, length);
ry = ROUNDED_DIV(ry * 3 << 4, length);
rx = ROUNDED_DIV(rx * (3 << 4), length);
ry = ROUNDED_DIV(ry * (3 << 4), length);
if (tail) {
rx = -rx;
+1 -1
View File
@@ -57,7 +57,7 @@ static int cudaupload_query_formats(AVFilterContext *ctx)
int ret;
static const enum AVPixelFormat input_pix_fmts[] = {
AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_P010, AV_PIX_FMT_P016, AV_PIX_FMT_YUV444P16,
AV_PIX_FMT_0RGB32, AV_PIX_FMT_0BGR32,
#if CONFIG_VULKAN
+4 -1
View File
@@ -157,9 +157,12 @@ static int overlay_cuda_blend(FFFrameSync *fs)
if (ret < 0)
return ret;
if (!input_main || !input_overlay)
if (!input_main)
return AVERROR_BUG;
if (!input_overlay)
return ff_filter_frame(outlink, input_main);
ret = av_frame_make_writable(input_main);
if (ret < 0) {
av_frame_free(&input_main);
+3 -2
View File
@@ -152,9 +152,10 @@ static int query_formats(AVFilterContext *ctx)
return 0;
}
static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, int scale, int shift)
static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg,
int eb, int scale, int shift)
{
return av_clip_uint8( px >> 24 ) << 24
return px >> 24 << 24
| av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<<shift))) << 16
| av_clip_uint8((px >> 8 & 0xff) + ((eg * scale) / (1<<shift))) << 8
| av_clip_uint8((px & 0xff) + ((eb * scale) / (1<<shift)));
+2 -2
View File
@@ -635,8 +635,8 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s
int vsub= ((i+1)&2) ? scale->vsub : 0;
in_stride[i] = cur_pic->linesize[i] * mul;
out_stride[i] = out_buf->linesize[i] * mul;
in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
out[i] = out_buf->data[i] + field * out_buf->linesize[i];
in[i] = FF_PTR_ADD(cur_pic->data[i], ((y>>vsub)+field) * cur_pic->linesize[i]);
out[i] = FF_PTR_ADD(out_buf->data[i], field * out_buf->linesize[i]);
}
if (scale->input_is_pal)
in[1] = cur_pic->data[1];
+5 -2
View File
@@ -229,8 +229,11 @@ static int aa_read_header(AVFormatContext *s)
chapter_pos -= start + CHAPTER_HEADER_SIZE * chapter_idx;
avio_skip(pb, 4 + chapter_size);
if (!avpriv_new_chapter(s, chapter_idx, st->time_base,
chapter_pos * TIMEPREC, (chapter_pos + chapter_size) * TIMEPREC, NULL))
return AVERROR(ENOMEM);
chapter_pos * TIMEPREC,
(chapter_pos + chapter_size) * TIMEPREC, NULL)) {
av_freep(&c->tea_ctx);
return AVERROR(ENOMEM);
}
}
st->duration = (largest_size - CHAPTER_HEADER_SIZE * s->nb_chapters) * TIMEPREC;
+32 -18
View File
@@ -72,38 +72,39 @@ static int alp_read_header(AVFormatContext *s)
{
int ret;
AVStream *st;
ALPHeader hdr;
ALPHeader *hdr = s->priv_data;
AVCodecParameters *par;
if ((hdr.magic = avio_rl32(s->pb)) != ALP_TAG)
if ((hdr->magic = avio_rl32(s->pb)) != ALP_TAG)
return AVERROR_INVALIDDATA;
hdr.header_size = avio_rl32(s->pb);
hdr->header_size = avio_rl32(s->pb);
if (hdr.header_size != 8 && hdr.header_size != 12) {
if (hdr->header_size != 8 && hdr->header_size != 12) {
return AVERROR_INVALIDDATA;
}
if ((ret = avio_read(s->pb, hdr.adpcm, sizeof(hdr.adpcm))) < 0)
if ((ret = avio_read(s->pb, hdr->adpcm, sizeof(hdr->adpcm))) < 0)
return ret;
else if (ret != sizeof(hdr.adpcm))
else if (ret != sizeof(hdr->adpcm))
return AVERROR(EIO);
if (strncmp("ADPCM", hdr.adpcm, sizeof(hdr.adpcm)) != 0)
if (strncmp("ADPCM", hdr->adpcm, sizeof(hdr->adpcm)) != 0)
return AVERROR_INVALIDDATA;
hdr.unk1 = avio_r8(s->pb);
hdr.num_channels = avio_r8(s->pb);
hdr->unk1 = avio_r8(s->pb);
hdr->num_channels = avio_r8(s->pb);
if (hdr.header_size == 8) {
if (hdr->header_size == 8) {
/* .TUN music file */
hdr.sample_rate = 22050;
hdr->sample_rate = 22050;
} else {
/* .PCM sound file */
hdr.sample_rate = avio_rl32(s->pb);
hdr->sample_rate = avio_rl32(s->pb);
}
if (hdr.sample_rate > 44100) {
if (hdr->sample_rate > 44100) {
avpriv_request_sample(s, "Sample Rate > 44100");
return AVERROR_PATCHWELCOME;
}
@@ -115,12 +116,12 @@ static int alp_read_header(AVFormatContext *s)
par->codec_type = AVMEDIA_TYPE_AUDIO;
par->codec_id = AV_CODEC_ID_ADPCM_IMA_ALP;
par->format = AV_SAMPLE_FMT_S16;
par->sample_rate = hdr.sample_rate;
par->channels = hdr.num_channels;
par->sample_rate = hdr->sample_rate;
par->channels = hdr->num_channels;
if (hdr.num_channels == 1)
if (hdr->num_channels == 1)
par->channel_layout = AV_CH_LAYOUT_MONO;
else if (hdr.num_channels == 2)
else if (hdr->num_channels == 2)
par->channel_layout = AV_CH_LAYOUT_STEREO;
else
return AVERROR_INVALIDDATA;
@@ -151,12 +152,25 @@ static int alp_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int alp_seek(AVFormatContext *s, int stream_index,
int64_t pts, int flags)
{
const ALPHeader *hdr = s->priv_data;
if (pts != 0)
return AVERROR(EINVAL);
return avio_seek(s->pb, hdr->header_size + 8, SEEK_SET);
}
AVInputFormat ff_alp_demuxer = {
.name = "alp",
.long_name = NULL_IF_CONFIG_SMALL("LEGO Racers ALP"),
.priv_data_size = sizeof(ALPHeader),
.read_probe = alp_probe,
.read_header = alp_read_header,
.read_packet = alp_read_packet
.read_packet = alp_read_packet,
.read_seek = alp_seek,
};
#endif
+1 -1
View File
@@ -444,7 +444,7 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
if (index < 0)
return -1;
if ((ret = avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET)) < 0)
if ((ret = avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET)) < 0)
return ret;
ape->currentframe = index;
return 0;
+2 -2
View File
@@ -1690,11 +1690,11 @@ static int asf_read_seek(AVFormatContext *s, int stream_index,
asf->index_read = -1;
}
if (asf->index_read > 0 && st->internal->index_entries) {
if (asf->index_read > 0 && st->index_entries) {
int index = av_index_search_timestamp(st, pts, flags);
if (index >= 0) {
/* find the position */
uint64_t pos = st->internal->index_entries[index].pos;
uint64_t pos = st->index_entries[index].pos;
/* do the seek */
av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
+3 -3
View File
@@ -1636,11 +1636,11 @@ static int asf_read_seek(AVFormatContext *s, int stream_index,
ASFContext *asf = s->priv_data;
int idx, ret;
if (s->streams[stream_index]->internal->nb_index_entries && asf->is_simple_index) {
if (s->streams[stream_index]->nb_index_entries && asf->is_simple_index) {
idx = av_index_search_timestamp(s->streams[stream_index], timestamp, flags);
if (idx < 0 || idx >= s->streams[stream_index]->internal->nb_index_entries)
if (idx < 0 || idx >= s->streams[stream_index]->nb_index_entries)
return AVERROR_INVALIDDATA;
avio_seek(s->pb, s->streams[stream_index]->internal->index_entries[idx].pos, SEEK_SET);
avio_seek(s->pb, s->streams[stream_index]->index_entries[idx].pos, SEEK_SET);
} else {
if ((ret = ff_seek_frame_binary(s, stream_index, timestamp, flags)) < 0)
return ret;
+4 -7
View File
@@ -954,11 +954,7 @@ typedef struct AVStream {
* decoding: set by libavformat, must not be modified by the caller.
* encoding: unused
*/
#if FF_API_INIT_PACKET
AVPacket attached_pic;
#else
AVPacket *attached_pic;
#endif
/**
* An array of side data that applies to the whole stream (i.e. the
@@ -1092,10 +1088,11 @@ typedef struct AVStream {
void *unused7;
AVProbeData unused6;
int64_t unused5[16+1];
void *unused2;
int unused3;
unsigned int unused4;
#endif
AVIndexEntry *index_entries; /**< Only used if the format does not
support seeking natively. */
int nb_index_entries;
unsigned int index_entries_allocated_size;
/**
* Stream Identifier
+51 -51
View File
@@ -281,7 +281,7 @@ static void clean_index(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
AVIStream *ast = st->priv_data;
int n = st->internal->nb_index_entries;
int n = st->nb_index_entries;
int max = ast->sample_size;
int64_t pos, size, ts;
@@ -291,9 +291,9 @@ static void clean_index(AVFormatContext *s)
while (max < 1024)
max += max;
pos = st->internal->index_entries[0].pos;
size = st->internal->index_entries[0].size;
ts = st->internal->index_entries[0].timestamp;
pos = st->index_entries[0].pos;
size = st->index_entries[0].size;
ts = st->index_entries[0].timestamp;
for (j = 0; j < size; j += max)
av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
@@ -441,12 +441,12 @@ static int calculate_bitrate(AVFormatContext *s)
int64_t len = 0;
AVStream *st = s->streams[i];
if (!st->internal->nb_index_entries)
if (!st->nb_index_entries)
continue;
for (j = 0; j < st->internal->nb_index_entries; j++)
len += st->internal->index_entries[j].size;
maxpos = FFMAX(maxpos, st->internal->index_entries[j-1].pos);
for (j = 0; j < st->nb_index_entries; j++)
len += st->index_entries[j].size;
maxpos = FFMAX(maxpos, st->index_entries[j-1].pos);
lensum += len;
}
if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file
@@ -460,12 +460,12 @@ static int calculate_bitrate(AVFormatContext *s)
int64_t duration;
int64_t bitrate;
for (j = 0; j < st->internal->nb_index_entries; j++)
len += st->internal->index_entries[j].size;
for (j = 0; j < st->nb_index_entries; j++)
len += st->index_entries[j].size;
if (st->internal->nb_index_entries < 2 || st->codecpar->bit_rate > 0)
if (st->nb_index_entries < 2 || st->codecpar->bit_rate > 0)
continue;
duration = st->internal->index_entries[j-1].timestamp - st->internal->index_entries[0].timestamp;
duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp;
bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num);
if (bitrate > 0) {
st->codecpar->bit_rate = bitrate;
@@ -1057,7 +1057,7 @@ end_of_header:
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
if (st->internal->nb_index_entries)
if (st->nb_index_entries)
break;
}
// DV-in-AVI cannot be non-interleaved, if set this must be
@@ -1288,7 +1288,7 @@ start_sync:
AVStream *st1 = s->streams[1];
AVIStream *ast1 = st1->priv_data;
// workaround for broken small-file-bug402.avi
if ( d[2] == 'w' && d[3] == 'b'
if (ast1 && d[2] == 'w' && d[3] == 'b'
&& n == 0
&& st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
&& st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
@@ -1347,8 +1347,8 @@ start_sync:
if (size) {
uint64_t pos = avio_tell(pb) - 8;
if (!st->internal->index_entries || !st->internal->nb_index_entries ||
st->internal->index_entries[st->internal->nb_index_entries - 1].pos < pos) {
if (!st->index_entries || !st->nb_index_entries ||
st->index_entries[st->nb_index_entries - 1].pos < pos) {
av_add_index_entry(st, pos, ast->frame_offset, size,
0, AVINDEX_KEYFRAME);
}
@@ -1378,10 +1378,10 @@ static int ni_prepare_read(AVFormatContext *s)
int64_t ts = ast->frame_offset;
int64_t last_ts;
if (!st->internal->nb_index_entries)
if (!st->nb_index_entries)
continue;
last_ts = st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp;
last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
if (!ast->remaining && ts > last_ts)
continue;
@@ -1410,11 +1410,11 @@ static int ni_prepare_read(AVFormatContext *s)
} else {
i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
if (i >= 0)
best_ast->frame_offset = best_st->internal->index_entries[i].timestamp;
best_ast->frame_offset = best_st->index_entries[i].timestamp;
}
if (i >= 0) {
int64_t pos = best_st->internal->index_entries[i].pos;
int64_t pos = best_st->index_entries[i].pos;
pos += best_ast->packet_size - best_ast->remaining;
if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
return AVERROR_EOF;
@@ -1424,7 +1424,7 @@ static int ni_prepare_read(AVFormatContext *s)
avi->stream_index = best_stream_index;
if (!best_ast->remaining)
best_ast->packet_size =
best_ast->remaining = best_st->internal->index_entries[i].size;
best_ast->remaining = best_st->index_entries[i].size;
}
else
return AVERROR_EOF;
@@ -1515,15 +1515,15 @@ resync:
pkt->dts /= ast->sample_size;
pkt->stream_index = avi->stream_index;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->index_entries) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
AVIndexEntry *e;
int index;
index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY);
e = &st->internal->index_entries[index];
e = &st->index_entries[index];
if (index >= 0 && e->timestamp == ast->frame_offset) {
if (index == st->internal->nb_index_entries-1) {
if (index == st->nb_index_entries-1) {
int key=1;
uint32_t state=-1;
if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
@@ -1559,7 +1559,7 @@ resync:
}
ast->seek_pos= 0;
if (!avi->non_interleaved && st->internal->nb_index_entries>1 && avi->index_loaded>1) {
if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
if (avi->dts_max < dts) {
@@ -1659,8 +1659,8 @@ static int avi_read_idx1(AVFormatContext *s, int size)
if (!anykey) {
for (index = 0; index < s->nb_streams; index++) {
st = s->streams[index];
if (st->internal->nb_index_entries)
st->internal->index_entries[0].flags |= AVINDEX_KEYFRAME;
if (st->nb_index_entries)
st->index_entries[0].flags |= AVINDEX_KEYFRAME;
}
}
return 0;
@@ -1685,16 +1685,16 @@ static int check_stream_max_drift(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
AVIStream *ast = st->priv_data;
int n = st->internal->nb_index_entries;
while (idx[i] < n && st->internal->index_entries[idx[i]].pos < pos)
int n = st->nb_index_entries;
while (idx[i] < n && st->index_entries[idx[i]].pos < pos)
idx[i]++;
if (idx[i] < n) {
int64_t dts;
dts = av_rescale_q(st->internal->index_entries[idx[i]].timestamp /
dts = av_rescale_q(st->index_entries[idx[i]].timestamp /
FFMAX(ast->sample_size, 1),
st->time_base, AV_TIME_BASE_Q);
min_dts = FFMIN(min_dts, dts);
min_pos = FFMIN(min_pos, st->internal->index_entries[idx[i]].pos);
min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
}
}
for (i = 0; i < s->nb_streams; i++) {
@@ -1703,7 +1703,7 @@ static int check_stream_max_drift(AVFormatContext *s)
if (idx[i] && min_dts != INT64_MAX / 2) {
int64_t dts, delta_dts;
dts = av_rescale_q(st->internal->index_entries[idx[i] - 1].timestamp /
dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp /
FFMAX(ast->sample_size, 1),
st->time_base, AV_TIME_BASE_Q);
delta_dts = av_sat_sub64(dts, min_dts);
@@ -1733,30 +1733,30 @@ static int guess_ni_flag(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
int n = st->internal->nb_index_entries;
int n = st->nb_index_entries;
unsigned int size;
if (n <= 0)
continue;
if (n >= 2) {
int64_t pos = st->internal->index_entries[0].pos;
int64_t pos = st->index_entries[0].pos;
unsigned tag[2];
avio_seek(s->pb, pos, SEEK_SET);
tag[0] = avio_r8(s->pb);
tag[1] = avio_r8(s->pb);
avio_rl16(s->pb);
size = avio_rl32(s->pb);
if (get_stream_idx(tag) == i && pos + size > st->internal->index_entries[1].pos)
if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
last_start = INT64_MAX;
if (get_stream_idx(tag) == i && size == st->internal->index_entries[0].size + 8)
if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8)
last_start = INT64_MAX;
}
if (st->internal->index_entries[0].pos > last_start)
last_start = st->internal->index_entries[0].pos;
if (st->internal->index_entries[n - 1].pos < first_end)
first_end = st->internal->index_entries[n - 1].pos;
if (st->index_entries[0].pos > last_start)
last_start = st->index_entries[0].pos;
if (st->index_entries[n - 1].pos < first_end)
first_end = st->index_entries[n - 1].pos;
}
avio_seek(s->pb, oldpos, SEEK_SET);
@@ -1844,20 +1844,20 @@ static int avi_read_seek(AVFormatContext *s, int stream_index,
timestamp * FFMAX(ast->sample_size, 1),
flags);
if (index < 0) {
if (st->internal->nb_index_entries > 0)
if (st->nb_index_entries > 0)
av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
timestamp * FFMAX(ast->sample_size, 1),
st->internal->index_entries[0].timestamp,
st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp);
st->index_entries[0].timestamp,
st->index_entries[st->nb_index_entries - 1].timestamp);
return AVERROR_INVALIDDATA;
}
/* find the position */
pos = st->internal->index_entries[index].pos;
timestamp = st->internal->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
pos = st->index_entries[index].pos;
timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n",
timestamp, index, st->internal->index_entries[index].timestamp);
timestamp, index, st->index_entries[index].timestamp);
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
/* One and only one real stream for DV in AVI, and it has video */
@@ -1888,7 +1888,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index,
continue;
}
if (st2->internal->nb_index_entries <= 0)
if (st2->nb_index_entries <= 0)
continue;
// av_assert1(st2->codecpar->block_align);
@@ -1902,14 +1902,14 @@ static int avi_read_seek(AVFormatContext *s, int stream_index,
(st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
if (index < 0)
index = 0;
ast2->seek_pos = st2->internal->index_entries[index].pos;
ast2->seek_pos = st2->index_entries[index].pos;
pos_min = FFMIN(pos_min,ast2->seek_pos);
}
for (i = 0; i < s->nb_streams; i++) {
AVStream *st2 = s->streams[i];
AVIStream *ast2 = st2->priv_data;
if (ast2->sub_ctx || st2->internal->nb_index_entries <= 0)
if (ast2->sub_ctx || st2->nb_index_entries <= 0)
continue;
index = av_index_search_timestamp(
@@ -1918,9 +1918,9 @@ static int avi_read_seek(AVFormatContext *s, int stream_index,
flags | AVSEEK_FLAG_BACKWARD | (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
if (index < 0)
index = 0;
while (!avi->non_interleaved && index>0 && st2->internal->index_entries[index-1].pos >= pos_min)
while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
index--;
ast2->frame_offset = st2->internal->index_entries[index].timestamp;
ast2->frame_offset = st2->index_entries[index].timestamp;
}
/* do the seek */
+5 -5
View File
@@ -225,8 +225,8 @@ static int read_header(AVFormatContext *s)
return ret;
}
if (vst->internal->index_entries)
avio_seek(pb, vst->internal->index_entries[0].pos + bink->smush_size, SEEK_SET);
if (vst->index_entries)
avio_seek(pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET);
else
avio_skip(pb, 4);
@@ -256,8 +256,8 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
}
bink->remain_packet_size = st->internal->index_entries[index_entry].size;
bink->flags = st->internal->index_entries[index_entry].flags;
bink->remain_packet_size = st->index_entries[index_entry].size;
bink->flags = st->index_entries[index_entry].flags;
bink->current_track = 0;
}
@@ -313,7 +313,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
return -1;
/* seek to the first frame */
ret = avio_seek(s->pb, vst->internal->index_entries[0].pos + bink->smush_size, SEEK_SET);
ret = avio_seek(s->pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET);
if (ret < 0)
return ret;
+25 -20
View File
@@ -204,15 +204,20 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
st->nb_frames += avio_rb32(pb); /* priming frames */
st->nb_frames += avio_rb32(pb); /* remainder frames */
st->duration = 0;
for (i = 0; i < num_packets; i++) {
if (avio_feof(pb))
return AVERROR_INVALIDDATA;
ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME);
if (ret < 0)
return ret;
pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb);
st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
st->duration = caf->frames_per_packet * num_packets;
pos = caf-> bytes_per_packet * num_packets;
} else {
st->duration = 0;
for (i = 0; i < num_packets; i++) {
if (avio_feof(pb))
return AVERROR_INVALIDDATA;
ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME);
if (ret < 0)
return ret;
pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb);
st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
}
}
if (avio_tell(pb) - ccount > size) {
@@ -337,7 +342,7 @@ found_data:
if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
if (caf->data_size > 0)
st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
} else if (st->internal->nb_index_entries && st->duration > 0) {
} else if (st->nb_index_entries && st->duration > 0) {
if (st->codecpar->sample_rate && caf->data_size / st->duration > INT64_MAX / st->codecpar->sample_rate / 8) {
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %d * 8 * %"PRId64"\n",
st->codecpar->sample_rate, caf->data_size / st->duration);
@@ -390,13 +395,13 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size;
pkt_size = FFMIN(pkt_size, left);
pkt_frames = pkt_size / caf->bytes_per_packet;
} else if (st->internal->nb_index_entries) {
if (caf->packet_cnt < st->internal->nb_index_entries - 1) {
pkt_size = st->internal->index_entries[caf->packet_cnt + 1].pos - st->internal->index_entries[caf->packet_cnt].pos;
pkt_frames = st->internal->index_entries[caf->packet_cnt + 1].timestamp - st->internal->index_entries[caf->packet_cnt].timestamp;
} else if (caf->packet_cnt == st->internal->nb_index_entries - 1) {
pkt_size = caf->num_bytes - st->internal->index_entries[caf->packet_cnt].pos;
pkt_frames = st->duration - st->internal->index_entries[caf->packet_cnt].timestamp;
} else if (st->nb_index_entries) {
if (caf->packet_cnt < st->nb_index_entries - 1) {
pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos;
pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp;
} else if (caf->packet_cnt == st->nb_index_entries - 1) {
pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos;
pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp;
} else {
return AVERROR(EIO);
}
@@ -435,10 +440,10 @@ static int read_seek(AVFormatContext *s, int stream_index,
pos = FFMIN(pos, caf->data_size);
packet_cnt = pos / caf->bytes_per_packet;
frame_cnt = caf->frames_per_packet * packet_cnt;
} else if (st->internal->nb_index_entries) {
} else if (st->nb_index_entries) {
packet_cnt = av_index_search_timestamp(st, timestamp, flags);
frame_cnt = st->internal->index_entries[packet_cnt].timestamp;
pos = st->internal->index_entries[packet_cnt].pos;
frame_cnt = st->index_entries[packet_cnt].timestamp;
pos = st->index_entries[packet_cnt].pos;
} else {
return -1;
}
+2 -2
View File
@@ -288,10 +288,10 @@ static int cine_read_packet(AVFormatContext *avctx, AVPacket *pkt)
AVIOContext *pb = avctx->pb;
int n, size, ret;
if (cine->pts >= st->internal->nb_index_entries)
if (cine->pts >= st->nb_index_entries)
return AVERROR_EOF;
avio_seek(pb, st->internal->index_entries[cine->pts].pos, SEEK_SET);
avio_seek(pb, st->index_entries[cine->pts].pos, SEEK_SET);
n = avio_rl32(pb);
if (n < 8)
return AVERROR_INVALIDDATA;
+2 -2
View File
@@ -434,10 +434,10 @@ static int dhav_read_seek(AVFormatContext *s, int stream_index,
if (index < 0)
return -1;
if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0)
if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
return -1;
pts = st->internal->index_entries[index].timestamp;
pts = st->index_entries[index].timestamp;
for (int n = 0; n < s->nb_streams; n++) {
AVStream *st = s->streams[n];
+17 -20
View File
@@ -219,7 +219,6 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt)
} else
read_size = DSS_FRAME_SIZE;
ctx->counter -= read_size;
ctx->packet_size = DSS_FRAME_SIZE - 1;
ret = av_new_packet(pkt, DSS_FRAME_SIZE);
@@ -231,17 +230,16 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->stream_index = 0;
s->bit_rate = 8LL * ctx->packet_size * st->codecpar->sample_rate * 512 / (506 * pkt->duration);
if (ctx->counter < 0) {
int size2 = ctx->counter + read_size;
ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset,
size2 - offset);
if (ret < size2 - offset)
if (ctx->counter < read_size) {
ret = avio_read(s->pb, ctx->dss_sp_buf + buff_offset,
ctx->counter);
if (ret < ctx->counter)
goto error_eof;
offset = ctx->counter;
dss_skip_audio_header(s, pkt);
offset = size2;
}
ctx->counter -= read_size;
ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset,
read_size - offset);
@@ -278,7 +276,7 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt)
size = frame_size[byte & 3];
ctx->packet_size = size;
ctx->counter -= size;
ctx->counter--;
ret = av_new_packet(pkt, size);
if (ret < 0)
@@ -288,27 +286,26 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->data[0] = byte;
offset = 1;
pkt->duration = 240;
s->bit_rate = 8LL * size * st->codecpar->sample_rate * 512 / (506 * pkt->duration);
s->bit_rate = 8LL * size-- * st->codecpar->sample_rate * 512 / (506 * pkt->duration);
pkt->stream_index = 0;
if (ctx->counter < 0) {
int size2 = ctx->counter + size;
if (ctx->counter < size) {
ret = avio_read(s->pb, pkt->data + offset,
size2 - offset);
if (ret < size2 - offset) {
ctx->counter);
if (ret < ctx->counter)
return ret < 0 ? ret : AVERROR_EOF;
}
offset += ctx->counter;
size -= ctx->counter;
ctx->counter = 0;
dss_skip_audio_header(s, pkt);
offset = size2;
}
ctx->counter -= size;
ret = avio_read(s->pb, pkt->data + offset, size - offset);
if (ret < size - offset) {
ret = avio_read(s->pb, pkt->data + offset, size);
if (ret < size)
return ret < 0 ? ret : AVERROR_EOF;
}
return pkt->size;
}
+4 -4
View File
@@ -40,8 +40,8 @@ static void reset_index_position(int64_t metadata_head_size, AVStream *st)
{
/* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */
int i;
for(i=0; i<st->internal->nb_index_entries; i++) {
st->internal->index_entries[i].pos += metadata_head_size;
for(i=0; i<st->nb_index_entries; i++) {
st->index_entries[i].pos += metadata_head_size;
}
}
@@ -318,10 +318,10 @@ static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
}
index = av_index_search_timestamp(s->streams[0], timestamp, flags);
if(index<0 || index >= s->streams[0]->internal->nb_index_entries)
if(index<0 || index >= s->streams[0]->nb_index_entries)
return -1;
e = s->streams[0]->internal->index_entries[index];
e = s->streams[0]->index_entries[index];
pos = avio_seek(s->pb, e.pos, SEEK_SET);
if (pos >= 0) {
return 0;
+3 -3
View File
@@ -268,7 +268,7 @@ static int flic_read_seek(AVFormatContext *s, int stream_index,
int64_t pos, ts;
int index;
if (!st->internal->index_entries || stream_index != flic->video_stream_index)
if (!st->index_entries || stream_index != flic->video_stream_index)
return -1;
index = av_index_search_timestamp(st, pts, flags);
@@ -278,8 +278,8 @@ static int flic_read_seek(AVFormatContext *s, int stream_index,
if (index < 0)
return -1;
pos = st->internal->index_entries[index].pos;
ts = st->internal->index_entries[index].timestamp;
pos = st->index_entries[index].pos;
ts = st->index_entries[index].timestamp;
flic->frame_number = ts;
avio_seek(s->pb, pos, SEEK_SET);
return 0;
+7 -5
View File
@@ -142,7 +142,7 @@ static void add_keyframes_index(AVFormatContext *s)
av_assert0(flv->last_keyframe_stream_index <= s->nb_streams);
stream = s->streams[flv->last_keyframe_stream_index];
if (stream->internal->nb_index_entries == 0) {
if (stream->nb_index_entries == 0) {
for (i = 0; i < flv->keyframe_count; i++) {
av_log(s, AV_LOG_TRACE, "keyframe filepositions = %"PRId64" times = %"PRId64"\n",
flv->keyframe_filepositions[i], flv->keyframe_times[i] * 1000);
@@ -844,10 +844,10 @@ static void clear_index_entries(AVFormatContext *s, int64_t pos)
AVStream *st = s->streams[i];
/* Remove all index entries that point to >= pos */
out = 0;
for (j = 0; j < st->internal->nb_index_entries; j++)
if (st->internal->index_entries[j].pos < pos)
st->internal->index_entries[out++] = st->internal->index_entries[j];
st->internal->nb_index_entries = out;
for (j = 0; j < st->nb_index_entries; j++)
if (st->index_entries[j].pos < pos)
st->index_entries[out++] = st->index_entries[j];
st->nb_index_entries = out;
}
}
@@ -875,6 +875,8 @@ static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth)
parse_name = 0;
case AMF_DATA_TYPE_MIXEDARRAY:
nb = avio_rb32(pb);
if (nb < 0)
return AVERROR_INVALIDDATA;
case AMF_DATA_TYPE_OBJECT:
while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) {
if (parse_name) {
+3 -3
View File
@@ -575,9 +575,9 @@ static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int
AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
if (idx < 0)
return -1;
pos = st->internal->index_entries[idx].pos;
if (idx < st->internal->nb_index_entries - 2)
maxlen = st->internal->index_entries[idx + 2].pos - pos;
pos = st->index_entries[idx].pos;
if (idx < st->nb_index_entries - 2)
maxlen = st->index_entries[idx + 2].pos - pos;
maxlen = FFMAX(maxlen, 200 * 1024);
res = avio_seek(s->pb, pos, SEEK_SET);
if (res < 0)
+4 -4
View File
@@ -195,15 +195,15 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt)
if (ifv->next_video_index < ifv->total_vframes) {
st = s->streams[ifv->video_stream_index];
if (ifv->next_video_index < st->internal->nb_index_entries)
e_next = ev = &st->internal->index_entries[ifv->next_video_index];
if (ifv->next_video_index < st->nb_index_entries)
e_next = ev = &st->index_entries[ifv->next_video_index];
}
if (ifv->is_audio_present &&
ifv->next_audio_index < ifv->total_aframes) {
st = s->streams[ifv->audio_stream_index];
if (ifv->next_audio_index < st->internal->nb_index_entries) {
ea = &st->internal->index_entries[ifv->next_audio_index];
if (ifv->next_audio_index < st->nb_index_entries) {
ea = &st->index_entries[ifv->next_audio_index];
if (!ev || ea->timestamp < ev->timestamp)
e_next = ea;
}
+1 -1
View File
@@ -590,7 +590,7 @@ static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
int index = av_index_search_timestamp(st, timestamp, flags);
if(index < 0)
return -1;
s1->img_number = st->internal->index_entries[index].pos;
s1->img_number = st->index_entries[index].pos;
return 0;
}
+2
View File
@@ -113,6 +113,8 @@ retry:
imx->first_video_packet_pos = pos;
break;
case 0xAA98:
if (chunk_size > 256 * 3)
return AVERROR_INVALIDDATA;
for (int i = 0; i < chunk_size / 3; i++) {
unsigned r = avio_r8(pb) << 18;
unsigned g = avio_r8(pb) << 10;
-5
View File
@@ -236,11 +236,6 @@ struct AVStreamInternal {
} *info;
AVIndexEntry *index_entries; /**< Only used if the format does not
support seeking natively. */
int nb_index_entries;
unsigned int index_entries_allocated_size;
int64_t interleaver_chunk_size;
int64_t interleaver_chunk_duration;
+3 -2
View File
@@ -125,8 +125,8 @@ static const char *read_ts(JACOsubContext *jacosub, const char *buf,
return NULL;
shift_and_ret:
ts_start64 = (ts_start + jacosub->shift) * 100LL / jacosub->timeres;
ts_end64 = (ts_end + jacosub->shift) * 100LL / jacosub->timeres;
ts_start64 = (ts_start + (int64_t)jacosub->shift) * 100LL / jacosub->timeres;
ts_end64 = (ts_end + (int64_t)jacosub->shift) * 100LL / jacosub->timeres;
*start = ts_start64;
*duration = ts_end64 - ts_start64;
return buf + len;
@@ -199,6 +199,7 @@ static int jacosub_read_header(AVFormatContext *s)
sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line);
if (!sub) {
av_bprint_finalize(&header, NULL);
ret = AVERROR(ENOMEM);
goto fail;
}
+14 -14
View File
@@ -92,7 +92,7 @@ static int read_header(AVFormatContext *s)
vst->codecpar->height = avio_rl16(pb);
vst->duration =
vst->nb_frames =
ast->internal->nb_index_entries = avio_rl16(pb);
ast->nb_index_entries = avio_rl16(pb);
avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);
avio_skip(pb, 4);
@@ -107,19 +107,19 @@ static int read_header(AVFormatContext *s)
avio_skip(pb, 10);
ast->internal->index_entries = av_malloc(ast->internal->nb_index_entries *
sizeof(*ast->internal->index_entries));
if (!ast->internal->index_entries)
ast->index_entries = av_malloc(ast->nb_index_entries *
sizeof(*ast->index_entries));
if (!ast->index_entries)
return AVERROR(ENOMEM);
jv->frames = av_malloc(ast->internal->nb_index_entries * sizeof(JVFrame));
jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame));
if (!jv->frames) {
av_freep(&ast->internal->index_entries);
av_freep(&ast->index_entries);
return AVERROR(ENOMEM);
}
offset = 0x68 + ast->internal->nb_index_entries * 16;
for (i = 0; i < ast->internal->nb_index_entries; i++) {
AVIndexEntry *e = ast->internal->index_entries + i;
offset = 0x68 + ast->nb_index_entries * 16;
for (i = 0; i < ast->nb_index_entries; i++) {
AVIndexEntry *e = ast->index_entries + i;
JVFrame *jvf = jv->frames + i;
/* total frame size including audio, video, palette data and padding */
@@ -139,7 +139,7 @@ static int read_header(AVFormatContext *s)
if (s->error_recognition & AV_EF_EXPLODE) {
read_close(s);
av_freep(&jv->frames);
av_freep(&ast->internal->index_entries);
av_freep(&ast->index_entries);
return AVERROR_INVALIDDATA;
}
jvf->audio_size =
@@ -170,8 +170,8 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
AVStream *ast = s->streams[0];
int ret;
while (!avio_feof(s->pb) && jv->pts < ast->internal->nb_index_entries) {
const AVIndexEntry *e = ast->internal->index_entries + jv->pts;
while (!avio_feof(s->pb) && jv->pts < ast->nb_index_entries) {
const AVIndexEntry *e = ast->index_entries + jv->pts;
const JVFrame *jvf = jv->frames + jv->pts;
switch (jv->state) {
@@ -244,9 +244,9 @@ static int read_seek(AVFormatContext *s, int stream_index,
return 0;
}
if (i < 0 || i >= ast->internal->nb_index_entries)
if (i < 0 || i >= ast->nb_index_entries)
return 0;
if (avio_seek(s->pb, ast->internal->index_entries[i].pos, SEEK_SET) < 0)
if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0)
return -1;
jv->state = JV_AUDIO;
+11 -1
View File
@@ -110,12 +110,22 @@ static int kvag_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int kvag_seek(AVFormatContext *s, int stream_index,
int64_t pts, int flags)
{
if (pts != 0)
return AVERROR(EINVAL);
return avio_seek(s->pb, KVAG_HEADER_SIZE, SEEK_SET);
}
AVInputFormat ff_kvag_demuxer = {
.name = "kvag",
.long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"),
.read_probe = kvag_probe,
.read_header = kvag_read_header,
.read_packet = kvag_read_packet
.read_packet = kvag_read_packet,
.read_seek = kvag_seek,
};
#endif
+29 -19
View File
@@ -31,7 +31,6 @@
typedef struct GMEContext {
const AVClass *class;
Music_Emu *music_emu;
gme_info_t *info; ///< selected track
/* options */
int track_index;
@@ -55,12 +54,16 @@ static void add_meta(AVFormatContext *s, const char *name, const char *value)
av_dict_set(&s->metadata, name, value, 0);
}
static int load_metadata(AVFormatContext *s)
static int load_metadata(AVFormatContext *s, int64_t *duration)
{
GMEContext *gme = s->priv_data;
gme_info_t *info = gme->info;
gme_info_t *info = NULL;
char buf[30];
if (gme_track_info(gme->music_emu, &info, gme->track_index))
return AVERROR_STREAM_NOT_FOUND;
*duration = info->length;
add_meta(s, "system", info->system);
add_meta(s, "game", info->game);
add_meta(s, "song", info->song);
@@ -71,20 +74,30 @@ static int load_metadata(AVFormatContext *s)
snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu));
add_meta(s, "tracks", buf);
gme_free_info(info);
return 0;
}
#define AUDIO_PKT_SIZE 512
static int read_close_gme(AVFormatContext *s)
{
GMEContext *gme = s->priv_data;
gme_delete(gme->music_emu);
return 0;
}
static int read_header_gme(AVFormatContext *s)
{
AVStream *st;
AVIOContext *pb = s->pb;
GMEContext *gme = s->priv_data;
int64_t sz = avio_size(pb);
int64_t duration;
char *buf;
char dummy;
int ret;
if (sz < 0) {
av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
@@ -103,6 +116,7 @@ static int read_header_gme(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "File size is larger than max_size option "
"value %"PRIi64", consider increasing the max_size option\n",
gme->max_size);
av_freep(&buf);
return AVERROR_BUFFER_TOO_SMALL;
}
@@ -112,20 +126,24 @@ static int read_header_gme(AVFormatContext *s)
}
av_freep(&buf);
if (gme_track_info(gme->music_emu, &gme->info, gme->track_index))
return AVERROR_STREAM_NOT_FOUND;
if (gme_start_track(gme->music_emu, gme->track_index))
ret = load_metadata(s, &duration);
if (ret < 0) {
read_close_gme(s);
return ret;
}
if (gme_start_track(gme->music_emu, gme->track_index)) {
read_close_gme(s);
return AVERROR_UNKNOWN;
load_metadata(s);
}
st = avformat_new_stream(s, NULL);
if (!st)
if (!st) {
read_close_gme(s);
return AVERROR(ENOMEM);
}
avpriv_set_pts_info(st, 64, 1, 1000);
if (st->duration > 0)
st->duration = gme->info->length;
st->duration = duration;
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE);
st->codecpar->channels = 2;
@@ -153,14 +171,6 @@ static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int read_close_gme(AVFormatContext *s)
{
GMEContext *gme = s->priv_data;
gme_free_info(gme->info);
gme_delete(gme->music_emu);
return 0;
}
static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
{
GMEContext *gme = s->priv_data;
+24 -13
View File
@@ -99,6 +99,14 @@ static const AVOption options[] = {
{NULL},
};
static int modplug_read_close(AVFormatContext *s)
{
ModPlugContext *modplug = s->priv_data;
ModPlug_Unload(modplug->f);
av_freep(&modplug->buf);
return 0;
}
#define SET_OPT_IF_REQUESTED(libopt, opt, flag) do { \
if (modplug->opt) { \
settings.libopt = modplug->opt; \
@@ -168,6 +176,7 @@ static int modplug_read_header(AVFormatContext *s)
ModPlug_Settings settings;
ModPlugContext *modplug = s->priv_data;
int64_t sz = avio_size(pb);
int ret;
if (sz < 0) {
av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
@@ -221,8 +230,10 @@ static int modplug_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
}
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
}
avpriv_set_pts_info(st, 64, 1, 1000);
st->duration = ModPlug_GetLength(modplug->f);
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -235,8 +246,10 @@ static int modplug_read_header(AVFormatContext *s)
if (modplug->video_stream) {
AVStream *vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
if (!vst) {
ret = AVERROR(ENOMEM);
goto fail;
}
avpriv_set_pts_info(vst, 64, 1, 1000);
vst->duration = st->duration;
vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -247,7 +260,13 @@ static int modplug_read_header(AVFormatContext *s)
modplug->fsize = modplug->linesize * modplug->h;
}
return modplug_load_metadata(s);
ret = modplug_load_metadata(s);
if (ret < 0)
goto fail;
return 0;
fail:
modplug_read_close(s);
return ret;
}
static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y)
@@ -332,14 +351,6 @@ static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int modplug_read_close(AVFormatContext *s)
{
ModPlugContext *modplug = s->priv_data;
ModPlug_Unload(modplug->f);
av_freep(&modplug->buf);
return 0;
}
static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
{
ModPlugContext *modplug = s->priv_data;
+20 -20
View File
@@ -3845,13 +3845,13 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
matroska_parse_cues(matroska);
}
if (!st->internal->nb_index_entries)
if (!st->nb_index_entries)
goto err;
timestamp = FFMAX(timestamp, st->internal->index_entries[0].timestamp);
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) {
matroska_reset_status(matroska, 0, st->internal->index_entries[st->internal->nb_index_entries - 1].pos);
while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) {
if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) {
matroska_reset_status(matroska, 0, st->index_entries[st->nb_index_entries - 1].pos);
while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) {
matroska_clear_queue(matroska);
if (matroska_parse_cluster(matroska) < 0)
break;
@@ -3859,7 +3859,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
}
matroska_clear_queue(matroska);
if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->internal->nb_index_entries - 1))
if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->nb_index_entries - 1))
goto err;
tracks = matroska->tracks.elem;
@@ -3871,17 +3871,17 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
}
/* We seek to a level 1 element, so set the appropriate status. */
matroska_reset_status(matroska, 0, st->internal->index_entries[index].pos);
matroska_reset_status(matroska, 0, st->index_entries[index].pos);
if (flags & AVSEEK_FLAG_ANY) {
st->internal->skip_to_keyframe = 0;
matroska->skip_to_timecode = timestamp;
} else {
st->internal->skip_to_keyframe = 1;
matroska->skip_to_timecode = st->internal->index_entries[index].timestamp;
matroska->skip_to_timecode = st->index_entries[index].timestamp;
}
matroska->skip_to_keyframe = 1;
matroska->done = 0;
ff_update_cur_dts(s, st, st->internal->index_entries[index].timestamp);
ff_update_cur_dts(s, st, st->index_entries[index].timestamp);
return 0;
err:
// slightly hackish but allows proper fallback to
@@ -3927,8 +3927,8 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start)
MatroskaDemuxContext *matroska = s->priv_data;
CueDesc cue_desc;
int i;
int nb_index_entries = s->streams[0]->internal->nb_index_entries;
AVIndexEntry *index_entries = s->streams[0]->internal->index_entries;
int nb_index_entries = s->streams[0]->nb_index_entries;
AVIndexEntry *index_entries = s->streams[0]->index_entries;
if (ts >= matroska->duration * matroska->time_scale) return (CueDesc) {-1, -1, -1, -1};
for (i = 1; i < nb_index_entries; i++) {
if (index_entries[i - 1].timestamp * matroska->time_scale <= ts &&
@@ -3958,11 +3958,11 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s)
uint32_t id = matroska->current_id;
int64_t cluster_pos, before_pos;
int index, rv = 1;
if (s->streams[0]->internal->nb_index_entries <= 0) return 0;
if (s->streams[0]->nb_index_entries <= 0) return 0;
// seek to the first cluster using cues.
index = av_index_search_timestamp(s->streams[0], 0, 0);
if (index < 0) return 0;
cluster_pos = s->streams[0]->internal->index_entries[index].pos;
cluster_pos = s->streams[0]->index_entries[index].pos;
before_pos = avio_tell(s->pb);
while (1) {
uint64_t cluster_id, cluster_length;
@@ -4086,9 +4086,9 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t
double bandwidth = 0.0;
int i;
for (i = 0; i < st->internal->nb_index_entries; i++) {
for (i = 0; i < st->nb_index_entries; i++) {
int64_t prebuffer_ns = 1000000000;
int64_t time_ns = st->internal->index_entries[i].timestamp * matroska->time_scale;
int64_t time_ns = st->index_entries[i].timestamp * matroska->time_scale;
double nano_seconds_per_second = 1000000000.0;
int64_t prebuffered_ns = time_ns + prebuffer_ns;
double prebuffer_bytes = 0.0;
@@ -4226,14 +4226,14 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range)
// store cue point timestamps as a comma separated list for checking subsegment alignment in
// the muxer. assumes that each timestamp cannot be more than 20 characters long.
buf = av_malloc_array(s->streams[0]->internal->nb_index_entries, 20);
buf = av_malloc_array(s->streams[0]->nb_index_entries, 20);
if (!buf) return -1;
strcpy(buf, "");
for (i = 0; i < s->streams[0]->internal->nb_index_entries; i++) {
for (i = 0; i < s->streams[0]->nb_index_entries; i++) {
int ret = snprintf(buf + end, 20,
"%" PRId64"%s", s->streams[0]->internal->index_entries[i].timestamp,
i != s->streams[0]->internal->nb_index_entries - 1 ? "," : "");
if (ret <= 0 || (ret == 20 && i == s->streams[0]->internal->nb_index_entries - 1)) {
"%" PRId64"%s", s->streams[0]->index_entries[i].timestamp,
i != s->streams[0]->nb_index_entries - 1 ? "," : "");
if (ret <= 0 || (ret == 20 && i == s->streams[0]->nb_index_entries - 1)) {
av_log(s, AV_LOG_ERROR, "timestamp too long.\n");
av_free(buf);
return AVERROR_INVALIDDATA;
+10 -10
View File
@@ -191,12 +191,12 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f
}
} else if (vst && type == MKTAG('V', 'I', 'D', 'F') && size >= 4) {
uint64_t pts = avio_rl32(pb);
ff_add_index_entry(&vst->internal->index_entries, &vst->internal->nb_index_entries, &vst->internal->index_entries_allocated_size,
ff_add_index_entry(&vst->index_entries, &vst->nb_index_entries, &vst->index_entries_allocated_size,
avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME);
size -= 4;
} else if (ast && type == MKTAG('A', 'U', 'D', 'F') && size >= 4) {
uint64_t pts = avio_rl32(pb);
ff_add_index_entry(&ast->internal->index_entries, &ast->internal->nb_index_entries, &ast->internal->index_entries_allocated_size,
ff_add_index_entry(&ast->index_entries, &ast->nb_index_entries, &ast->index_entries_allocated_size,
avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME);
size -= 4;
} else if (vst && type == MKTAG('W','B','A','L') && size >= 28) {
@@ -374,22 +374,22 @@ static int read_header(AVFormatContext *avctx)
}
if (vst)
vst->duration = vst->internal->nb_index_entries;
vst->duration = vst->nb_index_entries;
if (ast)
ast->duration = ast->internal->nb_index_entries;
ast->duration = ast->nb_index_entries;
if ((vst && !vst->internal->nb_index_entries) || (ast && !ast->internal->nb_index_entries)) {
if ((vst && !vst->nb_index_entries) || (ast && !ast->nb_index_entries)) {
av_log(avctx, AV_LOG_ERROR, "no index entries found\n");
read_close(avctx);
return AVERROR_INVALIDDATA;
}
if (vst && ast)
avio_seek(pb, FFMIN(vst->internal->index_entries[0].pos, ast->internal->index_entries[0].pos), SEEK_SET);
avio_seek(pb, FFMIN(vst->index_entries[0].pos, ast->index_entries[0].pos), SEEK_SET);
else if (vst)
avio_seek(pb, vst->internal->index_entries[0].pos, SEEK_SET);
avio_seek(pb, vst->index_entries[0].pos, SEEK_SET);
else if (ast)
avio_seek(pb, ast->internal->index_entries[0].pos, SEEK_SET);
avio_seek(pb, ast->index_entries[0].pos, SEEK_SET);
return 0;
}
@@ -415,12 +415,12 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
return AVERROR(EIO);
}
pb = mlv->pb[st->internal->index_entries[index].size];
pb = mlv->pb[st->index_entries[index].size];
if (!pb) {
ret = FFERROR_REDO;
goto next_packet;
}
avio_seek(pb, st->internal->index_entries[index].pos, SEEK_SET);
avio_seek(pb, st->index_entries[index].pos, SEEK_SET);
avio_skip(pb, 4); // blockType
size = avio_rl32(pb);
+111 -105
View File
@@ -2037,8 +2037,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!entries)
return 0;
if (sc->chunk_offsets)
av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
if (sc->chunk_offsets) {
av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
return 0;
}
av_free(sc->chunk_offsets);
sc->chunk_count = 0;
sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
@@ -2263,7 +2265,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
}
bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
if (bits_per_sample) {
if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
st->codecpar->bits_per_coded_sample = bits_per_sample;
sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
}
@@ -2671,8 +2673,10 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!entries)
return 0;
if (sc->stsc_data)
av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
if (sc->stsc_data) {
av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
return 0;
}
av_free(sc->stsc_data);
sc->stsc_count = 0;
sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
@@ -3018,7 +3022,7 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_freep(&sc->sdtp_data);
sc->sdtp_count = 0;
sc->sdtp_data = av_mallocz(entries);
sc->sdtp_data = av_malloc(entries);
if (!sc->sdtp_data)
return AVERROR(ENOMEM);
@@ -3210,8 +3214,8 @@ static int find_prev_closest_index(AVStream *st,
int64_t* ctts_sample)
{
MOVStreamContext *msc = st->priv_data;
AVIndexEntry *e_keep = st->internal->index_entries;
int nb_keep = st->internal->nb_index_entries;
AVIndexEntry *e_keep = st->index_entries;
int nb_keep = st->nb_index_entries;
int64_t i = 0;
int64_t index_ctts_count;
@@ -3224,8 +3228,8 @@ static int find_prev_closest_index(AVStream *st,
timestamp_pts -= msc->dts_shift;
}
st->internal->index_entries = e_old;
st->internal->nb_index_entries = nb_old;
st->index_entries = e_old;
st->nb_index_entries = nb_old;
*index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
// Keep going backwards in the index entries until the timestamp is the same.
@@ -3278,14 +3282,14 @@ static int find_prev_closest_index(AVStream *st,
}
/* restore AVStream state*/
st->internal->index_entries = e_keep;
st->internal->nb_index_entries = nb_keep;
st->index_entries = e_keep;
st->nb_index_entries = nb_keep;
return *index >= 0 ? 0 : -1;
}
/**
* Add index entry with the given values, to the end of st->internal->index_entries.
* Returns the new size st->internal->index_entries if successful, else returns -1.
* Add index entry with the given values, to the end of st->index_entries.
* Returns the new size st->index_entries if successful, else returns -1.
*
* This function is similar to ff_add_index_entry in libavformat/utils.c
* except that here we are always unconditionally adding an index entry to
@@ -3299,27 +3303,27 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
{
AVIndexEntry *entries, *ie;
int64_t index = -1;
const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
// Double the allocation each time, to lower memory fragmentation.
// Another difference from ff_add_index_entry function.
const size_t requested_size =
min_size_needed > st->internal->index_entries_allocated_size ?
FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
min_size_needed > st->index_entries_allocated_size ?
FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
min_size_needed;
if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
return -1;
entries = av_fast_realloc(st->internal->index_entries,
&st->internal->index_entries_allocated_size,
entries = av_fast_realloc(st->index_entries,
&st->index_entries_allocated_size,
requested_size);
if (!entries)
return -1;
st->internal->index_entries= entries;
st->index_entries= entries;
index= st->internal->nb_index_entries++;
index= st->nb_index_entries++;
ie= &entries[index];
ie->pos = pos;
@@ -3338,10 +3342,10 @@ static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_
int64_t* frame_duration_buffer,
int frame_duration_buffer_size) {
int i = 0;
av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
for (i = 0; i < frame_duration_buffer_size; i++) {
end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
st->index_entries[end_index - 1 - i].timestamp = end_ts;
}
}
@@ -3393,14 +3397,14 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
st->codecpar->codec_id == AV_CODEC_ID_H264) {
st->codecpar->video_delay = 0;
for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
// Point j to the last elem of the buffer and insert the current pts there.
j = buf_start;
buf_start = (buf_start + 1);
if (buf_start == MAX_REORDER_DELAY + 1)
buf_start = 0;
pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
// The timestamps that are already in the sorted buffer, and are greater than the
// current pts, are exactly the timestamps that need to be buffered to output PTS
@@ -3480,7 +3484,7 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
}
/**
* Fix st->internal->index_entries, so that it contains only the entries (and the entries
* Fix st->index_entries, so that it contains only the entries (and the entries
* which are needed to decode them) that fall in the edit list time ranges.
* Also fixes the timestamps of the index entries to match the timeline
* specified the edit lists.
@@ -3488,8 +3492,8 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
static void mov_fix_index(MOVContext *mov, AVStream *st)
{
MOVStreamContext *msc = st->priv_data;
AVIndexEntry *e_old = st->internal->index_entries;
int nb_old = st->internal->nb_index_entries;
AVIndexEntry *e_old = st->index_entries;
int nb_old = st->nb_index_entries;
const AVIndexEntry *e_old_end = e_old + nb_old;
const AVIndexEntry *current = NULL;
MOVStts *ctts_data_old = msc->ctts_data;
@@ -3534,9 +3538,9 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
current_index_range = msc->index_ranges - 1;
// Clean AVStream from traces of old index
st->internal->index_entries = NULL;
st->internal->index_entries_allocated_size = 0;
st->internal->nb_index_entries = 0;
st->index_entries = NULL;
st->index_entries_allocated_size = 0;
st->nb_index_entries = 0;
// Clean ctts fields of MOVStreamContext
msc->ctts_data = NULL;
@@ -3665,7 +3669,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
// discarded packets.
if (frame_duration_buffer) {
fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
frame_duration_buffer, num_discarded_begin);
av_freep(&frame_duration_buffer);
}
@@ -3704,7 +3708,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Make timestamps strictly monotonically increasing by rewriting timestamps for
// discarded packets.
if (frame_duration_buffer) {
fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
frame_duration_buffer, num_discarded_begin);
av_freep(&frame_duration_buffer);
}
@@ -3765,8 +3769,8 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (msc->min_corrected_pts > 0) {
av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
for (i = 0; i < st->internal->nb_index_entries; ++i) {
st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
for (i = 0; i < st->nb_index_entries; ++i) {
st->index_entries[i].timestamp -= msc->min_corrected_pts;
}
}
}
@@ -3859,17 +3863,17 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
current_dts -= sc->dts_shift;
last_dts = current_dts;
if (!sc->sample_count || st->internal->nb_index_entries)
if (!sc->sample_count || st->nb_index_entries)
return;
if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
return;
if (av_reallocp_array(&st->internal->index_entries,
st->internal->nb_index_entries + sc->sample_count,
sizeof(*st->internal->index_entries)) < 0) {
st->internal->nb_index_entries = 0;
if (av_reallocp_array(&st->index_entries,
st->nb_index_entries + sc->sample_count,
sizeof(*st->index_entries)) < 0) {
st->nb_index_entries = 0;
return;
}
st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
if (ctts_data_old) {
// Expand ctts entries such that we have a 1-1 mapping with samples
@@ -3952,7 +3956,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
return;
}
e = &st->internal->index_entries[st->internal->nb_index_entries++];
e = &st->index_entries[st->nb_index_entries++];
e->pos = current_offset;
e->timestamp = current_dts;
e->size = sample_size;
@@ -3961,7 +3965,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
"size %u, distance %u, keyframe %d\n", st->index, current_sample,
current_offset, current_dts, sample_size, distance, keyframe);
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
ff_rfps_add_frame(mov->fc, st, current_dts);
}
@@ -4033,15 +4037,15 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
return;
if (av_reallocp_array(&st->internal->index_entries,
st->internal->nb_index_entries + total,
sizeof(*st->internal->index_entries)) < 0) {
st->internal->nb_index_entries = 0;
if (av_reallocp_array(&st->index_entries,
st->nb_index_entries + total,
sizeof(*st->index_entries)) < 0) {
st->nb_index_entries = 0;
return;
}
st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
// populate index
for (i = 0; i < sc->chunk_count; i++) {
@@ -4076,7 +4080,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
if (st->internal->nb_index_entries >= total) {
if (st->nb_index_entries >= total) {
av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
return;
}
@@ -4084,7 +4088,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
return;
}
e = &st->internal->index_entries[st->internal->nb_index_entries++];
e = &st->index_entries[st->nb_index_entries++];
e->pos = current_offset;
e->timestamp = current_dts;
e->size = size;
@@ -4107,8 +4111,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
// Update start time of the stream.
if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
if (sc->ctts_data) {
st->start_time += sc->ctts_data[0].duration;
}
@@ -4806,7 +4810,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// A valid index_entry means the trun for the fragment was read
// and it's samples are in index_entries at the given position.
// New index entries will be inserted before the index_entry found.
index_entry_pos = st->internal->nb_index_entries;
index_entry_pos = st->nb_index_entries;
for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
if (frag_stream_info && frag_stream_info->index_entry >= 0) {
@@ -4815,7 +4819,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
break;
}
}
av_assert0(index_entry_pos <= st->internal->nb_index_entries);
av_assert0(index_entry_pos <= st->nb_index_entries);
avio_r8(pb); /* version */
flags = avio_rb24(pb);
@@ -4866,22 +4870,22 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
// realloc space for new index entries
if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
}
if (entries == 0)
return 0;
requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
new_entries = av_fast_realloc(st->internal->index_entries,
&st->internal->index_entries_allocated_size,
requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
new_entries = av_fast_realloc(st->index_entries,
&st->index_entries_allocated_size,
requested_size);
if (!new_entries)
return AVERROR(ENOMEM);
st->internal->index_entries= new_entries;
st->index_entries= new_entries;
requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
old_ctts_allocated_size = sc->ctts_allocated_size;
ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
requested_size);
@@ -4895,12 +4899,12 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
sc->ctts_allocated_size - old_ctts_allocated_size);
if (index_entry_pos < st->internal->nb_index_entries) {
if (index_entry_pos < st->nb_index_entries) {
// Make hole in index_entries and ctts_data for new samples
memmove(st->internal->index_entries + index_entry_pos + entries,
st->internal->index_entries + index_entry_pos,
sizeof(*st->internal->index_entries) *
(st->internal->nb_index_entries - index_entry_pos));
memmove(st->index_entries + index_entry_pos + entries,
st->index_entries + index_entry_pos,
sizeof(*st->index_entries) *
(st->nb_index_entries - index_entry_pos));
memmove(sc->ctts_data + index_entry_pos + entries,
sc->ctts_data + index_entry_pos,
sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
@@ -4909,15 +4913,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
}
st->internal->nb_index_entries += entries;
sc->ctts_count = st->internal->nb_index_entries;
st->nb_index_entries += entries;
sc->ctts_count = st->nb_index_entries;
// Record the index_entry position in frag_index of this fragment
if (frag_stream_info)
frag_stream_info->index_entry = index_entry_pos;
if (index_entry_pos > 0)
prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
prev_dts = st->index_entries[index_entry_pos-1].timestamp;
for (i = 0; i < entries && !pb->eof_reached; i++) {
unsigned sample_size = frag->size;
@@ -4966,11 +4970,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (prev_dts >= dts)
index_entry_flags |= AVINDEX_DISCARD_FRAME;
st->internal->index_entries[index_entry_pos].pos = offset;
st->internal->index_entries[index_entry_pos].timestamp = dts;
st->internal->index_entries[index_entry_pos].size= sample_size;
st->internal->index_entries[index_entry_pos].min_distance= distance;
st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
st->index_entries[index_entry_pos].pos = offset;
st->index_entries[index_entry_pos].timestamp = dts;
st->index_entries[index_entry_pos].size= sample_size;
st->index_entries[index_entry_pos].min_distance= distance;
st->index_entries[index_entry_pos].flags = index_entry_flags;
sc->ctts_data[index_entry_pos].count = 1;
sc->ctts_data[index_entry_pos].duration = ctts_duration;
@@ -4997,16 +5001,16 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// EOF found before reading all entries. Fix the hole this would
// leave in index_entries and ctts_data
int gap = entries - i;
memmove(st->internal->index_entries + index_entry_pos,
st->internal->index_entries + index_entry_pos + gap,
sizeof(*st->internal->index_entries) *
(st->internal->nb_index_entries - (index_entry_pos + gap)));
memmove(st->index_entries + index_entry_pos,
st->index_entries + index_entry_pos + gap,
sizeof(*st->index_entries) *
(st->nb_index_entries - (index_entry_pos + gap)));
memmove(sc->ctts_data + index_entry_pos,
sc->ctts_data + index_entry_pos + gap,
sizeof(*sc->ctts_data) *
(sc->ctts_count - (index_entry_pos + gap)));
st->internal->nb_index_entries -= gap;
st->nb_index_entries -= gap;
sc->ctts_count -= gap;
if (index_entry_pos < sc->current_sample) {
sc->current_sample -= gap;
@@ -5019,11 +5023,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// fragment that overlap with AVINDEX_DISCARD_FRAME
prev_dts = AV_NOPTS_VALUE;
if (index_entry_pos > 0)
prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
if (prev_dts < st->internal->index_entries[i].timestamp)
prev_dts = st->index_entries[index_entry_pos-1].timestamp;
for (i = index_entry_pos; i < st->nb_index_entries; i++) {
if (prev_dts < st->index_entries[i].timestamp)
break;
st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
}
// If a hole was created to insert the new index_entries into,
@@ -7118,10 +7122,10 @@ static int mov_probe(const AVProbeData *p)
int64_t size;
int minsize = 8;
/* ignore invalid offset */
if ((offset + 8) > (unsigned int)p->buf_size)
if ((offset + 8ULL) > (unsigned int)p->buf_size)
break;
size = AV_RB32(p->buf + offset);
if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
size = AV_RB64(p->buf+offset + 8);
minsize = 16;
} else if (size == 0) {
@@ -7165,6 +7169,8 @@ static int mov_probe(const AVProbeData *p)
score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
break;
}
if (size > INT64_MAX - offset)
break;
offset += size;
}
if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
@@ -7221,9 +7227,9 @@ static void mov_read_chapters(AVFormatContext *s)
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
if (st->internal->nb_index_entries) {
if (st->nb_index_entries) {
// Retrieve the first frame, if possible
AVIndexEntry *sample = &st->internal->index_entries[0];
AVIndexEntry *sample = &st->index_entries[0];
if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
goto finish;
@@ -7239,9 +7245,9 @@ static void mov_read_chapters(AVFormatContext *s)
st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
st->discard = AVDISCARD_ALL;
for (i = 0; i < st->internal->nb_index_entries; i++) {
AVIndexEntry *sample = &st->internal->index_entries[i];
int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
for (i = 0; i < st->nb_index_entries; i++) {
AVIndexEntry *sample = &st->index_entries[i];
int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
uint8_t *title;
uint16_t ch;
int len, title_len;
@@ -7314,10 +7320,10 @@ static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
int64_t cur_pos = avio_tell(sc->pb);
int hh, mm, ss, ff, drop;
if (!st->internal->nb_index_entries)
if (!st->nb_index_entries)
return -1;
avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
avio_skip(s->pb, 13);
hh = avio_r8(s->pb);
mm = avio_r8(s->pb);
@@ -7339,10 +7345,10 @@ static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
int64_t cur_pos = avio_tell(sc->pb);
uint32_t value;
if (!st->internal->nb_index_entries)
if (!st->nb_index_entries)
return -1;
avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
value = avio_rb32(s->pb);
if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
@@ -7807,8 +7813,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
for (i = 0; i < s->nb_streams; i++) {
AVStream *avst = s->streams[i];
MOVStreamContext *msc = avst->priv_data;
if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
if (msc->pb && msc->current_sample < avst->nb_index_entries) {
AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
@@ -8011,8 +8017,8 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
sc->ctts_sample = 0;
}
} else {
int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
st->internal->index_entries[sc->current_sample].timestamp : st->duration;
int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
st->index_entries[sc->current_sample].timestamp : st->duration;
if (next_dts >= pkt->dts)
pkt->duration = next_dts - pkt->dts;
@@ -8093,7 +8099,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
sample = av_index_search_timestamp(st, timestamp, flags);
av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
sample = 0;
if (sample < 0) /* not sure what to do */
return AVERROR_INVALIDDATA;
@@ -8134,8 +8140,8 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
static int64_t mov_get_skip_samples(AVStream *st, int sample)
{
MOVStreamContext *sc = st->priv_data;
int64_t first_ts = st->internal->index_entries[0].timestamp;
int64_t ts = st->internal->index_entries[sample].timestamp;
int64_t first_ts = st->index_entries[0].timestamp;
int64_t ts = st->index_entries[sample].timestamp;
int64_t off;
if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
@@ -8164,7 +8170,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
if (mc->seek_individually) {
/* adjust seek timestamp to found sample timestamp */
int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
int64_t seek_timestamp = st->index_entries[sample].timestamp;
st->internal->skip_samples = mov_get_skip_samples(st, sample);
for (i = 0; i < s->nb_streams; i++) {
+3 -2
View File
@@ -5746,11 +5746,12 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (trk->entry >= trk->cluster_capacity) {
unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
if (av_reallocp_array(&trk->cluster, new_capacity,
sizeof(*trk->cluster))) {
void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
if (!cluster) {
ret = AVERROR(ENOMEM);
goto err;
}
trk->cluster = cluster;
trk->cluster_capacity = new_capacity;
}

Some files were not shown because too many files have changed in this diff Show More