1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00
Commit Graph

660 Commits

Author SHA1 Message Date
Andreas Rheinhardt
6de6ce7bc8 avformat/matroskaenc: Don't use NULL for %s format string
The argument pertaining to a printf %s conversion specifier must not
be NULL, even if the precision (i.e. the number of characters to write)
is zero. If it is NULL, it is undefined behaviour.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-06-15 16:54:06 +02:00
Andreas Rheinhardt
a5572f5a80 avformat/matroskaenc: Forward errors from avpriv_split_xiph_headers()
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-23 07:10:56 +02:00
Andreas Rheinhardt
72baae1395 avformat/matroskaenc: Remove pointless casts
by using a const void * pointer as an intermediate.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-22 06:33:25 +02:00
Andreas Rheinhardt
68dd1e6a57 avformat/matroskaenc: Don't use stream side-data size
av_stream_get_side_data() tells the caller whether a stream has side
data of a specific type; if present it can also tell the caller the size
of the side data via an optional argument. The Matroska muxer always
used this optional argument, although it doesn't really need the size,
as the relevant side-data are not buffers, but structures. So change
this.

Furthermore, relying on the size also made the code susceptible to
a quirk of av_stream_get_side_data(): It only sets the size argument if
it found side data of the desired type. mkv_write_video_color() checks
for side-data twice with the same variable for the size without resetting
the size in between; if the second type of side-data isn't present, the
size will still be what it was after the first call. This was not
dangerous in practice, as the check for the existence of the second
side-data compared the size with the expected size, so it would only be
problematic if lots of elements were to be added to AVContentLightMetadata.

Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-22 06:30:56 +02:00
Andreas Rheinhardt
4ebfc13c33 avformat/matroskaenc: Don't ignore tags of chapters written late
The Matroska muxer writes the Chapters early when chapters were already
available when writing the header; in this case any tags pertaining to
these chapters get written, too.

Yet if no chapters had been supplied before writing the header, Chapters
can also be written when writing the trailer if any are supplied. Tags
belonging to these chapters were up until now completely ignored.

This commit changes this: Writing the tags belonging to chapters has
been moved to mkv_write_chapters(). If mkv_write_tags() has not been
called yet (i.e. when chapters are written when writing the header),
the AVIOContext for writing the ordinary Tags element is used, but not
output, as this is left to mkv_write_tags() in order to only write one
Tags element. Yet if mkv_write_tags() has already been called,
mkv_write_chapters() will output a Tags element of its own which only
contains the tags for chapters.

When chapters are available initially, the corresponding tags will now
be the first tags in the Tags element; but the ordering of tags in Tags
is irrelevant anyway.

This commit also makes chapter_id_offset local to mkv_write_chapters()
as it is used only there and not reused at all.

Potentially writing a second Tags element means that the maximum number
of SeekHead entries had to be incremented. All the changes to FATE
result from the ensuing increase in the amount of space reserved for the
SeekHead (21 bytes more).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 03:34:44 +02:00
Andreas Rheinhardt
19e189b1f0 avformat/matroskaenc: Move mkv_write_chapters()
This is needed so that it can access mkv_write_tag() and mkv_check_tag()
without using forward declarations (which are unnecessary here).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 03:26:32 +02:00
Andreas Rheinhardt
4992bfe824 avformat/matroskaenc: Allow a custom destination for writing Tags
Up until now, the Matroska muxer writes only one Tags level 1 element
and therefore using a certain place to store the dynamic buffer used for
writing it was hardcoded; yet the Matroska specifications allow an
unlimited amount of Tags elements and we have reason to write a second
one: If chapters are provided after writing the header, they are written
when writing the trailer; yet the corresponding tags are ignored. This
can be fixed by writing them in a second Tags element.

