Commit Graph

81 Commits

Author SHA1 Message Date
Anton Khirnov 33f058f2ec fftools/ffmpeg_enc: constify the frame passed to enc_open() 2023-10-10 12:41:31 +02:00
Anton Khirnov 9196be2fb1 fftools/ffmpeg_enc: move fps conversion code to ffmpeg_filter
Its function is analogous to that of the fps filter, so filtering is a
more appropriate place for this.

The main practical reason for this move is that it places the encoding
sync queue right at the boundary between filters and encoders. This will
be important when switching to threaded scheduling, as the sync queue
involves multiple streams and will thus need to do nontrivial
inter-thread synchronization.

In addition to framerate conversion, the closely-related
* encoder timebase selection
* applying the start_time offset
are also moved to filtering.
2023-10-10 12:41:31 +02:00
Anton Khirnov f0f6d6d0e1 fftools/ffmpeg_enc: move framerate conversion state into a separate struct
Makes it more clear what state is specific to framerate conversion,
which will be useful in the following commit.
2023-10-10 12:41:31 +02:00
Anton Khirnov 61777c62d7 fftools/ffmpeg: stop accessing OutputStream.last_dropped in print_report()
That field is used by the framerate code to track whether any output has
been generated for the last input frame(*). Its use in the last
invocation of print_report() is meant to account for the very last
filtered frame being dropped in the number of dropped frames printed in
the log. However, that is a highly inappropriate place to do so, as it
makes assumptions about vsync logic in completely unrelated code. Move
the increment to encoder flush instead.

(*) the name is misleading, as the input frame has not yet been dropped
    and may still be output in the future
2023-10-10 12:41:31 +02:00
Anton Khirnov d2c416fdf1 fftools/ffmpeg_enc: merge -force_key_frames source/source_no_drop
Always use the functionality of the latter, which makes more sense as it
avoids losing keyframes due to vsync code dropping frames.

Deprecate the 'source_no_drop' value, as it is now redundant.
2023-10-10 12:41:31 +02:00
Anton Khirnov 735b082231 fftools/ffmpeg_enc: unbreak -force_key_frames source_no_drop
Unlike the 'source' mode, which preserves source keyframe-marking as-is,
the 'source_no_drop' mode attempts to keep track of keyframes dropped by
framerate conversion and mark the next output frame as key in such
cases. However,
* c75be06148 broke this functionality entirely, and made it equivalent
  to 'source'
* even before it would only work when the frame immediately following
  the dropped keyframe is preserved and not dropped as well

Also, drop a redundant check for 'frame' in setting dropped_keyframe, as
it is redundant with the check on the above line.
2023-10-10 12:41:31 +02:00
Anton Khirnov 99567ee870 fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature
It does not need an OutputFile and an OutputStream, only the target
timebase and the timestamp offset.
2023-10-10 12:41:31 +02:00
Anton Khirnov 096d88dcc6 fftools/ffmpeg_enc: move remaining vsync-related code to video_sync_process() 2023-10-10 12:41:31 +02:00
Anton Khirnov a9b9e771b3 fftools/ffmpeg_enc: move handling video frame duration to video_sync_process()
That is a more appropriate place for this.
2023-10-10 12:41:31 +02:00
James Almer 3fd37b5268 fftools/ffmpeg: stop using AVStream.side_data
Signed-off-by: James Almer <jamrial@gmail.com>
2023-10-06 10:11:00 -03:00
Anton Khirnov 8d12762b42 fftools/ffmpeg: move derivation of frame duration from filter framerate
From ffmpeg_enc to ffmpeg_filter, which is a more appropriate
place for it.
2023-10-03 16:57:02 +02:00
Anton Khirnov 9d4ca76c08 fftools/ffmpeg_enc: do not round frame durations prematurely
Changes the results of fate-idroq-video-encode and fate-lavf* tests,
where different frames now get duplicated by framerate conversion code.
2023-10-03 16:57:02 +02:00
Anton Khirnov 5d58a35f98 fftools/ffmpeg: deprecate the -top option
It is badly named (should have been -top_field_first, or at least -tff),
underdocumented and underspecified, and (most importantly) entirely
redundant with the setfield filter.
2023-09-18 17:16:06 +02:00
Anton Khirnov 43a0004b5c fftools/ffmpeg_enc: apply -top to individual encoded frames
Fixes #9339.
2023-09-18 17:15:53 +02:00
Anton Khirnov 74b643a51e fftools/ffmpeg_enc: refactor setting encoding field_order
Merge three blocks with slightly inconsistent checks into one, treating
encoder input as interlaced when either:
* at least one of ilme/ildct flags is set
* the first frame in the stream is marked as interlaced
* the user specified the -top option

