Commit Graph

268 Commits

Author SHA1 Message Date
Martin Storsjö 4eb9232c6e libavformat: Split version.h
Signed-off-by: Martin Storsjö <martin@martin.st>
2022-03-16 14:05:26 +02:00
Anton Khirnov b6746b7462 lavf: drop the channel layout compat layer for old-style (de)muxers
All the (de)muxers have been converted to the new API.

Signed-off-by: James Almer <jamrial@gmail.com>
2022-03-15 09:42:39 -03:00
Anton Khirnov ac10e3c47c lavf: convert the generic layer to the new channel layout
Signed-off-by: James Almer <jamrial@gmail.com>
2022-03-15 09:42:29 -03:00
Anton Khirnov c30e22c9fb lavf: add a temporary compat layer for the channel layout API change
Mediates between old-style (de)muxers and new-style callers. Will be
removed once all the (de)muxers are converted to the new API.

Signed-off-by: James Almer <jamrial@gmail.com>
2022-03-15 09:42:29 -03:00
Andreas Rheinhardt c24ee7c275 avformat/mux: Peek into the muxing queue for avoid_negative_ts
Peeking into the muxing queue can improve the estimate of
the lowest timestamp needed for avoid_negative_ts in case
the lowest timestamp is in a packet other than the first packet
to be muxed.
This fixes tickets #4536 and #5784 as well as the output from
the matroska-avoid-negative-ts FATE-test.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-21 16:47:38 +01:00
Andreas Rheinhardt c602deb138 avformat/mux: Preserve sync even if later packet has negative ts
write_packet() has code to shift the packets timestamps
to make them nonnegative or even make them start at ts zero;
this code inspects every packet that is written and if a packet
with negative timestamp (whether this is dts or pts depends upon
another flag; basically: Matroska uses pts, everyone else dts)
is encountered, this is offset to make the timestamp zero.
All further packets will be offset accordingly (with the offset
converted according to the streams' timebases).

This is based around an assumption, namely that the timestamps
are indeed non-decreasing, so that the first packet with negative
timestamps is the first packet with timestamps. This assumption
is often fulfilled given that the default interleavement function
by default interleaves per dts; yet there are scenarios in which
it may not be fulfilled:
a) av_write_frame() instead of av_interleaved_write_frame() is used.
b) The audio_preload option is used.
c) When the timestamps that are made nonnegative/zero are pts
(i.e. with Matroska), because the packet with the smallest dts
is not necessarily the packet with the smallest pts.
d) Possibly with custom interleavement functions.
In these cases the relative sync of the first few packet(s) is offset
relative to the later packets. This contradicts the documentation
("When shifting is enabled, all output timestamps are shifted by
the same amount").

Therefore this commit changes this: As soon as the first packet
with valid timestamps is output, it is checked and recorded whether
the timestamps need to be shifted. Further packets are no longer
checked for needing to be offset; instead they are simply offset.
In the cases above this leads to packets with negative timestamps
(and the appropriate warnings) instead of desync. This will mostly
be fixed in the next commit.

This commit also factors handling the avoid_negative_ts stuff out
of write_packet() in order to be able to return immediately.

Tickets #4536 and #5784 as well as the matroska-avoid-negative-ts-test
are examples of c); as has been said, some timestamps are now negative,
yet the ref file update does not show it because ffmpeg.c sanitizes
the timestamps (-copyts disables it; ffprobe and mkvinfo also show
the original timestamps).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-21 16:47:38 +01:00
Andreas Rheinhardt f6d14b1297 avformat/avformat: Add AVFMT_AVOID_NEG_TS_DISABLED
And also don't use explicit constants in the movenc test.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-21 16:47:38 +01:00
Andreas Rheinhardt 5d5b62e595 avformat/mux: Remove assert based on faulty assumptions
This assert is based upon the wrong assumption that
the noninterleaved codepath is never used; if it is used,
max_interleave_delta is irrelevant. It furthermore
ignores audio_preload.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-21 16:45:43 +01:00
Andreas Rheinhardt d61240f8c9 avcodec/packet_internal: Add proper PacketList struct
Up until now, we had a PacketList structure which is actually
a PacketListEntry; a proper PacketList did not exist
and all the related functions just passed pointers to pointers
to the head and tail elements around. All these pointers were
actually consecutive elements of their containing structs,
i.e. the users already treated them as if they were a struct.