Also use a MatroskaMuxContext * instead of an AVFormatContext * as
parameter in mkv_write_tag() and mkv_write_tag_targets() as that is all
these functions use.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 03:15:51 +02:00
Andreas Rheinhardt
99c58e49e8 avformat/matroskaenc: Clean up mkv_write_stereo_mode()
Mostly reindentation after the last commit. Also remove a variable that
is always zero; move another variable to a more local scope and don't
assign a value to a local variable immediately before leaving the function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 03:04:46 +02:00
Andreas Rheinhardt
ff1264aa4d avformat/matroskaenc: Use av_stream_get_side_data() instead of loop
in mkv_write_stereo_mode(). Also check the size of the AVStereo3D
side data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 02:54:13 +02:00
Andreas Rheinhardt
b921d4d013 avformat/matroskaenc: Make mkv_write_video_projection() return void
It can't fail since 9c8aa86883.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 02:44:55 +02:00
Andreas Rheinhardt
0e5ff31545 avformat/matroskaenc: Cosmetics
Mainly reindentation plus some reordering in MatroskaMuxContext;
moreover, use the IS_SEEKABLE() macro troughout the code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 02:35:53 +02:00
Andreas Rheinhardt
575557ce66 avformat/matroskaenc: Don't assert when writing huge files
EBML numbers are variable length numbers: Only seven bits of every byte
are available to encode the number, the other bits encode the length of
the number itself. So an eight byte EBML number can only encode numbers
in the range 0..(2^56 - 1). And when using EBML numbers to encode the
length of an EBML element, the EBML number corresponding to 2^56 - 1 is
actually reserved to mean that the length of the corresponding element
is unknown.

And therefore put_ebml_length() asserted that the length it should
represent is < 2^56 - 1. Yet there was nothing that actually guaranteed
this to be true for the Segment (the main/root EBML element of a
Matroska file that encompasses nearly the whole file). This commit
changes this by checking in advance how big the length is and only
updating the number if it is representable at all; if not, the unknown
length element is not touched.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 01:51:06 +02:00
Andreas Rheinhardt
efeb3a53ad avformat/matroskaenc: Avoid unnecessary seek
The Matroska muxer has a pair of functions designed to write master
elements whose exact length is not known in advance: start_ebml_master()
and end_ebml_master(). The first one of these would write the EBML ID of
the master element that is about to be started, reserve some bytes for
the length field and record the current position as well as how many
bytes were used for the length field. When writing the master's contents
is finished, end_ebml_master() gets the current position (at the end of
the master element), seeks to the length field using the recorded
position, writes the length field and seeks back to the end of the
master element so that one can continue writing other elements.

But if one wants to modify the content of the master element itself,
then the seek back is superfluous. This is the scenario that presents
itself when writing the trailer: One wants to update several elements
contained in the Segment master element (this is the main/root master
element of a Matroska file) that were already written when writing the
header. The current approach is to seek to the beginning of the file
to update the elements, then seek to the end, call end_ebml_master()
which immediately seeks to the beginning to write the length and seeks
back. The seek to the end (which has only been performed because
end_ebml_master() uses the initial position to determine the length
of the master element) and the seek back are of course superfluous.

This commit avoids these seeks by no longer using start/end_ebml_master()
to write the segment's length field. Instead, it is now written
manually. The new approach is: Seek to the beginning to write the length
field, then update the elements (in the order they appear in the file)
and seek back to the end.

This reduces the ordinary amount of seeks of the Matroska muxer to two
(ordinary excludes scenarios where one has big Chapters or Attachments
or where one writes the Cues at the front).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 01:26:07 +02:00
Andreas Rheinhardt
a54c94d95f avformat/matroskaenc: Only write Cues at the front if space has been reserved
If the AVIOContext for output was unseekable when writing the header,
no space for Cues would be reserved even if the reserve_index_space
option was used (because it is reasonable to expect that one can't seek
back to the beginning to write the Cues anyway). But if the AVIOContext
was seekable when writing the trailer, it was presumed that space for
the Cues had been reserved when the reserve_index_space option indicated
so even when it was not. As a result, the beginning of the file would be
overwritten.

This commit fixes this: If the reserve_index_space option had been used
and no space has been reserved in advance because of unseekability when
writing the header, then no attempt to write Cues will be performed
when writing the trailer; after all, writing them at the front is
impossible and writing them at the end is probably undesired.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 01:12:06 +02:00
Andreas Rheinhardt
81e39cf481 avformat/matroskaenc: Don't reserve space for duration when unseekable
We won't be able to seek back to write the actual duration anyway.

FATE-tests using the md5pipe command had to be updated due to this change.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 01:03:05 +02:00
Andreas Rheinhardt
1779f0b12e avformat/matroskaenc: Remove inconsistencies wrt seekability handling
The Matroska muxer behaves differently in several ways when it thinks
that it is in unseekable/livestreaming mode: It does not add Cue entries
because they won't be written anyway for a livestream and it writes some
elements only preliminarily (with the intention to overwrite them with
an updated version at the end) when non-livestreaming etc.

