Commit Graph

1247 Commits

Author SHA1 Message Date
James Almer
fa961bb383 ffmpeg_mux_init: use strtoll() to parse stream and group indexes
Long is 32 bits signed on Windows, and nb_stream{s,_groups} are both unsigned
int. In a realistic scenario this wont make a difference, but it's still
proper.

Also ensure the parsed string is an integer while at it.

Signed-off-by: James Almer <jamrial@gmail.com>
2023-12-21 10:32:53 -03:00
Zhao Zhili
f72d781339 fftools/ffmpeg_enc: assert necessary frame fields before create encoder
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-12-21 19:30:25 +08:00
Zhao Zhili
42a4c59e59 fftools/ffmpeg_filter: remove semicolon after code block
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-12-21 19:30:11 +08:00
Zhao Zhili
7cd416792a fftools/ffmpeg_filter: fix NULL pointer dereference
In close_output(), a dummy frame is created with format NONE passed
to enc_open(), which isn't prepared for it. The NULL pointer
dereference happened at
av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth.

When fgt.graph is NULL, skip fg_output_frame() since there is
nothing to output.

frame #0: 0x0000005555bc34a4 ffmpeg_g`enc_open(opaque=0xb400007efe2db690, frame=0xb400007efe2d9f70) at ffmpeg_enc.c:235:44
frame #1: 0x0000005555bef250 ffmpeg_g`enc_open(sch=0xb400007dde2d4090, enc=0xb400007e4e2daad0, frame=0xb400007efe2d9f70) at ffmpeg_sched.c:1462:11
frame #2: 0x0000005555bee094 ffmpeg_g`send_to_enc(sch=0xb400007dde2d4090, enc=0xb400007e4e2daad0, frame=0xb400007efe2d9f70) at ffmpeg_sched.c:1571:19
frame #3: 0x0000005555bee01c ffmpeg_g`sch_filter_send(sch=0xb400007dde2d4090, fg_idx=0, out_idx=0, frame=0xb400007efe2d9f70) at ffmpeg_sched.c:2154:12
frame #4: 0x0000005555bcf124 ffmpeg_g`close_output(ofp=0xb400007e4e2d85b0, fgt=0x0000007d1790eb08) at ffmpeg_filter.c:2225:15
frame #5: 0x0000005555bcb000 ffmpeg_g`fg_output_frame(ofp=0xb400007e4e2d85b0, fgt=0x0000007d1790eb08, frame=0x0000000000000000) at ffmpeg_filter.c:2317:16
frame #6: 0x0000005555bc7e48 ffmpeg_g`filter_thread(arg=0xb400007eae2ce7a0) at ffmpeg_filter.c:2836:15
frame #7: 0x0000005555bee568 ffmpeg_g`task_wrapper(arg=0xb400007d8e2db478) at ffmpeg_sched.c:2200:21

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-12-21 19:29:53 +08:00
James Almer
ed670b9b98 ffmpeg: add support for muxing AVStreamGroups
Starting with IAMF support.

Signed-off-by: James Almer <jamrial@gmail.com>
2023-12-18 15:18:09 -03:00
Anton Khirnov
2ad0b8e0ea fftools/ffmpeg: use a mutex for enc_stats_write()
It may be called concurrently from different threads to write into the
same file.
2023-12-18 08:50:02 +01:00
Anton Khirnov
244d2fcc49 fftools/ffmpeg_mux: deduplicate uniniting EncStats 2023-12-18 08:50:02 +01:00
Anton Khirnov
02a4393647 fftools/ffmpeg: print keyframe information with -stats_* 2023-12-18 08:50:02 +01:00
Anton Khirnov
23c00d8c89 fftools/ffmpeg_mux_init: change 1-bit bitfields from int to unsigned
They cannot store 1 as signed, only 0 and -1.

Avoids warnings such as:
  implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Wsingle-bit-bitfield-constant-conversion]
2023-12-18 08:50:02 +01:00
Anton Khirnov
ca6f0192f2 fftools/cmdutils: change option flags to (1 << N) style
It is easier to read.
2023-12-18 08:50:02 +01:00
Anton Khirnov
7a7550ec28 fftools/ffmpeg_mux: factor timestamps processing out of write_packet() 2023-12-18 08:50:02 +01:00
Anton Khirnov
3dc319587f fftools/ffmpeg: deprecate -fps_mode/vsync drop
It depends on the ability of muxers to generate timestamps, which is
itself deprecated.
2023-12-18 08:50:02 +01:00
Anton Khirnov
8a11724a02 fftools/ffmpeg_mux: stop logging to AVFormatContext
Only the muxer itself is supposed to do that. Log to OutputStream
instead.

Drop now-redundant information from the logged string.
2023-12-18 08:50:02 +01:00
Anton Khirnov
5c5140ded2 fftools/ffmpeg_sched: track dts+duration as last_dts
This should be slightly (probably negligibly) more accurate for
scheduling, but mainly it improves the final reported time.

