This implementation is based on D3D12 Video Encoding Spec:
https://microsoft.github.io/DirectX-Specs/d3d/D3D12VideoEncoding.html
Sample command line for transcoding:
ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4
-c:v hevc_d3d12va output.mp4
Signed-off-by: Tong Wu <tong1.wu@intel.com>
Move receive_packet function to base. This requires adding *alloc,
*issue, *output, *free as hardware callbacks. HWBaseEncodePicture is
introduced as the base layer structure. The related parameters in
VAAPIEncodeContext are also extracted to HWBaseEncodeContext. Then DPB
management logic can be fully extracted to base layer as-is.
Signed-off-by: Tong Wu <tong1.wu@intel.com>
Add external encoder VVenC for H266/VVC encoding.
Register new encoder libvvenc.
Add libvvenc to wrap the vvenc interface.
libvvenc implements encoder option: preset,qp,qpa,period,
passlogfile,stats,vvenc-params,level,tier.
Enable encoder by adding --enable-libvvenc in configure step.
Co-authored-by: Christian Bartnik chris10317h5@gmail.com
Signed-off-by: Thomas Siedel <thomas.ff@spin-digital.com>
If any of these files (say A) would be changed in such a way
that A acquires a new dependency on another file B, building B
would need to be added to all the rules that lead to A being built.
Yet currently the rules for several files are spread over
the lavc Makefile and the Makefile of the lavc/hevc subdir, making
it more likely to be forgotten. So move the rules for these files
to the lavc/Makefile.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Forgotten in d1d30edf42.
This fixes standalone compilation of the VC-1 based
decoders when using shared builds (for static builds,
nothing pulls in msmpeg4data.o, yet for shared builds
the default behaviour of linkers is different, leading
to undefined references because msmpeg4data.o relies
on stuff from mpeg4video.o).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
We need to set up the configuration struct appropriately based on the
codec type, colorspace metadata, and presence/absence of an EL (though,
we currently don't support an EL).
When present, we use the signalled RPU data header to help infer (and
validate) the right values.
Behavior can be controlled by a new DOVIContext.enable flag.
To allow compiling the decoding objects without the encoding objects and
vice versa. Common helpers that users of both APIs need are put into the
shared dovi_rpu.c.
Frame-threaded decoders with inter-frame dependencies
use the ThreadFrame API for syncing. It works as follows:
During init each thread allocates an AVFrame for every
ThreadFrame.
Thread A reads the header of its packet and allocates
a buffer for an AVFrame with ff_thread_get_ext_buffer()
(which also allocates a small structure that is shared
with other references to this frame) and sets its fields,
including side data. Then said thread calls ff_thread_finish_setup().
From that moment onward it is not allowed to change any
of the AVFrame fields at all any more, but it may change
fields which are an indirection away, like the content of
AVFrame.data or already existing side data.
After thread A has called ff_thread_finish_setup(),
another thread (the user one) calls the codec's update_thread_context
callback which in turn calls ff_thread_ref_frame() which
calls av_frame_ref() which reads every field of A's
AVFrame; hence the above restriction on modifications
of the AVFrame (as any modification of the AVFrame by A after
ff_thread_finish_setup() would be a data race). Of course,
this av_frame_ref() also incurs allocations and therefore
needs to be checked. ff_thread_ref_frame() also references
the small structure used for communicating progress.
This av_frame_ref() makes it awkward to propagate values that
only become known during decoding to later threads (in case of
frame reordering or other mechanisms of delayed output (like
show-existing-frames) it's not the decoding thread, but a later
thread that returns the AVFrame). E.g. for VP9 when exporting video
encoding parameters as side data the number of blocks only
becomes known during decoding, so one can't allocate the side data
before ff_thread_finish_setup(). It is currently being done afterwards
and this leads to a data race in the vp9-encparams test when using
frame-threading. Returning decode_error_flags is also complicated
by this.
To perform this exchange a buffer shared between the references
is needed (notice that simply giving the later threads a pointer
to the original AVFrame does not work, because said AVFrame will
be reused lateron when thread A decodes the next packet given to it).
One could extend the buffer already used for progress for this
or use a new one (requiring yet another allocation), yet both
of these approaches have the drawback of being unnatural, ugly
and requiring quite a lot of ad-hoc code. E.g. in case of the VP9
side data mentioned above one could not simply use the helper
that allocates and adds the side data to an AVFrame in one go.
The ProgressFrame API meanwhile offers a different solution to all
of this. It is based around the idea that the most natural
shared object for sharing information about an AVFrame between
decoding threads is the AVFrame itself. To actually implement this
the AVFrame needs to be reference counted. This is achieved by
putting a (ownership) pointer into a shared (and opaque) structure
that is managed by the RefStruct API and which also contains
the stuff necessary for progress reporting.
The users get a pointer to this AVFrame with the understanding
that the owner may set all the fields until it has indicated
that it has finished decoding this AVFrame; then the users are
allowed to read everything. Every decoder may of course employ
a different contract than the one outlined above.
Given that there is no underlying av_frame_ref(), creating
references to a ProgressFrame can't fail. Only
ff_thread_progress_get_buffer() can fail, but given that
it will replace calls to ff_thread_get_ext_buffer() it is
at places where errors are already expected and properly
taken care of.
The ProgressFrames are empty (i.e. the AVFrame pointer is NULL
and the AVFrames are not allocated during init at all)
while not being in use; ff_thread_progress_get_buffer() both
sets up the actual ProgressFrame and already calls
ff_thread_get_buffer(). So instead of checking for
ThreadFrame.f->data[0] or ThreadFrame.f->buf[0] being NULL
for "this reference frame is non-existing" one should check for
ProgressFrame.f.
This also implies that one can only set AVFrame properties
after having allocated the buffer. This restriction is not deep:
if it becomes onerous for any codec, ff_thread_progress_get_buffer()
can be broken up. The user would then have to get a buffer
himself.
In order to avoid unnecessary allocations, the shared structure
is pooled, so that both the structure as well as the AVFrame
itself are reused. This means that there won't be lots of
unnecessary allocations in case of non-frame-threaded decoding.
It might even turn out to have fewer than the current code
(the current code allocates AVFrames for every DPB slot, but
these are often excessively large and not completely used;
the new code allocates them on demand). Pooling relies on the
reset function of the RefStruct pool API, it would be impossible
to implement with the AVBufferPool API.
Finally, ProgressFrames have no notion of owner; they are built
on top of the ThreadProgress API which also lacks such a concept.
Instead every ThreadProgress and every ProgressFrame contains
its own mutex and condition variable, making it completely independent
of pthread_frame.c. Just like the ThreadFrame API it is simply
presumed that only the actual owner/producer of a frame reports
progress on said frame.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Use SHLIBOBJS and STLIBOBJS in the Makefiles for avcodec and avformat,
and add a stub ffjni.c to libavformat, which allows the symbols to be
duplicated for shared builds but not static builds.
Signed-off-by: Leo Izen <leo.izen@gmail.com>
Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
The LC3 audio codec is the default codec of Bluetooth LE audio.
This is a wrapper over the liblc3 library (https://github.com/google/liblc3).
Signed-off-by: Antoine Soulier <asoulier@google.com>
Once upon a time, there used to be a LGPL and a GPL ProRes decoder
in FFmpeg; the current decoder evolved from the second of these.
But given that it is now the only ProRes decoder we have, it's file
should simply be named proresdec.c (which also brings it in line with
its header).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
hevc_data.c only provides ff_hevc_diag_scan tables and
neither the QSV HEVC encoder nor the HEVC parser use these
directly and the indirect dependency is already accounted
for in the dependencies of the hevcparse subsystem since
b0c61209cd, so remove these
spurious dependencies.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This currently builds files in the libavcodec/x86/{vvc,h26x}
subdirectories, which is somewhat unexpected when building for
another architecture than x86.
The regular arch subdirectories are handled with
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
in the toplevel Makefile. Switch this to a similar optional
inclusion, using $(ARCH).
Signed-off-by: Martin Storsjö <martin@martin.st>
It is only used by hq_hqa.c, so said header can simply
be included there.
Also move the code to initialize the VLCs to hq_hqa.c.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This BSF is supposed to be used in conjunction with mp3_header_compress,
which has been removed more than ten years ago in commit
c6080d8900. It mangled the headers
by removing the CRC field as well as fields that are supposed
to stay constant for the entirety of a stream (which are put into
extradata). This made these files unplayable; they need to be
decompressed with the BSF first (which does not happen automatically).
Even in this case the CRC does not get restored.
I am not aware that such compressed files exist at all; therefore
this commit removes the BSF completely.
Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This together with adjusting the inclusion define allows for the
build to not fail with latest Vulkan-Headers that contain the
stabilized Vulkan AV1 decoding definitions.
Compilation fails currently as the AV1 header is getting included
via hwcontext_vulkan.h -> <vulkan/vulkan.h> -> vulkan_core.h, which
finally includes vk_video/vulkan_video_codec_av1std.h and the decode
header, leading to the bundled header to never defining anything
due to the inclusion define being the same.
This fix is imperfect, as it leads to additional re-definition
warnings for things such as
VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION. , but it is
not clear how to otherwise have the bundled version trump the
actually standardized one for a short-term compilation fix.
The implementation is based on:
https://learn.microsoft.com/en-us/windows/win32/medfound/direct3d-12-video-overview
With the Direct3D 12 video decoding support, we can render or process
the decoded images by the pixel shaders or compute shaders directly
without the extra copy overhead, which is beneficial especially if you
are trying to render or post-process a 4K or 8K video.
The command below is how to enable d3d12va:
ffmpeg -hwaccel d3d12va -i input.mp4 output.mp4
Signed-off-by: Wu Jianhua <toqsxw@outlook.com>
Signed-off-by: Tong Wu <tong1.wu@intel.com>
This commit adds support for VP8 bitstream read methods to the cbs
codec. This enables the trace_headers bitstream filter to support VP8,
in addition to AV1, H.264, H.265, and VP9. This can be useful for
debugging VP8 stream issues.
The CBS VP8 implements a simple VP8 boolean decoder using GetBitContext
to read the bitstream.
Only the read methods `read_unit` and `split_fragment` are implemented.
The write methods `write_unit` and `assemble_fragment` return the error
code AVERROR_PATCHWELCOME. This is because CBS VP8 write is unlikely to
be used by any applications at the moment. The write methods can be
added later if there is a real need for them.
TESTS: ffmpeg -i fate-suite/vp8/frame_size_change.webm -vcodec copy
-bsf:v trace_headers -f null -
Signed-off-by: Jianhui Dai <jianhui.j.dai@intel.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Partially fixes ticket #798
Reviewed-by: James Almer <jamrial@gmail.com>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Peter Ross <pross@xvid.org>
For now, this API is supposed to replace all the internal uses
of reference counted objects in libavcodec; "internal" here
means that the object is created in libavcodec and is never
put directly in the hands of anyone outside of it.
It is intended to be made public eventually, but for now
I enjoy the ability to modify it freely.
Several shortcomings of the AVBuffer API motivated this API:
a) The unnecessary allocations (and ensuing error checks)
when using the API. Besides the need for runtime checks it
imposes upon the developer the burden of thinking through
what happens in case an error happens. Furthermore, these
error paths are typically not covered by FATE.
b) The AVBuffer API is designed with buffers and not with
objects in mind: The type for the actual buffers used
is uint8_t*; it pretends to be able to make buffers
writable, but this is wrong in case the buffer is not a POD.
Another instance of this thinking is the lack of a reset
callback in the AVBufferPool API.
c) The AVBuffer API incurs unnecessary indirections by
going through the AVBufferRef.data pointer. In case the user
tries to avoid this indirection and stores a pointer to
AVBuffer.data separately (which also allows to use the correct
type), the user has to keep these two pointers in sync
in case they can change (and in any case has two pointers
occupying space in the containing context). See the following
commit using this API for H.264 parameter sets for an example
of the removal of such syncing code as well as the casts
involved in the parts where only the AVBufferRef* pointer
was stored.
d) Given that the AVBuffer API allows custom allocators,
creating refcounted objects with dedicated free functions
often involves a lot of boilerplate like this:
obj = av_mallocz(sizeof(*obj));
ref = av_buffer_create((uint8_t*)obj, sizeof(*obj), free_func, opaque, 0);
if (!ref) {
av_free(obj);
return AVERROR(ENOMEM);
}
(There is also a corresponding av_free() at the end of free_func().)
This is now just
obj = ff_refstruct_alloc_ext(sizeof(*obj), 0, opaque, free_func);
if (!obj)
return AVERROR(ENOMEM);
See the subsequent patch for the framepool (i.e. get_buffer.c)
for an example.
This API does things differently; it is designed to be lightweight*
as well as geared to the common case where the allocator of the
underlying object does not matter as long as it is big enough and
suitably aligned. This allows to allocate the user data together
with the API's bookkeeping data which avoids an allocation as well
as the need for separate pointers to the user data and the API's
bookkeeping data. This entails that the actual allocation of the
object is performed by RefStruct, not the user. This is responsible
for avoiding the boilerplate code mentioned in d).
As a downside, custom allocators are not supported, but it will
become apparent in subsequent commits that there are enough
usecases to make it worthwhile.
Another advantage of this API is that one only needs to include
the relevant header if one uses the API and not when one includes
the header or some other component that uses it. This is because there
is no RefStruct type analog of AVBufferRef. This brings with it
one further downside: It is not apparent from the pointer itself
whether the underlying object is managed by the RefStruct API
or whether this pointer is a reference to it (or merely a pointer
to it).
Finally, this API supports const-qualified opaque pointees;
this will allow to avoid casting const away by the CBS code.
*: Basically the only exception to the you-only-pay-for-what-you-use
rule is that it always uses atomics for the refcount.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>