There are two ways to set the Matroska muxer into livestreaming mode:
Setting an option or by providing an unseekable AVIOContext. Yet the
actual checks were not consistent:

If the AVIOContext was unseekable and no AAC extradata was available
when writing the header, writing the header failed; but if the AVIOContext
was seekable, it didn't, because the muxer expected to get the extradata
via packet side-data. Here the livestreaming option has not been checked,
although one can't use the updated extradata in case it is a livestream.

If the reserve_index_space option was used, space for writing Cues would
be reserved when writing the header unless the AVIOContext was
unseekable. Yet Cues were only written if the livestreaming option was
not set and the AVIOContext was seekable (when writing the trailer), so
if the AVIOContext was seekable and the livestreaming option set, the
reserved space would never be used at all.

If the AVIOContext was unseekable and the livestreaming option was not
set, it would be attempted to update the main length field at the end.
After all, it might be possible that the file is so short that it fits
into the AVIOContext's buffer in which case the seek back would work.
Yet this is dangerous: It might be that we are not dealing with a
simple output file, but that our output gets split into chunks and that
each of these chunks is actually seekable. In this case some part of the
last chunk (namely the eight bytes that have the same offset as the
length field had in the header) will be overwritten with what the muxer
wrongly believes to be the filesize.
(The livestreaming option has been added to deal with this scenario,
yet its documentation ("Write files assuming it is a live stream.")
doesn't make this clear at all. At least the segment muxer does not
set the option for live and given that the chances of successfully
seeking when the output is actually unseekable are slim, it is best to
not attempt to update the length field in the unseekable case at all.)

All these inconsistencies were fixed by treating the output as seekable
if the livestreaming option is not set and if the AVIOContext is
seekable. A macro has been used to enforce consistency and improve code
readability.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 00:52:20 +02:00
Andreas Rheinhardt
8aabcf6c11 avformat/matroskaenc: Don't segfault when seekability changes
If the Matroska muxer's AVIOContext was unseekable when writing the
header, but is seekable when writing the trailer, the code for writing
the trailer presumes that a dynamic buffer exists and tries to update
its content in order to overwrite data that has already been
preliminarily written when writing the header, yet said buffer doesn't
exist as it has been written finally and not preliminarily when writing
the header (because of the unseekability it was presumed that one won't
be able to update the data anyway).

This commit adds a check for this and also for a similar situation
involving updating extradata with new data from packet side-data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-19 00:04:04 +02:00
Andreas Rheinhardt
3a822717bd avformat/matroskaenc: Check allocations implicit in dynamic buffers
Failures of the allocations that happen under the hood when using dynamic
buffers are usually completely unchecked and the Matroska muxer is no
exception to this.

The API has its part in this, because there is no documented way to
actually check for errors: The return value of both avio_get_dyn_buf()
as well as avio_close_dyn_buf() is only documented as "the length of
the byte buffer", so that using this to return errors would be an API
break.

Therefore this commit uses the only reliable way to check for errors
with avio_get_dyn_buf(): The AVIOContext's error flag. (This is one of
the advantages of avio_get_dyn_buf(): By not destroying the AVIOContext
it is possible to inspect this value.) Checking whether the size or the
pointer vanishes is not enough as it does not check for truncated output
(the dynamic buffer API is int based and so has to truncate the buffer
even when enough memory would be available; it's current actual limit is
even way below INT_MAX).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-06 10:49:51 +02:00
Andreas Rheinhardt
8370c9c206 avformat/matroskaenc: Simplify writing buffer
If one already has the contents of a master elements in a buffer of
known size, then writing a EBML master element is no different from
writing an EBML binary element. It is overtly complicated to use
start/end_ebml_master() as these functions first write an unkown-length
size field of the appropriate length, then write the buffer's contents,
followed by a seek to the length field to overwrite it with the real
size (obtained via avio_tell() although it was already known in
advance), followed by another seek to the previous position. Just use
put_ebml_binary() instead.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-06 10:38:53 +02:00
Andreas Rheinhardt
3122dcf2fe avformat/matroskaenc: Avoid dynamic buffer when writing Colour
There is a good upper bound for the maximum length of the Colour master
element; it is therefore unnecessary to use a dynamic buffer for it.
A simple buffer on the stack is enough. This commit implements this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-06 10:22:48 +02:00
Andreas Rheinhardt
851283a777 avformat/matroskaenc: Unify writing level 1 elements preliminarily
The Matroska muxer updates several header elements when the output is
seekable; if unseekable, the buffer containing the contents of the element
is immediately freed after writing. Before this commit, there were three
places doing exactly the same: Checking whether the output is seekable
and calling the function that writes and frees or the function that
just writes the EBML master. This has been unified; adding SeekHead
entries for these elements has been unified, too.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-06 09:45:17 +02:00
Andreas Rheinhardt
4ed3c925c3 avformat/matroskaenc: Move adding SeekEntry into end_ebml_master_crc32()
Up until now, SeekEntries were already added before
start_ebml_master_crc32() was even called and before we were actually
sure that we really write the element the SeekHead references: After
all, we might also error out later; and given that the allocations
implicit in dynamic buffers should be checked, end_ebml_master_crc32()
will eventually have to return errors itself, so that it is the right
place to add SeekHead entries.

