The following three commits created a regression by writing initially
invalid mkv headers:
650e17d88b avformat/matroskaenc: write a
CRC32 element on Tags
3bcadf8227 avformat/matroskaenc: write a
CRC32 element on Info
ee888cfbe7 avformat/matroskaenc: postpone
writing the Tracks master
Symptoms:
- You can no longer playback a file that is still processed by ffmpeg,
e.g. VLC fails playback
- You can no longer stream a file to a client while if is still being
processed
- Various diagnosing tools show header errors or incomplete headers
(e.g. ffprobe, mediainfo, mkvalidator)
Note: The symptoms do not apply to completed files or ffmpeg runs that
were interrupted with 'q'
Cause:
The mentioned commits made changes in a way that some header elements
are only partially written in
mkv_write_header, leaving the header in an invalid state. Only in
mkv_write_trailer, these elements
are finished correctly, but that does only occur at the end of the
process.
Regression:
Before these commits were applied, mkv headers have always been valid,
even before completion of ffmpeg.
This has worked reliably over many versions of ffmpeg, to it was an
obvious regression.
Bugtracker:
This issue has been recorded as #5977 which is resolved by this patch
Patch:
The patch adds a new function 'end_ebml_master_crc32_preliminary' that
preliminarily finishes the ebml
element without destroying the buffer. The buffer can be used to update
the ebml element later during
mkv_write_trailer. But most important: mkv_write_header finishes with a
valid mkv header again.
Signed-off-by: James Almer <jamrial@gmail.com>
FLAC streams originating from the FLAC encoder send updated and more
complete STREAMINFO metadata as part of the last packet, so write that
to CodecPrivate instead of the incomplete one available in extradata
during init.
Signed-off-by: James Almer <jamrial@gmail.com>
This avoids potential rounding errors and guarantees the source aspect
ratio is preserved.
Keep writing pixel values when Stereo 3D Mode is enabled and for WebM,
as the format doesn't support anything else.
This fixes ticket #5743, implementing the suggestion from ticket #5903.
Signed-off-by: James Almer <jamrial@gmail.com>
The dynamic buffer does not contain the CRC32 element so calls to avio_tell()
don't take it into account. This resulted in CueRelativePosition values being
six bytes short.
This is a regression since 6724525a15
Instead of adding yet another custom check for CRC32 to fix a size or an offset,
remove the existing ones and reserve the six bytes in the dynamic buffer.
Signed-off-by: James Almer <jamrial@gmail.com>
We don't currently support values 1 (centimeters), 2 (inches) or 3 (DAR),
only the default value 0 (pixels) which doesn't need to be written.
The fate refs are updated as unknown SAR is now signaled in the output
files with the addition of the new element.
Reviewed-by: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
The spec says:
"Mandatory elements with a default value may be left out of the file. In the absence
of a mandatory element, the element's default value is used."
Reviewed-by: Hendrik Leppkes <h.leppkes@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Attachment tags were being written targeting non-existent streams in the
output file.
Also filter filename and mimetype entries, as they are standard elements
in the Attachment master.
Signed-off-by: James Almer <jamrial@gmail.com>
The dynamic AVIOContext would get closed pointing to the wrong position
in the buffer.
This is a regression since 650e17d88b.
Reviewed-by: Dave Rice <dave@dericed.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Implements part of ticket #4347
Tested-by: Dave Rice <dave@dericed.com>
Tested-by: Jerome Martinez <jerome@mediaarea.net>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Printing the dynamic buffer offset is useless.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
The durations are never written in that situation.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Previously, we used a different list of checks when deciding whether to
write a set of tags at all than we did when deciding whether to write an
individual tag in the set. This resulted in sometimes writing an empty
tag master and seekhead. Now we use mkv_check_tag_name everywhere, so
if a dictionary is entirely composed of tags we skip, we don't write a
tag master at all.
This affected the test file, since "language" was on one list but not
the other, so we were writing an empty tag master there. The test hash
is updated to reflect that change.
Rev #2: Fixes doubled header writing, checked FATE running without errors
Rev #3: Fixed coding style
This commit addresses the following scenario:
we are using ffmpeg to transcode or remux mkv (or something else) to mkv. The result is being streamed on-the-fly to an HTML5 client (streaming starts while ffmpeg is still running). The problem here is that the client is unable to detect the duration because the duration is only written to the mkv at the end of the transcoding/remoxing process. In matroskaenc.c, the duration is only written during mkv_write_trailer but not during mkv_write_header.
The approach:
FFMPEG is currently putting quite some effort to estimate the durations of source streams, but in many cases the source stream durations are still left at 0 and these durations are nowhere mapped to or used for output streams. As much as I would have liked to deduct or estimate output durations based on input stream durations - I realized that this is a hard task (as Nicolas already mentioned in a previous conversation). It would involve changes to the duration calculation/estimation/deduction for input streams and propagating these durations to output streams or the output context in a correct way.
So I looked for a simple and small solution with better chances to get accepted. In webmdashenc.c I found that a duration is written during write_header and this duration is taken from the streams' metadata, so I decided for a similar approach.
And here's what it does:
At first it is checking the duration of the AVFormatContext. In typical cases this value is not set, but: It is set in cases where the user has specified a recording_time or an end_time via the -t or -to parameters.
Then it is looking for a DURATION metadata field in the metadata of the output context (AVFormatContext::metadata). This would only exist in case the user has explicitly specified a metadata DURATION value from the command line.
Then it is iterating all streams looking for a "DURATION" metadata (this works unless the option "-map_metadata -1" has been specified) and determines the maximum value.
The precendence is as follows: 1. Use duration of AVFormatContext - 2. Use explicitly specified metadata duration value - 3. Use maximum (mapped) metadata duration over all streams.
To test this:
1. With explicit recording time:
ffmpeg -i file:"src.mkv" -loglevel debug -t 01:38:36.000 -y "dest.mkv"
2. Take duration from metadata specified via command line parameters:
ffmpeg -i file:"src.mkv" -loglevel debug -map_metadata -1 -metadata Duration="01:14:33.00" -y "dest.mkv"
3. Take duration from mapped input metadata:
ffmpeg -i file:"src.mkv" -loglevel debug -y "dest.mkv"
Regression risk:
Very low IMO because it only affects the header while ffmpeg is still running. When ffmpeg completes the process, the duration is rewritten to the header with the usual value (same like without this commit).
Signed-off-by: SoftWorkz <softworkz@hotmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
The header was never installed and the function is only used in libavformat
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Adding early support for a subset of the proposed colour elements
according to the latest version of spec:
https://mailarchive.ietf.org/arch/search/?email_list=cellar&gbt=1&index=hIKLhMdgTMTEwUTeA4ct38h0tmE
Like matroskadec, I've left out elements for pix_fmt related things
as there still seems to be some discussion around these.
The new elements are exposed under strict experimental mode.
Signed-off-by: Neil Birkbeck <neil.birkbeck@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Currently, AVStream contains an embedded AVCodecContext instance, which
is used by demuxers to export stream parameters to the caller and by
muxers to receive stream parameters from the caller. It is also used
internally as the codec context that is passed to parsers.
In addition, it is also widely used by the callers as the decoding (when
demuxer) or encoding (when muxing) context, though this has been
officially discouraged since Libav 11.
There are multiple important problems with this approach:
- the fields in AVCodecContext are in general one of
* stream parameters
* codec options
* codec state
However, it's not clear which ones are which. It is consequently
unclear which fields are a demuxer allowed to set or a muxer allowed to
read. This leads to erratic behaviour depending on whether decoding or
encoding is being performed or not (and whether it uses the AVStream
embedded codec context).
- various synchronization issues arising from the fact that the same
context is used by several different APIs (muxers/demuxers,
parsers, bitstream filters and encoders/decoders) simultaneously, with
there being no clear rules for who can modify what and the different
processes being typically delayed with respect to each other.
- avformat_find_stream_info() making it necessary to support opening
and closing a single codec context multiple times, thus
complicating the semantics of freeing various allocated objects in the
codec context.
Those problems are resolved by replacing the AVStream embedded codec
context with a newly added AVCodecParameters instance, which stores only
the stream parameters exported by the demuxers or read by the muxers.