Stop modifying the frame passed to enc_open().
2023-09-18 17:15:53 +02:00
Anton Khirnov d65d0f4df1 fftools/ffmpeg_enc: reindent after previous commit 2023-08-30 11:53:50 +02:00
Anton Khirnov 411ada649f fftools/ffmpeg_enc: only use fallback framerate when encoding CFR
When no output video framerate is specified by the user with -r or can
be inferred from the filtergraph, encoder setup will arbitrarily decide
that the framerate is 25fps. However, making up any framerate value for
VFR encoding is at best unnecessary.

Changes the results of the sub2video tests, where the input timebase is
now used instead of 1/25.
2023-08-30 11:53:50 +02:00
Anton Khirnov 8b6b2518fa fftools/ffmpeg_enc: reindent after previous commit 2023-08-30 11:53:50 +02:00
Anton Khirnov d1a2cd1e13 fftools/ffmpeg_enc: factor out setting encoder timebase
Mainly this fixes handling special values of -enc_time_base ('demux' or
'filter') for audio. It also prints a warning if -enc_time_base is
specified for subtitles, instead of ignoring it silently (current
subtitle encoding API only works with AV_TIME_BASE_Q).
2023-08-30 11:53:50 +02:00
Anton Khirnov 8ecbb1f9af fftools/ffmpeg_mux: stop rescaling timestamps in of_streamcopy()
This function converts packet timestamps from the input stream timebase
to OutputStream.mux_timebase, which may or may not be equal to the
actual output AVStream timebase (and even when it is, this may not
always be the optimal choice due to bitstream filtering).

Just keep the timestamps in input stream timebase, they will be rescaled
as needed before bitstream filtering and/or sending the packet to the
muxer.

Move the av_rescale_delta() call for audio (needed to preserve accuracy
with coarse demuxer timebases) to write_packet.

Drop now-unused OutputStream.mux_timebase.
2023-08-30 11:53:46 +02:00
Anton Khirnov 2f155b18a1 fftools/ffmpeg: return an error from assert_avoptions() instead of aborting
Rename it to check_avoptions().
2023-07-20 20:47:46 +02:00
Anton Khirnov e0f4259689 fftools/ffmpeg_mux: return errors from of_output_packet() instead of aborting 2023-07-20 20:30:13 +02:00
Anton Khirnov 2b4afe8169 fftools/ffmpeg_enc: return errors from encode_frame() instead of aborting 2023-07-20 20:30:13 +02:00
Anton Khirnov 43bcf631d0 fftools/ffmpeg_enc: return errors from enc_flush() instead of aborting 2023-07-20 20:30:13 +02:00
Anton Khirnov dde3de0170 fftools/ffmpeg_enc: return errors from do_*_out() instead of aborting 2023-07-20 20:30:13 +02:00
Anton Khirnov aa1173feee fftools/ffmpeg_enc: return errors from enc_open() instead of aborting 2023-07-20 20:30:13 +02:00
Anton Khirnov 80a64800ea fftools/ffmpeg_enc: return errors from enc_frame() instead of aborting 2023-07-20 20:30:13 +02:00
Andreas Rheinhardt 463a472426 fftools/ffmpeg_enc: Reindentate after the last commit
Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-07-17 16:18:12 +02:00
Andreas Rheinhardt bfe15b81b3 fftools/ffmpeg_enc: Remove always-true checks
frame is always != NULL for audio and video here
(this is checked by an assert and the frame is already dereferenced
before it reaches this code here).
Fixes Coverity issue #1538858.

Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-07-17 16:14:41 +02:00
Anton Khirnov dff3a283cd fftools/ffmpeg: rework -enc_time_base handling
Read the timebase from FrameData rather than the input stream. This
should fix #10393 and generally be more reliable.

Replace the use of '-1' to indicate demuxing timebase with the string
'demux'. Also allow to request filter timebase with
'-enc_time_base filter'.
2023-07-15 11:02:11 +02:00
Anton Khirnov 4d06742b93 fftools/ffmpeg: add more structure to FrameData
It now contains data from multiple sources, so group those items that
always come from the decoder. Also, initialize them to invalid values,
so that frames that did not originate from a decoder can be
distinguished.
2023-07-15 11:02:11 +02:00
Anton Khirnov 9a97f9cf3a fftools/ffmpeg_enc: initialize audio/video encoders from frame parameters
This is possible now that enc_open() is always called with a non-NULL
frame for audio/video.