The earlier behaviour is of course a remnant of the time in which
start_ebml_master_crc32() really did output something, so that the
position before start_ebml_master_crc32() needed to be recorded.
Erroring out later is also not as dangerous as it seems because in
this case no SeekHead will be written (if it happened when writing
the header, the whole muxing process would abort; if it happened
when writing the trailer (when writing chapters not available initially),
writing the trailer would be aborted and no SeekHead containing the
bogus chapter entry would be written).

This commit does not change the way the SeekEntries are added for those
elements that are output preliminarily; this is so because the SeekHead
is written before those elements are finally output and doing it
otherwise would increase the amount of seeks.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-06 09:27:40 +02:00
Andreas Rheinhardt
449eaeb7a7 avformat/matroskaenc: Check mimetypes earlier
This avoids errors lateron after the file header has already been
partially written.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 14:14:06 +02:00
Andreas Rheinhardt
cb255b616c avformat/matroskaenc: Fix memleak upon encountering bogus chapter
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 14:05:44 +02:00
Andreas Rheinhardt
0aed3002ad avformat/matroskaenc: Make sure UIDs of delayed chapters are != 0
This has previously only been checked if the chapters were initially
available, but not if they were only written in the trailer.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 13:56:29 +02:00
Andreas Rheinhardt
6397b4d6a2 avformat/vorbiscomment: Switch to AVIOContext from bytestream API
Up until now ff_vorbiscomment_write() used the bytestream API to write
VorbisComments. Therefore the caller had to provide a sufficiently large
buffer to write the output.

Yet two of the three callers (namely the FLAC and the Matroska muxer)
actually want the output to be written via an AVIOContext; therefore
they allocated buffers of the right size just for this purpose (i.e.
they get freed immediately afterwards). Only the Ogg muxer actually
wants a buffer. But given that it is easy to wrap a buffer into an
AVIOContext this commit changes ff_vorbiscomment_write() to use an
AVIOContext for its output.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 13:43:54 +02:00
Andreas Rheinhardt
704d7c9f46 avformat/vorbiscomment: Replace AVDictionary ** by const AVDictionary *
ff_vorbiscomment_write() used an AVDictionary ** parameter for a
dictionary whose contents ought to be written; yet this can be replaced
by AVDictionary * since commit 042ca05f0fdc5f4d56a3e9b94bc9cd67bca9a4bc;
and this in turn can be replaced by const AVDictionary * to indicate
that the dictionary isn't modified; the latter also applies to
ff_vorbiscomment_length().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 12:45:01 +02:00
Andreas Rheinhardt
ca0a38f2f7 avformat/matroskaenc: Replace impossible condition with assert
If a FLAC track uses an unconventional channel layout, the Matroska
muxer adds a WAVEFORMATEXTENSIBLE_CHANNEL_MASK VorbisComment to the
CodecPrivate to preserve this information. And given that FLAC uses
24bit length fields, the muxer checks if the length is more than this
and errors out if it is.

