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>
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>
This tests the issue from tickets #4536, #5784;
the output of this test is currently broken.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
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>
MOVAtom.type is always read as a little-endian number
(despite MOV/ISOBMFF being big-endian).
Fixes the matroska-dovi-write-config8 FATE-test on big-endian
arches (which runs into the "index out of range" warning message).
Reviewed-by: Martin Storsjö <martin@martin.st>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Add transform_skip option to hevc_qsv. By enabling this option,
the transform_skip_enabled_flag in PPS will be set to 1.
This option is supported on the platform equal or newer than ICL.
Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
Add low latency P-pyramid support to qsv. This feature relates to
command line option "-p_strategy". To enable this flag, user also
need to set "-bf" to 0. P-strategy has two modes "1-simple" and
"2-pyramid". The details of the two models refer to
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#preftype
Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
Add dblk_idc option to 264_qsv and hevc_qsv. Turining on this opion can
disable deblocking.
Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
Add max_frame_size support to hevc_qsv as well.
Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
According to the documentation, the ISOBMFF 'equi' box must
be present for equirectangular projections.
Reviewed-by: Hendrik Leppkes <h.leppkes@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Tests the parsing and writing of AVDOVIDecoderConfigurationRecord,
when it is present as a Dolby Vision configuration block addition mapping.
Signed-off-by: quietvoid <tcChlisop0@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This avoids copying the data in small chunks (1024B) into
the dynamic buffer's small buffer before finally writing them
into the "big" buffer.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Up until now, the WebM variant of WebVTT subtitles has been handled
specially: It had its own function to write it, because the data
had to be reformatted before writing. But given that other codecs
also need reformatting, this is no good reason to also duplicate the
generic stuff for writing Block(Group)s.
This commit therefore uses an ordinary reformatting function for
this task; writing WebVTT subtitles now uses the generic code
and therefore automatically uses the least amount of bytes
for its BlockGroup length fields whereas the earlier code used
an overestimation for the length of the Duration element.
This is the reason for the changes to the webm-webvtt-remux FATE-test.
(This commit does not implement support for Matroska's way of muxing
WebVTT; it also does not add checks to ensure that WebM-style subtitles
don't get muxed in Matroska. But the function for reformatting gets a
webm prefix to indicate that this is for WebM.)
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit uses the new EbmlWriter API to write the length fields
of the BlockGroup and its descendants that are themselves Master
elements (namely BlockAdditions and BlockMore) on the least amount of
bytes.
This fixes regressions introduced when the special code for writing
general subtitles was removed. Accordingly, the binsub-mksenc and
matroska-zero-length-block FATE-tests have now been reverted back
to their old state again; the advantages of this approach are evident
with the matroska-vp8-alpha-remux test which up until now wrote
all the length fields of all BlockGroups, BlockAdditions and BlockMore
on eight bytes.
Using the EbmlWriter API also allowed to improve locality in
mkv_write_block(): E.g. both DiscardPadding as well as the
BlockAdditional side-data are now directly used to add elements
to the writer whereas the earlier code had to first check
for whether a BlockGroup should be used and then check again
(after the place where a BlockGroup would be opened if one were
used) for whether there is DiscardPadding or BlockAdditional
side-data to write.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Add a field to mkv_track that is set to the offset instead
of checking for whether the track is ProRes when writing
the Block. This makes writing the Block independent
of the AVCodecParameters.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This e.g. stops recalculating ts again.
Also pass the AVFormatContext as pointer to void as it is only used
for logging.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Once upon a time, mkv_write_block() only wrote a (Simple)Block,
not a BlockGroup which is needed for subtitles to convey
the duration. But with the introduction of support for writing
BlockAdditions and DiscardPadding (both of which require a BlockGroup),
mkv_write_block() can also open and close a BlockGroup of its own. This
naturally led to some code duplication which is removed in this commit.
This new code leads to one regression: It always uses eight bytes for
the BlockGroup's length field, whereas the earlier code usually used the
lowest amount of bytes needed. This will be fixed in a future commit.
This temporary regression is also the reason for changes to the
binsub-mksenc and matroska-zero-length-block fate tests.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Do this by using the new NALUList API. This avoids an allocation
of a dynamic buffer per packet as well as the (re)allocation
of the actual buffer as well as copying the data around.
This improves performance: The time for one call to write_packet
decreased from 703501 to 357900 decicyles when remuxing a 5min
14000 kb/s H.264 transport stream.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This will allow to avoid the temporary buffer and memcpys
when repacketing annex B to mp4-style H.264/H.265 without
searching twice for start codes.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Matroska does not have different profiles that allow or disallow
in-band extradata, so one can just use the ordinary H.264 function
for H.265, too. (Both use ff_avc_parse_nal_units() internally anyway.)
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This avoids allocations+copies in all cases, not only those
in which the desired OBUs are contiguous in the input buffer.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Document that it can be used with a NULL AVIOContext to
get the output size in a first pass.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
WavPack's blocks use a length field, so that parsing them is fast.
Therefore it makes sense to parse the block twice, once to get
the length of the output packet and once to write the actual data
instead of writing the data into a temporary buffer in a single pass.
This speeds up muxing from 1597092 to 761850 Decicycles per
write_packet call for a 2000kb/s stereo WavPack file muxed to /dev/null
with writing CRC-32 disabled.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Matroska uses variable-length elements and in order not to waste
bytes on length fields, the length of the data to write needs to
be known before writing the length field. Annex B H.264/5 and
WavPack need to be reformatted to know this length and this
currently involves writing the data into temporary buffers;
AV1 sometimes suffers from this as well.
This commit aims to solve this by adding a callback that is called
twice per packet: Once to get the size and once to actually write
the data. In case of WavPack and AV1 (where parsing is cheap due
to length fields) both calls will just parse the data with only
the second function writing anything. For H.264/5, the position
of the NALUs will need to be stored to be written lateron.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Avoids the surprise of using pb for the main AVIOContext
at the beginning and end of mkv_write_header() and for
for the dynamic buffer opened for the Info element
in the middle of mkv_write_header().
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Using start/end_ebml_master() to write an EBML Master element
uses seeks under the hood. This does not work if the output is
unseekable with the AVIOContext's buffer being very small
(the size of the currently written Matroska EBML header is 40)
or with the AVIOContext being in direct mode, because then
this seek can't be performed in the AVIOContext's buffer.
So using an approach that does not rely on seeking at all
is preferable; this is achieved by switching to EbmlWriter.
Also factor writing the EBML header out into a function of its own.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Also check the (user-provided) tags for being overlong; the earlier
code had an implicit unchecked size_t->int conversion.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This muxer currently uses two ways to ensure that no bytes
are wasted by writing unnecessary long EBML length fields
for Master elements and the (Simple)Block element
(all the other elements are fine as one either already has
the right length or getting the actual length is easy
and necessary anyway):
Either use an upper bound that is good enough in case one
is available or write the data into a dynamic buffer first
to get the length; the former approach is impossible in
lots of cases, whereas the latter incurs allocations and
memcpying. It is therefore unfeasible to use the latter
for e.g. the attachments or the BlockGroups.
This patch adds a third alternative to complement the other two:
It consists of an EbmlWriter that one can add EBML elements to
that can be written later by calling ebml_writer_write();
the latter function first traverses the written elements recursively
and calculates the length of each element; then a second pass
is performed in which all the elements are written directly
(without any seeks).
This new API also performs checks for overlong elements;
this is in contrast to put_ebml_string() which simply performs
a size_t->int conversion even for strings originating from the user.
The new API is designed to have very low overhead: It uses
stack arrays and performs no allocations; this also comes
at a price: Right now, it can only be used in contexts in which
there is a compile-time upper bound for the number of elements.
It is also incompatible with storing the offset of an element
in order to update this field later. Furthermore, it puts
the onus of memory management (i.e. ensuring that pointers stay valid)
on the user.
These restrictions might be overcome in the future.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This would happen in case non-WebVTT-subtitles had BlockAdditional
or DiscardPadding side-data. Given that these are not accounted for
in the length of the outer BlockGroup (which is a quite sharp upper
bound) it is possible for the outer BlockGroup to use an insufficient
number of bytes which leads to an assert in end_ebml_master().
Fix this by not opening a second BlockGroup inside an already opened
BlockGroup.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
add a dictionary that maps "src_url" -> "expiry;dst_url", the dictionary
is checked before issuing an http request, and updated after getting a
3xx redirect response.
the cache expiry is determined according to the following (in desc
priority) -
1. Expires header
2. Cache-Control containing no-cache/no-store (disables caching)
3. Cache-Control s-maxage/max-age
4. Http codes 301/308 are cached indefinitely, other codes are not
cached
The SDK may insert picture timing SEI for hevc and the code to set mfx
parameter has been added in qsvenc, however the corresponding option is
missing in the hevc option array
Reviewed-by: Limin Wang <lance.lmwang@gmail.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This can fill VAProcPipelineParameterBuffer correctly and make the
pipeline works.
Reviewed-by: Soft Works <softworkz@hotmail.com>
Signed-off-by: Fei Wang <fei.w.wang@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
Overlay one video on the top of another.
It takes two inputs and has one output. The first input is the "main" video on
which the second input is overlaid. This filter requires same memory layout for
all the inputs.
An example command to use this filter to overlay overlay.mp4 at the top-left
corner of the main.mp4:
ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_device foo -hwaccel_output_format vaapi -c:v h264 -i main.mp4 \
-hwaccel vaapi -hwaccel_device foo -hwaccel_output_format vaapi -c:v h264 -i overlay.mp4 \
-filter_complex "[0:v][1:v]overlay_vaapi=0:0:100💯0.5[t1]" \
-map "[t1]" -an -c:v h264_vaapi -y out_vaapi.mp4
Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
Signed-off-by: Xinpeng Sun <xinpeng.sun@intel.com>
Signed-off-by: Zachary Zhou <zachary.zhou@intel.com>
Signed-off-by: Fei Wang <fei.w.wang@intel.com>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>