Previously the code would directly reach into the buffersink, which is a
layering violation.
2023-07-15 11:02:11 +02:00
Anton Khirnov 0a6751a78a fftools/ffmpeg: rework initializing encoders with no frames
When no frames were passed from a filtergraph to an encoder, but the
filtergraph is configured (i.e. has output parameters), encoder flush
code will use those parameters to initialize the encoder in a last-ditch
effort to produce some useful output.

Rework this process so that it is triggered by the filtergraph, which
now sends a dummy frame with parameters, but no data, to the encoder,
rather than the encoder reaching backwards into the filter.

This approach is more in line with the natural data flow from filters to
encoders and will allow to reduce encoder-filter interactions in
following commits.

This code is tested by fate-adpcm-ima-cunning-trunc-t2-track1, which (as
confirmed by Zane) is supposed to produce empty output.
2023-07-15 11:02:11 +02:00
Anton Khirnov c328bff4da fftools/ffmpeg_enc: return errors from enc_subtitle() instead of aborting 2023-07-15 11:02:11 +02:00
Anton Khirnov fa717baaa5 fftools/ffmpeg_enc: constify the subtitle passed to enc_subtitle() 2023-06-19 09:48:56 +02:00
Anton Khirnov 5293adb1a7 fftools/ffmpeg: attach bits_per_raw_sample information to frames
This way avoids encoders reaching into filters or decoders for this
information.
2023-06-19 09:48:55 +02:00
Anton Khirnov a934392db0 fftools/ffmpeg_enc: move dup_warning global variable to Encoder 2023-06-19 09:48:55 +02:00
Anton Khirnov 730a2221af fftools/ffmpeg_enc: use a private AVPacket instance for encoding
The code currently uses OutputStream.pkt, which complicates its
ownership semantics.
2023-06-05 16:16:12 +02:00
Anton Khirnov f94957e8f4 fftools/ffmpeg_mux: simplify calling of_output_packet()
Use NULL packets to signal EOF instead of a separate variable. This is
made possible by the previous commit.
2023-06-05 16:16:12 +02:00
Anton Khirnov c803b36b8f fftools/ffmpeg_enc: stop using OutputStream.initialized
It is set by the muxing code, which will not be synchronized with
encoding code after upcoming threading changes. Use an encoder-private
variable instead.
2023-06-05 16:15:04 +02:00
Anton Khirnov 568d414074 fftools/ffmpeg: attach filter framerate to frames
This way the encoder does not need to reach backward into the filter.
2023-06-05 16:15:04 +02:00
Anton Khirnov d7781cfb95 fftools/ffmpeg: convert timestamps inside the muxer
Packets submitted to the muxer now have their timebase attached to them,
so the muxer can do conversion to muxing timebase and avoid exposing it
to callers.
2023-06-05 16:15:04 +02:00
Anton Khirnov cf121592c5 fftools/ffmpeg_mux_init: do not overwrite OutputStream.frame_rate for encoding
The values currently written into it are not used after
enc_open(), so it is better to confine them to that function.
2023-06-05 16:15:04 +02:00
Anton Khirnov 5bea8daa78 fftools/ffmpeg_enc: do not guess frame durations from output framerate
There is no reason to expect input frame durations to match output
framerate.
2023-06-05 16:15:04 +02:00
Anton Khirnov 2f92650c5d fftools/ffmpeg_enc: inline init_encoder_time_base() into its callers
The function now reduces to a ternary operator, so it is shorter and
clearer to eliminate it.
2023-06-05 16:15:04 +02:00
Anton Khirnov 93e26a4db7 fftools/ffmpeg: handle -enc_time_base -1 during stream creation
There is no reason to postpone it until opening the encoder. Also, abort
when the input stream is unknown, rather than disregard an explicit
request from the user.
2023-06-05 16:15:04 +02:00
Anton Khirnov 2baae6434b fftools/ffmpeg_enc: merge two adjacent video-specific blocks
There is no meaningful reason for them to be separated.
2023-06-05 16:15:04 +02:00
Anton Khirnov ccf219e361 fftools/ffmpeg_enc: avoid breaking exactly integer timestamps in vsync code
The code will currently add a small offset to avoid exact midpoints, but
this can cause inexact results when a float timestamp is exactly
representable as an integer.

Fixes off-by-one in the first frame duration in multiple FATE tests.
2023-06-05 16:15:04 +02:00
Anton Khirnov 57021a68d9 fftools/ffmpeg_mux: set stream duration after the timebase is certainly known
Stop assuming the encoder knows the muxing timebase, which does not
always have to hold (e.g. due to bitstream filters).
2023-06-05 16:15:04 +02:00
Anton Khirnov ba1141d8a9 fftools/ffmpeg_enc: move nb_frames{dup,drop} globals into OutputStream 2023-06-05 16:15:04 +02:00