Reported-by: Paul B Mahol
2023-12-14 20:16:54 +01:00
Anton Khirnov
2305091a3a fftools/ffmpeg: update the reported timestamp at the end
Reported-by: microchip
2023-12-14 20:16:54 +01:00
Anton Khirnov
98d706b818 fftools/ffmpeg_sched: move trailing_dts() higher up
Will be useful in following commit.
2023-12-14 20:16:54 +01:00
Anton Khirnov
4549f20222 fftools/ffmpeg: drop OutputFile.sq_encode
It is unused since d119ae2fd8
2023-12-14 20:16:54 +01:00
Anton Khirnov
0d01e61807 fftools/ffmpeg_mux: move OutputStream.sq_idx_mux to private data
It should not be accessed outside of ffmpeg_mux*
2023-12-14 20:16:54 +01:00
Anton Khirnov
2c54097614 fftools/ffmpeg_demux: move InputFile.readrate to private data
It is not used outside of ffmpeg_demux.
2023-12-14 20:16:53 +01:00
Anton Khirnov
116bc5a9f3 fftools/ffmpeg: drop unused InputFile.eof_reached 2023-12-14 20:16:53 +01:00
Anton Khirnov
882bc8049d fftools/ffmpeg: move InputStream.codec_desc to private data
It is not used outside of ffmpeg_demux.
2023-12-14 20:16:53 +01:00
Anton Khirnov
9afe3f5274 fftools/ffmpeg: move InputStream.discard to private data
It is not used outside of ffmpeg_demux.
2023-12-14 20:16:53 +01:00
Anton Khirnov
4224895a87 fftools/ffmpeg: replace OutputStream.file_index by a pointer
Reduces the need to use the output_files global array.
2023-12-14 20:16:53 +01:00
Anton Khirnov
0fcea80b2a fftools/ffmpeg: replace InputStream.file_index by a pointer
Reduces the need to use the input_files global array.
2023-12-14 20:16:53 +01:00
Anton Khirnov
84201d8af6 fftools/ffmpeg_filter: move FilterGraph.graph to FilterGraphThread
The AVFilterGraph is fully owned by the filtering thread and should
never be accessed outside of it.
2023-12-14 20:16:53 +01:00
Anton Khirnov
06d5dc11db fftools/ffmpeg_sched: actually initialize/destroy schedule_lock 2023-12-14 10:16:39 +01:00
Anton Khirnov
5256b2fbe6 fftools/ffmpeg_mux: print latency information in -debug_ts muxing output 2023-12-14 08:11:05 +01:00
Anton Khirnov
9d7000b1be fftools/ffmpeg: attach wallclock timing information to packets and frames
Will become useful in following commits.
2023-12-14 08:11:05 +01:00
Anton Khirnov
c9f38210fc fftools/ffmpeg: merge DemuxPktData into FrameData
This way we can propagate arbitrary data from the demuxer all the way
into the muxer, using a single struct.
2023-12-14 08:11:05 +01:00
James Almer
7cc4b306eb ffmpeg_sched: initialize have_unchoked
Should fix valgrind warnings about Conditional jump or move depends on uninitialised value.

Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: James Almer <jamrial@gmail.com>
2023-12-12 16:10:28 -03:00
Anton Khirnov
d119ae2fd8 fftools/ffmpeg: convert to a threaded architecture
Change the main loop and every component (demuxers, decoders, filters,
encoders, muxers) to use the previously added transcode scheduler. Every
instance of every such component was already running in a separate
thread, but now they can actually run in parallel.

Changes the results of ffmpeg-fix_sub_duration_heartbeat - tested by
JEEB to be more correct and deterministic.
2023-12-12 08:24:18 +01:00
Anton Khirnov
9b8cc36ce0 fftools/ffmpeg: add thread-aware transcode scheduling infrastructure
See the comment block at the top of fftools/ffmpeg_sched.h for more
details on what this scheduler is for.

This commit adds the scheduling code itself, along with minimal
integration with the rest of the program:
* allocating and freeing the scheduler
* passing it throughout the call stack in order to register the
  individual components (demuxers/decoders/filtergraphs/encoders/muxers)
  with the scheduler

The scheduler is not actually used as of this commit, so it should not
result in any change in behavior. That will change in future commits.
2023-12-12 08:24:18 +01:00
Anton Khirnov
ee2a8cbfd1 fftools/ffmpeg_enc: move encoding to a separate thread
As for the analogous decoding change, this is only a preparatory step to
a fully threaded architecture and does not yet make encoding truly
parallel. The main thread will currently submit a frame and wait until
it has been fully processed by the encoder before moving on. That will
change in future commits after filters are moved to threads and a
thread-aware scheduler is added.

This code suffers from a known issue -  if an encoder with a sync queue
receives EOF it will terminate after processing everything it currently
has, even though the sync queue might still be triggered by other
threads. That will be fixed in following commits.
2023-12-12 08:24:18 +01:00
Anton Khirnov
66e78e9680 fftools/ffmpeg_demux: switch from AVThreadMessageQueue to ThreadQueue
* the code is made shorter and simpler
* avoids constantly allocating and freeing AVPackets, thanks to
  ThreadQueue integration with ObjPool