Yet this can never happen, because we create the AVDictionary that is
the source for the VorbisComment. It only contains exactly one entry
that can't grow infinitely large (in fact, the length of the
VorbisComment is <= 4 + 33 + 1 + 18 + strlen(LIBAVFORMAT_IDENT)).
So we can simply assert the size to be < (1 << 24) - 4.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 12:44:54 +02:00
Andreas Rheinhardt
d13feae0f8 avformat/matroskaenc: Write SeekHead when livestreaming
Commit 6fd300ac6c added support for WebM
Chunk livestreaming; in this case, both the header as well as each
Cluster is written to a file of its own, so that even if the AVIOContext
seems seekable, the muxer has to behave as if it were not. Yet one of
the added checks makes no sense: It ensures that no SeekHead is written
preliminarily (and hence no SeekHead is written at all) if the option
for livestreaming is set, although one should write the SeekHead in this
case when writing the Header. E.g. the WebM-DASH specification [1]
never forbids writing a SeekHead and in some instances (that don't apply
here) even requires it (if Cues are written after the Clusters).

[1]: https://sites.google.com/a/webmproject.org/wiki/adaptive-streaming/webm-dash-specification

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 12:44:48 +02:00
Andreas Rheinhardt
68c7186d94 avformat/matroskaenc: Only write Cluster if it has in fact been opened
Since commit 4aa0665f39, the dynamic
buffer destined for the contents of the current Cluster is no longer
constantly allocated, reallocated and then freed after writing the
content; instead it is reset and reused when closing a Cluster.

Yet the code in mkv_write_trailer() still checked for whether a Cluster
is open by checking whether the pointer to the dynamic buffer is NULL or
not (instead of checking whether the position of the current Cluster is
-1 or not). If a Cluster was not open, an empty Cluster would be output.

One usually does not run into this issue, because unless there are
errors, there are only three possibilities to not have an opened Cluster
at the end of writing a packet:
The first is if one sent an audio packet to the muxer. It might trigger
closing and outputting the old Cluster, but because the muxer caches
audio packets internally, it would not be output immediately and
therefore no new Cluster would be opened.
The second is an audio packet that does not contain data (such packets
are sometimes sent for side-data only, e.g. by the FLAC encoder). The
only difference to the first scenario is that such packets are not
cached.
The third is if one explicitly flushes the muxer by sending a NULL
packet via av_write_frame().

If one also allows for errors, then there is also another possibility:
Caching the audio packet may fail in the first scenario.

If one calls av_write_trailer() after the first scenario, the cached
audio packet will be output when writing the trailer, for which
a Cluster is opened and everything is fine; because flushing the muxer
does currently not output the cached audio packet (if one is cached),
the issue also does not exist if an audio packet has been cached before
flushing. The issue only exists in one of the other scenarios.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-05-03 12:44:44 +02:00
Andreas Rheinhardt
904b25a550 avformat/matroskaenc: Use comparison instead of assignment
This bug was introduced in 3589b3f2e2.
Fixes Coverity ID 1462425.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-22 03:45:44 +02:00
Andreas Rheinhardt
8a4fda029a avformat/matroskaenc: Cosmetics
Reindentation, removal of { } if they contain only one statement
and moving the return statement to a line of its own in situations
like "if (ret < 0) return ret;". Moreover, several overlong lines
were made shorter and a camelCase variable received a name in line
with our naming conventions.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 08:50:22 +02:00
Andreas Rheinhardt
e3c54b549a avformat/matroskaenc: Redo handling of FlagDefault
Up until now, the Matroska muxer would mark a track as default if it had
the disposition AV_DISPOSITION_DEFAULT or if there was no track with
AV_DISPOSITION_DEFAULT set; in the latter case even more than one track
of a kind (audio, video, subtitles) was marked as default which is not
sensible.

This commit changes the logic used to mark tracks as default. There are
now three modes for this:
a) In the "infer" mode the first track of every type (audio, video,
subtitles) with default disposition set will be marked as default; if
there is no such track (for a given type), then the first track of this
type (if existing) will be marked as default. This behaviour is inspired
by mkvmerge. It ensures that the default flags will be set in a sensible
way even if the input comes from containers that lack the concept of
default flags. This mode is the default mode.
b) The "infer_no_subs" mode is similar to the "infer" mode; the
difference is that if no subtitle track with default disposition exists,
no subtitle track will be marked as default at all.
c) The "passthrough" mode: Here the track will be marked as default if
and only the corresponding input stream had disposition default.