So add a proper PacketList struct and rename the current PacketList
to PacketListEntry; also make the functions use this structure
instead of the pair of pointers.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-04 13:16:50 +01:00
Andreas Rheinhardt b74e47c4ff avcodec/utils: Unavpriv avpriv_toupper4()
This function is quite small (96B with GCC 11.2 on x64 Ubuntu 21.10
at -O3), making it more economical to duplicate it into libavformat
instead of exporting it as avpriv: Doing so saves 2x24B in .dynsim,
2x16B in .dynstr, 2x2B .gnu.version, 24B in .rela.plt, 16B in .plt,
16B in .plt.sec (if enabled), 4B .gnu.hash; besides the actual
duplicated code this also adds 2x8B .eh_frame_hdr and 24B .eh_frame.

In other words: Duplicating is neutral size-wise (it is also presumed
neutral for other systems). Given that it avoids the runtime
overhead of dynamic symbols, it is advantageouos to duplicate the
function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-04 13:16:50 +01:00
Andreas Rheinhardt 41457e536c avformat/mux, mxfenc: Don't use sizeof(AVPacket)
This removes one of the last usages of sizeof(AVPacket)
in the generic muxing code.

Reviewed-by: Tomas Härdin <tjoppen@acc.umu.se>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2022-01-04 05:09:33 +01:00
Andreas Rheinhardt a5ee166327 avformat/avformat: Add AVStream parameter to check_bitstream() sig
For most check_bitstream() functions this just avoids having
to dereference s->streams[pkt->stream_index] themselves; but for
meta-muxers it will allow to forward the packet to stream with
a different stream_index (belonging to a different AVFormatContext)
without using a spare packet.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-11-27 12:55:41 +01:00
Andreas Rheinhardt 52d13d54e1 avformat/mux: Avoid overhead of packet list in case of single streams
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-11-19 17:56:12 +01:00
Andreas Rheinhardt c03e53aea7 avformat/mux: Store pointer to interleavement func in FFFormatContext
It avoids branches lateron and will allow to easily avoid the overhead
of the linked list currently in use in case there is only one stream.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-11-19 17:47:04 +01:00
Andreas Rheinhardt 5de6c90187 avformat/mux: Remove unnecessary av_packet_unref()
AVFormatInternal.parse_pkt is always blank after having been used.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-10-03 20:56:12 +02:00
Andreas Rheinhardt c2bb054979 avformat/internal: Allow AVFormatInternal.pkt to be used by muxers
It is unused by the generic muxing code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-10-03 20:56:05 +02:00
Andreas Rheinhardt 2ce6a9f847 avformat/mux: Use AVFormatInternal.parse_pkt for temporary packets
The documentation of said packet ("Every user has to ensure that
this packet is blank after using it") perfectly fits how we use said
packet in the generic muxing code. Better than the documentation of pkt.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-10-03 20:50:50 +02:00
Andreas Rheinhardt 4fa8daab79 avformat/mux: Don't use stack packet when writing interleaved packets
Currently the interleave_packet functions use a packet for
a new packet to be interleaved (may be NULL if there is none) and
a packet for output; said packet is always a stack packet in
interleaved_write_packet(). But all the interleave_packet functions
in use first move the packet to the packet list and then check whether
a packet can be returned, i.e. the effective lifetime of the new packet
ends before the packet for output is touched.

So one can use one packet both for input and output by adding a new
parameter that indicates whether there is a packet to add to the packet
list; there is just one complication: In case the muxer is flushed,
there is no packet available. This can be solved by reusing one of
the packets from AVFormatInternal. They are currently unused when
flushing in av_interleaved_write_frame().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-10-03 20:50:50 +02:00
Andreas Rheinhardt 805ec95f8e avformat/mux: Sanitize packets without data and side-data
The BSF API treats such packets as signalling EOF and therefore
such a packet might corrupt the BSF state. In such a case,
the guarantee that av_interleaved_write_frame() always frees
the packet is not upheld.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-10-03 20:50:49 +02:00
Andreas Rheinhardt 40bdd8cc05 avformat: Avoid allocation for AVStreamInternal
Do this by allocating AVStream together with the data that is
currently in AVStreamInternal; or rather: Put AVStream at the
beginning of a new structure called FFStream (which encompasses
more than just the internal fields and is a proper context in its own
right, hence the name) and remove AVStreamInternal altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-17 13:22:25 +02:00
Andreas Rheinhardt 9f05b3ba60 avformat/mux, utils: Use dedicated pointer for AVStreamInternal
This gets rid of ugly "->internal" and is in preparation for removing
AVStreamInternal altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-17 13:02:35 +02:00
Andreas Rheinhardt fed0282508 avformat: Avoid allocation for AVFormatInternal
Do this by allocating AVFormatContext together with the data that is
currently in AVFormatInternal; or rather: Put AVFormatContext at the
beginning of a new structure called FFFormatContext (which encompasses
more than just the internal fields and is a proper context in its own
right, hence the name) and remove AVFormatInternal altogether.

The biggest simplifications occured in avformat_alloc_context(), where
one can now simply call avformat_free_context() in case of errors.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-17 04:58:34 +02:00
Andreas Rheinhardt dfbf41775c avformat/mux, mxfenc, utils: Use dedicated pointer for AVFormatInternal
This gets rid of ugly "->internal" and is in preparation for removing
AVFormatInternal altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-17 04:43:04 +02:00
Andreas Rheinhardt eaacb5c513 avformat/asfenc, mux, utils: Use smaller scope for variables
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-17 04:17:25 +02:00
Andreas Rheinhardt 2f710734c8 avformat/mux: Fix double-free when using AVPacket.opaque_ref
Up until now, ff_write_chained() copied the packet (manually, not with
av_packet_move_ref()) from a packet given to it to a stack packet whose
timing and stream_index is then modified before being sent to another
muxer via av_(interleaved_)write_frame(). Afterwards it is intended to
sync the fields of the packet relevant to freeing again; yet this only
encompasses buf, side_data and side_data_elems and not the newly added
opaque_ref. The other fields are not synced so that the returned packet
can have a size > 0 and data != NULL despite its buf being NULL (this
always happens in the interleaved codepath; before commit
fe251f77c8 it could also happen in the
noninterleaved one). This leads to double-frees if the interleaved
codepath is used and opaque_ref is set.

This commit therefore changes this by directly reusing the packet
instead of a spare packet. Given that av_write_frame() does not
change the packet given to it, one only needs to restore the timing
information to return it as it was; for the interleaved codepath
it is not possible to do likewise*, because av_interleaved_write_frame()
takes ownership of the packets given to it and returns blank packets.
But precisely because of this users of the interleaved codepath
have no legitimate expectation that their packet will be returned
unchanged. In line with av_interleaved_write_frame() ff_write_chained()
therefore returns blank packets when using the interleaved codepath.

Making the only user of said codepath compatible with this was trivial.

*: Unless one wanted to create a full new reference.

Reviewed-by: Lynne <dev@lynne.ee>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-09-03 19:23:18 +02:00
Andreas Rheinhardt bafb65ba2a avformat/mux: Don't access AVStream's internal AVCodecContext
An AVStream's internal AVCodecContext is pretty much unused for muxing:
The only place where any of its fields are set is
avformat_transfer_internal_stream_timing_info() where its time base is
set based upon the desired output format. The max_b_frames field is
never set at all, so don't read it in mux.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-08-30 16:12:22 +02:00
Andreas Rheinhardt 57b5ec6ba7 avcodec/avcodec: Stop including bsf.h in avcodec.h
Also include bsf.h directly wherever it is used.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2021-07-22 11:14:16 +02:00
James Almer 591b88e678 avformat: move AVStream.{first,cur}_dts to AVStreamInternal
They are private fields, no reason to have them exposed in a public header.

Signed-off-by: James Almer <jamrial@gmail.com>
2021-06-09 13:55:25 -03:00
James Almer 3749eede66 avformat: remove deprecated AVStream.codec
Signed-off-by: James Almer <jamrial@gmail.com>
2021-04-27 11:47:24 -03:00
Andreas Rheinhardt 30f7021aa0 avformat: Remove deprecated filename field from AVFormatContext
Deprecated in fa8308d3d4.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
2021-04-27 10:43:09 -03:00
Andreas Rheinhardt 56450a0ee4 avformat: Constify the API wrt AV(In|Out)putFormat
Also constify AVProbeData.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
2021-04-27 10:43:08 -03:00
Anton Khirnov 270ddc2baf lavf: postpone removal of FF_API_COMPUTE_PKT_FIELDS2
The infrastructure to fully handle generating timestamps e.g. for raw
video streamcopy is still not present.
2021-04-08 11:03:15 +02:00
James Almer 9066969713 avformat/mux: use av_packet_alloc() to allocate packets
Signed-off-by: James Almer <jamrial@gmail.com>
2021-03-17 15:06:48 -03:00
James Almer d422b2ed87 avcodec/packet_internal: make avpriv_packet_list_* functions use an internal struct
The next pointer is kept at the end for backwards compatability until the
major bump, when it should ideally be moved at the front.

Signed-off-by: James Almer <jamrial@gmail.com>
2021-03-17 14:12:17 -03:00
James Almer d5d6751a55 avformat/mux: return a pointer to the packet in ff_interleaved_peek()
And make it const, so the caller doesn't attempt to change it.
ff_get_muxer_ts_offset() should be used to get the muxer timestamp offset.

Signed-off-by: James Almer <jamrial@gmail.com>
2021-02-13 13:05:26 -03:00
James Almer 93e2fa933f avformat/mux: add ff_get_muxer_ts_offset()
Will be useful in the next patch

Signed-off-by: James Almer <jamrial@gmail.com>
2021-02-13 13:01:48 -03:00
Anton Khirnov 1c0885334d lavf/mux: rewrite guessing the packet duration
Factor out the code into a separate muxing-specific function.
Stop accessing the deprecated AVStream-embedded codec context, use the
average framerate (if specified) instead.
2020-12-10 09:50:18 +01:00
Anton Khirnov 744b7f2e91 lavf: move AVStream.last_in_packet_buffer to AVStreamInternal
Those are private fields, no reason to have them exposed in a public
header.
2020-10-28 15:01:40 +01:00
Anton Khirnov 91a98cc4ea lavf: move AVStream.pts_buffer to AVStreamInternal
Those are private fields, no reason to have them exposed in a public
header.
2020-10-28 15:00:40 +01:00
Anton Khirnov cea7c19cda lavf: move AVStream.*index_entries* to AVStreamInternal
Those are private fields, no reason to have them exposed in a public
header. Since there are some (semi-)public fields located after these,
even though this section is supposed to be private, keep some dummy
padding there until the next major bump to preserve ABI compatibility.
2020-10-28 14:59:28 +01:00
Anton Khirnov 7e87288f73 lavf: move AVStream.interleaver_chunk_* to AVStreamInternal
Those are private fields, no reason to have them exposed in a public
header.
2020-10-28 14:58:28 +01:00
Anton Khirnov cb46a6bcbc lavf: move AVStream.{nb_decoded_frames,mux_ts_offset} to AVStreamInternal
Those are private fields, no reason to have them exposed in a public
header.
2020-10-28 14:55:53 +01:00
Andreas Rheinhardt 06fdc82337 avformat/mux: Remove unnecessary unreferencing of AVPacket
Since commit c5324d92c5 all custom
interleave_packet() functions always return clean packets (even on
error), so that unreferencing manually can be removed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-23 05:43:42 +02:00
Andreas Rheinhardt 718f05f5e5 avformat/mux: Call check_packet() more directly
Call it directly from write_packets_common() instead of indirectly
through prepare_input_packet().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-16 02:55:59 +02:00
Andreas Rheinhardt 39195896f3 avformat/mux: Check pkt->stream_index before using it
This commit stops using pkt->stream_index as index in an AVFormatContext's
streams array before actually comparing the value with the count of
streams in said array. 96e5e6abb9 used
pkt->stream_index in prepare_input_packet() before checking and
6406351222 did likewise in
write_packets_common().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-16 02:40:23 +02:00
Marton Balint d7a0071a44 avformat/mux: add proper support for full N:M bitstream filtering
Previously only 1:1 bitstream filters were supported, the end of the stream was
not signalled to the bitstream filters and time base changes were ignored.

This change also allows muxers to set up bitstream filters regardless of the
autobsf flag during write_header instead of during check_bitstream and those
bitstream filters will always be executed.

Signed-off-by: Marton Balint <cus@passwd.hu>
2020-05-07 22:49:50 +02:00
Marton Balint 6406351222 avformat/mux: factorize writing a packet
In preparation for N:M bsf support.

Signed-off-by: Marton Balint <cus@passwd.hu>
2020-05-07 22:48:06 +02:00
Marton Balint c31ba86c37 avformat/mux: factorize interleaved write_packet
Signed-off-by: Marton Balint <cus@passwd.hu>
2020-05-07 22:41:24 +02:00
Marton Balint 7a8a5c200b avformat/mux: move interleaved packet functions upwards
Will be needed later to avoid a forward declaration.

Signed-off-by: Marton Balint <cus@passwd.hu>
2020-05-07 22:41:24 +02:00
Limin Wang 96e5e6abb9 avformat/mux: Set AV_PKT_FLAG_KEY for is_intra_only packet
The patch will make audio and subtitle packets be marked as AV_PKT_FLAG_KEY.

For audio, it'll caused the audio sample to be sync sample.
To verify ref/fate/movenc results:
1. Get the movenc test data
[lmwang@vpn ffmpeg]$ libavformat/tests/movenc -w && mkdir -p audio_old && mv *.mp4 audio_old_

After applied the patch:
[lmwang@vpn ffmpeg]$ make fate-movenc SAMPLES=../fate-suite
[lmwang@vpn ffmpeg]$ libavformat/tests/movenc -w && mkdir -p audio_key && mv *.mp4 audio_key

2. Get l-smash and build boxdumper
https://github.com/l-smash/l-smash.git

3. dump the box of crc change mp4 and diff -u
[lmwang@vpn ffmpeg]$ ../l-smash/cli/boxdumper --box audio_key/non-empty-moov-no-elst.mp4  > audio_key/non-empty-moov-no-elst.log
[lmwang@vpn ffmpeg]$ ../l-smash/cli/boxdumper --box audio_old/non-empty-moov-no-elst.mp4  > audio_old/non-empty-moov-no-elst.log
[lmwang@vpn ffmpeg]$ diff -u audio_key/non-empty-moov-no-elst.log audio_old/non-empty-moov-no-elst.log
-                default_sample_flags = 0x02000000
-                    independent
-                    sync sample
+                default_sample_flags = 0x01010000
+                    dependent
+                    non-sync sample

4. have checked the change of crc are caused by default_sample_flags
non-empty-moov.mp4, non-empty-moov-elst.mp4,
non-empty-moov-no-elst.mp4, empty-moov.mp4, delay-moov-content.mp4,
empty-moov-second-frag.mp4, empty-moov-second-frag-discont.mp4,
delay-moov-second-frag-discont.mp4, delay-moov-elst-second-frag.mp4
etc

5 For subtitle, it'll effect for tests/ref/fate/binsub-movtextenc and
tests/ref/fate/sub2video, that's expecting result for the subtitle is
marked as keyframe. Below is the checking result of binsub-movtextenc:

[lmwang@vpn ffmpeg]$ ./ffmpeg -i ../fate-suite/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -fflags +bitexact -movflags frag_keyframe+empty_moov audio_key/binsub-movtextenc.mp4
[lmwang@vpn ffmpeg]$ ./ffmpeg -i ../fate-suite/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -fflags +bitexact -movflags frag_keyframe+empty_moov audio_old/binsub-movtextenc.mp4
[lmwang@vpn ffmpeg]$../l-smash/cli/boxdumper audio_key/binsub-movtextenc.mp4  > audio_key/binsub-movtextenc.log
[lmwang@vpn ffmpeg]$../l-smash/cli/boxdumper audio_old/binsub-movtextenc.mp4  > audio_old/binsub-movtextenc.log
[lmwang@vpn ffmpeg]$ diff -u audio_key/binsub-movtextenc.log audio_old/binsub-movtextenc.log
.... // the key difference is the flag for sync sample
-                flags = 0x000701
+                flags = 0x000301
                     data-offset-present
                     sample-duration-present
                     sample-size-present
-                    sample-flags-present
                 sample_count = 6
-                data_offset = 188
+                data_offset = 164
                 sample[0]
                     sample_duration = 1570000
                     sample_size = 21
-                    sample_flags = 0x02000000
-                        independent
-                        sync sample
-                        degradation_priority = 0
                 sample[1]
                     sample_duration = 510000
                     sample_size = 2
-                    sample_flags = 0x01010000
-                        dependent
-                        non-sync sample
-                        degradation_priority = 0
                 sample[2]
                     sample_duration = 1690000
                     sample_size = 9
-                    sample_flags = 0x02000000
-                        independent
-                        sync sample
-                        degradation_priority = 0

Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Suggested-by: Nicolas George <george@nsup.org>
Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
2020-05-07 07:12:24 +08:00