* is consistent with decoding/filtering/muxing
* reduces the diff in the future switch to thread-aware scheduling

This makes ifile_get_packet() always block. Any potential issues caused
by this will be resolved by the switch to thread-aware scheduling in
future commits.
2023-12-12 08:24:18 +01:00
Anton Khirnov
75efe530ce fftools/ffmpeg_mux: move bitstream filtering to the muxer thread
This will be the appropriate place for it after the rest of transcoding
is switched to a threaded architecture.
2023-12-12 08:24:18 +01:00
Anton Khirnov
1983507b6e fftools/ffmpeg_mux: add muxing thread private data
To be used for data that never needs to be visible outside of the muxer
thread. Start by moving the muxed AVPacket in there.
2023-12-12 08:24:18 +01:00
Anton Khirnov
f37a741f42 fftools/ffmpeg_filter: reindent 2023-12-12 08:24:18 +01:00
Anton Khirnov
40e1cf1cd2 fftools/ffmpeg_filter: buffer sub2video heartbeat frames like other frames
Otherwise they'd be silently ignored if received by the filtering thread
before the filtergraph can be initialized, which would make the output
dependent on the order in which frames from different inputs arrive.
2023-12-12 08:24:18 +01:00
Anton Khirnov
d35c05cb9e fftools/ffmpeg_filter: move filtering to a separate thread
As previously for decoding, this is merely "scaffolding" for moving to a
fully threaded architecture and does not yet make filtering truly
parallel - the main thread will currently wait for the filtering thread
to finish its work before continuing. That will change in future commits
after encoders are also moved to threads and a thread-aware scheduler is
added.
2023-12-12 08:24:18 +01:00
Anton Khirnov
4b8a171beb fftools/ffmpeg_filter: make sub2video heartbeat more robust
Avoid making decisions based on current graph input state, which makes
the output dependent on the order in which the frames from different
inputs are interleaved.

Makes the output of fate-filter-overlay-dvdsub-2397 more correct - the
subtitle appears two frames later, which is closer to its PTS as stored
in the file.
2023-12-12 08:24:18 +01:00
Anton Khirnov
99d2fa38ad fftools/ffmpeg: make sure FrameData is writable when we modify it
Also, add a function that returns const FrameData* for cases that only
read from it.
2023-12-06 10:30:28 +01:00
Anton Khirnov
1d536e0283 fftools/ffmpeg_filter: track input/output index in {Input,Output}FilterPriv
Will be useful in following commits.
2023-12-06 10:01:21 +01:00
Leo Izen
36980179a0 fftools/ffplay_renderer: declare function argument as const
Declaring the function argument as const fixes a warning down the line
that the const parameter is stripped. We don't modify this argument.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-27 23:39:48 +08:00
Zhao Zhili
a1a6a328f0 fftools/ffplay: add hwaccel decoding support
Add vulkan renderer via libplacebo.

Simple usage:
$ ffplay -hwaccel vulkan foo.mp4

Use cuda to vulkan map:
$ ffplay -hwaccel cuda foo.mp4

Create vulkan instance by libplacebo, and enable debug:
$ ffplay -hwaccel vulkan \
	-vulkan_params create_by_placebo=1:debug=1 foo.mp4

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-15 01:20:11 +08:00
Anton Khirnov
889a022cce fftools/ffmpeg: rework keeping track of file duration for -stream_loop
Current code tracks min/max pts for each stream separately; then when
the file ends it combines them with last frame's duration to compute the
total duration of each stream; finally it selects the longest of those
durations as the file duration.

This is incorrect - the total file duration is the largest timestamp
difference between any frames, regardless of the stream.

Also change the way the last frame information is reported from decoders
to the muxer - previously it would be just the last frame's duration,
now the end timestamp is sent, which is simpler.

Changes the result of the fate-ffmpeg-streamloop-transcode-av test,
where the timestamps are shifted slightly forward. Note that the
matroska demuxer does not return the first audio packet after seeking
(due to buggy interaction betwen the generic code and the demuxer), so
there is a gap in audio.
2023-11-14 18:18:26 +01:00
Anton Khirnov
87016e031f fftools/thread_queue: count receive-finished streams as finished
This ensures that tq_receive() will always return EOF after all streams
were receive-finished, even though the sending side might not have
closed them yet. This may allow the receiver to avoid manually tracking
which streams it has already closed.
2023-11-14 18:18:26 +01:00
Anton Khirnov
4f7b91a698 fftools/thread_queue: do not return elements for receive-finished streams
It does not cause any issues in current callers, but still should not
happen.
2023-11-14 18:18:26 +01:00
Anton Khirnov
7c97a0c63f fftools/ffmpeg: move a few inline function into a new header
Will allow to use them in future commits without including the whole
ffmpeg.h.
2023-11-14 18:18:26 +01:00
Anton Khirnov
26ebd96371 fftools/ffmpeg_filter: return an error on ofilter_alloc() failure 2023-11-09 11:25:17 +01:00
Anton Khirnov
5db07311a0 fftools/ffmpeg_filter: fail on ifilter_alloc() failure 2023-11-09 11:25:17 +01:00