This fixes ticket #8173 (the passthrough mode is ideal for this) as
well as ticket #8416 (the "infer_no_subs" mode leads to the desired
output).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 08:36:20 +02:00
Andreas Rheinhardt
75e50c3141 avformat/matroskaenc: Don't needlessly copy AVCodecParameters
At the end of encoding, the FLAC encoder sends a packet whose side data
contains updated extradata (e.g. a correct md5 checksum). The Matroska
muxer uses this to update the CodecPrivate.

In doing so, the stream's codecpar was copied. But given that writing
a FLAC CodecPrivate does not modify the used AVCodecParameters at all,
there is no need to do so and this commit changes this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 08:28:58 +02:00
Andreas Rheinhardt
abc7dc32bd avformat/matroskaenc: Add const where appropriate
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 08:20:02 +02:00
Andreas Rheinhardt
5b6e164b4b avformat/matroskaenc: Don't waste bytes on length fields
Several EBML Master elements for which a good upper bound of the final
length was available were nevertheless written without giving an
upper bound of the final length to start_ebml_master(), so that their
length fields were eight bytes long. This has been changed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 08:11:09 +02:00
Andreas Rheinhardt
a9844341f7 avformat/matroskaenc: Only write Tracks if there is a track
The Matroska muxer does not write every stream as a Matroska track;
some streams are written as AttachedFile. But should no stream be
written as a Matroska track, the Matroska muxer would nevertheless
write a Tracks element without a TrackEntry. This is against the spec.
This commit changes this and only writes a Tracks if there is a Matroska
track.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 07:49:39 +02:00
Andreas Rheinhardt
ef45cccc81 avformat/matroskaenc: Warn that WebM doesn't support Attachments
As WebM doesn't support Attachments, the Matroska muxer drops them when
in WebM mode. This happened silently until this commit which adds a
warning for this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 07:41:21 +02:00
Andreas Rheinhardt
4dd63ae86c avformat/matroskaenc: Don't use size of inexistent Cluster
In order to determine whether the current Cluster needs to be closed
because of the limits on clustersize and clustertime,
mkv_write_packet() would first get the size of the current Cluster by
applying avio_tell() on the dynamic buffer holding the current Cluster.
It did this without checking whether there is a dynamic buffer for
writing Clusters open right now.

In this case (which happens when writing the first packet)
avio_tell() returned AVERROR(EINVAL); yet it is not good to rely on
avio_tell() (or actually, avio_seek()) to handle the situation
gracefully.

Fixing this is easy: Only check whether a Cluster needs to be closed
if a Cluster is in fact open.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 07:33:04 +02:00
Andreas Rheinhardt
86de864741 avformat/matroskaenc: Add check for using explicit TrackNumber
When creating DASH streams, the TrackNumber is externally prescribed
and not derived from the number of streams in the AVFormatContext, so
if the number of tracks for a file using an explicit TrackNumber was
more than one, the resulting file would be broken (it would be impossible
to tell to which track a Block belongs if different tracks share the
same TrackNumber). So disallow this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-21 07:31:10 +02:00
Andreas Rheinhardt
945b928730 avformat/matroskaenc: Improve Cues in case of no video
The Matroska muxer currently only adds CuePoints in three cases:
a) For video keyframes. b) For the first audio frame in a new Cluster if
in DASH-mode. c) For subtitles. This means that ordinary Matroska audio
files won't have any Cues which impedes seeking.

This commit changes this. For every track in a file without video track
it is checked and tracked whether a Cue entry has already been added
for said track for the current Cluster. This is used to add a Cue entry
for each first packet of each track in each Cluster.

Implements #3149.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:30:46 +02:00
Andreas Rheinhardt
13c12cd470 avformat/matroskaenc: Remove limit on the number of tracks
The Matroska file format has practically no limit on the number of
tracks (the current limit is 2^56 - 1); yet because they are encoded in
a variable length format in (Simple)Blocks this muxer has simply imposed
a limit on the number of tracks in order to ensure that they can always
be written on one byte in order to simplify the muxing process.

This commit removes said limit.

Also, zero is an invalid TrackNumber, so disallow this value in the
dash_track_number option.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:30:46 +02:00
Andreas Rheinhardt
112afaccdf avformat/matroskaenc: Refactor writing EBML lengths
This commit factors the ability to write ordinary EBML numbers out of
the functions for writing EBML lengths. This is in preparation for
future commits.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:30:46 +02:00
Andreas Rheinhardt
40d038a635 avformat/matroskaenc: Rename functions to better reflect what they do
EBML uses variable length integers both for the EBML IDs as well as for
the EBML lengths; Matroska also uses them for the TrackNumber in
(Simple)Blocks and for the lengths of laces when EBML lacing is used.

When encoding EBML lengths, certain encodings have a special meaning,
namely that the element has an unknown length. This is not so when
encoding general EBML variable length integers.

Yet the functions called ebml_num_size() and put_ebml_num() had this
special meaning hardcoded, i.e. they are there to write EBML lengths and
not general EBML numbers. So rename them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:30:46 +02:00
Andreas Rheinhardt
9b0f9003df avformat/matroskaenc: Make ebml_num_size() more robust
Matroska (or actually EBML) uses variable-length numbers where only
seven bits of every byte is usable for the length; the other bits encode
the length of the variable-length number. So in order to find out how
many bytes one needs to encode a given number one can use a loop like
while (num >> 7 * bytes) bytes++; the Matroska muxer effectively did this.

Yet it has a disadvantage: It is impossible for the result of a single
right shift of an unsigned number with most significant bit set to be
zero, because one can only shift by 0..(width - 1). On some
architectures like x64 it is not even possible to do it with undefined
right shifts in which case this leads to an infinite loop.

This can be easily avoided by switching to a loop whose condition is
(num >>= 7). The maximum value the so modified function can return
is 10; any value > 8 is invalid and will now lead to an assert in
put_ebml_num() or in start_ebml_master() (or actually in
put_ebml_size_unknown()).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:30:46 +02:00
Andreas Rheinhardt
3589b3f2e2 avformat/matroskaenc: Improve mimetype search
Use the mime_types of the corresponding AVCodecDescriptor instead of
tables specific to Matroska. The former are generally more encompassing:
They contain every item of the current lists except "text/plain" for
AV_CODEC_ID_TEXT and "binary" for AV_CODEC_ID_BIN_DATA.

The former has been preserved by special-casing it while the latter is
a hack added in c9212abf so that the demuxer (which uses the same tables)
sets the appropriate CodecID for broken files ("binary" is not a correct
mime type at all); using it for the muxer was a mistake. The correct
mime type for AV_CODEC_ID_BIN_DATA is "application/octet-stream" and
this is what one gets from the AVCodecDescriptor.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-20 21:00:19 +02:00
Andreas Rheinhardt
f0d712d0f9 avformat/matroskaenc: Don't write elements with their default value
This has happened when writing chapters: Both editions as well as
chapters are by default not hidden and given that we don't support
writing hidden chapters at all, we don't need to write said elements at
all. The same goes for ChapterFlagEnabled.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-14 03:55:06 +02:00
Andreas Rheinhardt
59e3a9aede avformat/matroskaenc: Change signature of mkv_write_track()
Up until now, mkv_write_track() received the index of the stream whose
header data it is about to write as parameter; this index has until
recently been explicitly used to generate both TrackNumber and TrackUID.
But this is no longer so and as there is no reason why the function
for writing a single TrackEntry should even know the index of the
TrackEntry it is about to write, said index is replaced in the list of
function parameters by the corresponding AVStream and mkv_track.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-13 09:09:25 +02:00
Andreas Rheinhardt
385964409a avformat/matroskaenc: Automatically use right TrackNumber in Cues
mkv_cuepoint (the structure used to store the index entries in the
Matroska muxer) currently contains fields for both the index of the
packet's stream in the AVFormatContext.streams array and for the
Matroska TrackNumber; correspondingly, mkv_add_cuepoint() has parameters
for both. But these two numbers can't be chosen independently, so get
rid of the TrackNumber.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-13 09:08:41 +02:00
Andreas Rheinhardt
629f08a863 avformat/matroskaenc: Ignore AttachedFiles for track limit
Attachments are streams in FFmpeg, but they are not tracks in Matroska.
Yet they were counted when checking a limit for the number of tracks that
the Matroska muxer imposes. This is unnecessary and has been changed.

Also use unsigned variables for the variables denoting TrackNumbers as
negative TrackNumbers are impossible.

(The Matroska file format actually has practically no limit on the
number of tracks and this is purely what our muxer supports. But even if
this limit were removed/relaxed in the future, it still makes sense to
use small TrackNumbers as this patch does, because greater numbers need
more bytes to encode.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-04-13 08:51:21 +02:00