Commit Graph

564 Commits

Author SHA1 Message Date
Martin Storsjö c415c8104c movenc: Don't write any edit list if the start offset is zero
In these cases, the CTTS flag is set, but no edit list is necessary.

Signed-off-by: Martin Storsjö <martin@martin.st>
2017-05-15 14:08:48 +03:00
Martin Storsjö c380a0d7f7 movenc: Add an option for enabling negative CTS offsets
This reduces the need for an edit list; streams that start with
e.g. dts=-1, pts=0 can be encoded as dts=0, pts=0 (which is valid
in mov/mp4) by shifting the dts values of all packets forward.
This avoids the need for edit lists for such streams (while they
still are needed for audio streams with encoder delay).

This eases conformance with the DASH-IF interoperability guidelines.

Signed-off-by: Martin Storsjö <martin@martin.st>
2017-05-15 14:08:36 +03:00
Diego Biurrun a25dac976a Use bitstream_init8() where appropriate 2017-02-07 18:27:21 +01:00
Anton Khirnov fd9212f2ed Mark some arrays that never change as const. 2017-02-01 10:42:59 +01:00
Alexandra Hájková a895292f27 mov: Convert to the new bitstream reader 2017-01-13 10:27:03 +01:00
Diego Biurrun 0b77a59336 Use correct printf conversion specifiers for POSIX integer types 2016-12-23 19:30:00 +01:00
Anton Khirnov 83548fe894 lavf: fix usage of AVIOContext.seekable
It is supposed to be a flag. The only currently defined value is
AVIO_SEEKABLE_NORMAL, but other ones may be added in the future.
However all the current lavf code treats this field as a bool (mainly
for historical reasons).
Change all those cases to properly check for AVIO_SEEKABLE_NORMAL.
2016-09-30 16:54:33 +02:00
Martin Storsjö 4f7723cb3b movenc: Add an option for skipping writing the mfra/tfra/mfro trailer
When writing a fragmented file, we by default write an index pointing
to all the fragments at the end of the file. This causes constantly
increasing memory usage during the muxing. For live streams, the
index might not be useful at all.

A similar fragment index is written (but at the start of the file) if
the global_sidx flag is set. If ism_lookahead is set, we need to keep
data about the last ism_lookahead+1 fragments.

If no fragment index is to be written, we don't need to store information
about all fragments, avoiding increasing the memory consumption
linearly with the muxing runtime.

This fixes out of memory situations with long live mp4 streams.

Signed-off-by: Martin Storsjö <martin@martin.st>
2016-07-08 14:11:15 +03:00
Martin Storsjö 785c25443b movenc: Apply offsets on timestamps when peeking into interleaving queues
Signed-off-by: Martin Storsjö <martin@martin.st>
2016-06-28 14:16:06 +03:00
Martin Storsjö b84f3a4003 movenc: Write 'loci' geotag metadata for 3gp and mp4
Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-19 10:46:55 +03:00
Martin Storsjö f12a705ee5 movenc: Factorize a function for finding a metadata entry and the associated language
Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-19 10:46:54 +03:00
Michael Niedermayer daec1651f1 movenc: Write ?xyz geotag metadata for mov files
Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-19 10:46:53 +03:00
Martin Storsjö 72d621069f movenc: Add a missed const
This was missed in e1eb0fc960, when ff_interleaved_peek was
changed to include const during the evolution of the patch.

Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-18 21:59:48 +03:00
Martin Storsjö e1eb0fc960 movenc: Use packets in interleaving queues for the duration at the end of fragments
As long as caller only writes packets using av_interleaved_write_frame
with no manual flushing, this should allow us to always have accurate
durations at the end of fragments, since there should be at least
one queued packet in each stream (except for the stream where the
current packet is being written, but if the muxer itself does the
cutting of fragments, it also has info about the next packet for that
stream).

Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-18 10:37:03 +03:00
Martin Storsjö dbbaad32e3 movenc: Provide output bytestream markers for fragmented content
Signed-off-by: Martin Storsjö <martin@martin.st>
2016-05-18 10:36:55 +03:00
Diego Biurrun 5afb94c817 Mark read-only tables as static 2016-05-05 10:48:34 +02:00
Vittorio Giovara 41ed7ab45f cosmetics: Fix spelling mistakes
Signed-off-by: Diego Biurrun <diego@biurrun.de>
2016-05-04 18:16:21 +02:00
Diego Biurrun 0f40c90984 Drop pointless assert.h #includes 2016-05-03 15:45:10 +02:00
Martin Storsjö 74383def8f movenc: Handle pts == NOPTS when autoflushing
This muxer generally handles pts == NOPTS by using dts instead;
do this for consistency here as well.

Signed-off-by: Martin Storsjö <martin@martin.st>
2016-04-21 11:20:39 +03:00
Martin Storsjö 0abb07bad7 movenc: Update a comment to reflect how the code actually behaves
This codepath isn't quite as bad as it used to sound, if fragments
are cut automatically at video packets.

Signed-off-by: Martin Storsjö <martin@martin.st>
2016-04-19 22:43:00 +03:00
Anton Khirnov 9200514ad8 lavf: replace AVStream.codec with AVStream.codecpar
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.
2016-02-23 17:01:58 +01:00
Anton Khirnov 9f61abc811 lavf: allow custom IO for all files
Some (de)muxers open additional files beyond the main IO context.
Currently, they call avio_open() directly, which prevents the caller
from using custom IO for such streams.

This commit adds callbacks to AVFormatContext that default to
avio_open2()/avio_close(), but can be overridden by the caller. All
muxers and demuxers using AVIO are switched to using those callbacks
instead of calling avio_open()/avio_close() directly.

(de)muxers that use the URLProtocol layer directly instead of AVIO
remain unconverted for now. This should be fixed in later commits.
2016-01-24 16:45:32 +01:00
Anton Khirnov 5845a8273e movenc: use the CPB props side data
Do not access the encoder options, since it makes no sense when the
AVStream codec context is not the encoding context.
2015-12-06 10:26:01 +01:00
John Stebbins ca489564ae movenc: add fallback audio track tref support
This feature allows making associations between audio tracks
that apple players recognize.  E.g. when an ac3 track has a
tref that points to an aac track, devices that don't support
ac3 will automatically fall back to the aac track.

Apple used to *guess* these associations, but new products
(AppleTV 4) no longer guess and this association can only
be made explicitly now using the "fall" tref.

Signed-off-by: Anton Khirnov <anton@khirnov.net>
2015-11-18 11:38:03 +01:00
Martin Storsjö bef3b1f59f movenc: Allow setting start_dts/start_cts before writing actual packets
By writing a zero-sized packet, the caller can communicate the
start_dts/start_cts for the stream without actually writing
the first packet.

This allows doing random-access writing of fragments when the
start dts of the stream isn't zero, so that the edit list in the moov
is written based on timestamps from the nominal start time signaled
via the zero-sized packet, while the first proper packet written
corresponds to a later fragment.

To avoid potential unexpected behaviour, empty packets only set
start_dts if the frag_discont flag is set.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-11-11 22:53:31 +02:00
Martin Storsjö 09e431b9e3 movenc: Assume streams starting at pts=0 for discontinuous fragments with editlists
This allows producing fragments discontinously where the video
stream has b-frames (but starts at pts=0), but doesn't work for the
cases with audio with preroll.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-11-11 22:52:36 +02:00
Martin Storsjö 8ad5124b7e movenc: Automatically flush after writing the initial moov
In most other cases when writing fragmented mp4 files, the output
IO context is flushed after each fragment. Also flush it after
writing the initial moov, to have it behave in the same way.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-11-10 21:46:03 +02:00
Martin Storsjö 5ea5a24eb7 movenc: Honor flush requests with delay_moov, when some tracks lack samples
This also makes sure that a fragmented file without the empty_moov
flag (i.e. with a non-empty initial moov fragment) actually gets
written, if some of the tracks turn out to not have any samples.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-10-23 10:37:49 +03:00
Martin Storsjö 26ac22e5e7 movenc: Add a new flag for writing global sidx indexes for dash
The double meaning of the faststart flag (moving a moov atom
to the start of files, making them streamable, for non-fragmented
files, vs inserting a global sidx index at the start of files
for fragmented files) is confusing - see 40ed1cbf1 for
explanation of its origins.

Since the second meaning of the flag hasn't been part of any
libav release yet, just rename it to get rid of the confusion
without any extra deprecation (which wouldn't get rid of the
potential confusion, of users adding -movflags faststart
even for fragmented files, where it isn't needed for making
them "streamable").

This gets back the old behaviour, where -movflags faststart
doesn't have any effect for fragmented files.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-08-12 13:41:46 +03:00
Martin Storsjö 5f200bbf98 movenc: Place the sidx index after the initial moov/mdat pair
For fragmented files with non-empty moov, with a fragment index
(sidx), place the index after the initial moov/mdat pair.

Previously, for this pathological case, the index was written
at the start of the file.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-08-10 09:46:14 +03:00
Martin Storsjö 83f254e65f movenc: Rename reserved_moov_pos to reserved_header_pos
The same field is also used for writing the sidx index header,
for fragmented files, when the faststart flag is used.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-08-10 09:46:07 +03:00
Martin Storsjö 8e34089e26 movenc: Check that frag_info entries exist in mov_write_sidx_tag
This fixes crashes with pathological cases when trying to write
a sidx index (via the -movflags faststart option, in combination
with fragmenting options), when no fragments actually have been
written. (This is possible if the empty_moov flag isn't used,
so that all actual packet data is written in the moov/mdat pair,
and no moof/mdat pairs have been written.)

In these pathological cases, no sidx should be written at all.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-08-10 09:46:03 +03:00
Vittorio Giovara 059a934806 lavc: Consistently prefix input buffer defines
Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
2015-07-27 15:24:59 +01:00
Luca Barbato e95c7a6185 mov: Preserve the metadata even when bit-exactness is requested
Make sure to not write the custom `encoder` string in that case.

Bug-Id: 845
CC: libav-stable@libav.org
2015-06-30 15:34:38 +02:00
Janne Grunau 529c05698e movenc: fixes a questionable valgrind uninitialized value warning
display_matrix_size is only initialized when av_stream_get_side_data()
returns a side data pointer. The code is safe since the only effect this
has is setting the display_matrix pointer to NULL which it was already
anyway.
2015-06-10 14:32:11 +02:00
Martin Storsjö e0046bc9c9 movenc: Write the make and model metadata keys for mov style files
These are essential allowing QuickTime to keep detecting content
as slow-motion - this allows preserving them on stream copy.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-23 12:43:35 +02:00
Anton Khirnov cf18e777ae movenc: write the display transform matrix 2015-03-19 21:02:59 +01:00
Martin Storsjö 67a2912307 movenc: Don't assume that fragment durations in pts is equal to duration in dts
For strict CFR, they should be pretty much equal, but if the stream
is VFR, there can be a sometimes significant difference.

Calculate the pts duration separately, used in sidx atoms and for
tfrf/tfxd boxes in smooth streaming ismv files.

Also make sure to reduce the duration of sidx entries according to
edit lists.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:20 +02:00
Martin Storsjö 5c337353a2 movenc: Move sidx edit list timestamp adjustment into a block
When reading these values from track->frag_info, the same adjustment
has already been done.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:17 +02:00
Martin Storsjö eee13d6539 movenc: Only adjust the cts offset at the start of fragments if necessary
Adjusting it is only necessary when a sidx/tfrf/tfxd atom already has
been written for the previous fragment (since the sidx/tfrf/tfxd atoms
include the duration between the first pts of the previous fragment, to
the first pts of the new fragment).

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:15 +02:00
Martin Storsjö 5cf892d694 movenc: Write pts timestamps in tfxd, instead of dts timestamps
This matches what we write in tfra and tfrf since 9cbf70fa0e.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:12 +02:00
Martin Storsjö b81b0cc22b movenc: Set the last packet duration based on the next packet when autoflushing
When automatically flushing fragments based on set conditions
(fragmentation on keyframes, after some interval or byte size),
we already have the next packet for one stream - use this for setting
the duration of the last packet in the flushed fragment correctly.

This avoids having to adjust the timestamp of the first packet in
the new fragment since the last duration was unknown.

Unfortunately, this only works for automatic flushing (not for
caller-triggered flushing, like in the dash muxer), and only for the
one single track that triggered the flushing. The duration of the
last sample in all other tracks still is dependent on AVPacket
duration (or heuristics).

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:07 +02:00
Martin Storsjö 2889c5e167 movenc: Heuristically set the duration of the last sample in a fragment if not set
Even if this is a guess, it is way better than writing a zero duration
of the last sample in a fragment (because if the duration is zero,
the first sample of the next fragment will have the same timestamp
as the last sample in the previous one).

Since we normally don't require libavformat muxer users to set
the duration field in AVPacket, we probably can't strictly require
it here either, so don't log this as a strict warning, only as info.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:26:52 +02:00
Martin Storsjö 2cb9c2fc59 movenc: Allow interleaving samples when writing fragmented files
This is incompatible with the omit_tfhd_offset flag (writing
position independent fragments with interleaving requires the
default_base_moof flag).

This makes the moof atoms slightly bigger, but can be better for
playback (improving locality of sample data in the mdat).

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-16 13:23:19 +02:00
Martin Storsjö 50ff0c05b6 movenc: Support writing multiple trun atoms
This is needed if all the data for one track isn't continuous
within the mdat. Normally we make sure all the data for one
track is continuous, but in new cases we will need to have
the samples interleaved.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-16 13:23:19 +02:00
Martin Storsjö 448c8cfe4c movenc: Support setting fragment_index before the moov atom is written
This way, the caller doesn't need to coordinate setting the option
after the moov atom has been written. The downside is that it is
no longer possible to use the option for checking whether the moov
atom already has been written, but a caller is able to keep track
of that by other means anyway.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-10 10:41:06 +02:00
Martin Storsjö 0c5e380c2c movenc: Don't rely on the fragment index for vc1 info gathering
The previous use of the mov->fragments field, for determining whether
written packets were part of the first fragment or not, didn't
work as intended when using the empty_moov flag.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-10 10:41:03 +02:00
Martin Storsjö 46d4d85759 movenc: Avoid writing separate flags for the first sample if not necessary
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-09 10:36:12 +02:00
Martin Storsjö 00d751d4fc movenc: Set tfhd default sample flags based on actual samples, if possible
This avoids assuming that e.g. audio samples are marked as
sync samples.

This allows omitting the sample flags from trun, if the default
flags happen to be right for all the samples.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-09 10:36:02 +02:00
Martin Storsjö 9731cf4001 movenc: Keep writing zero-entry stts atoms as intended
a876585215 had the unintended side effect of returning AVERROR(ENOMEM)
when track->entry is zero, while the code intentionally wants to
continue in that case.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-06 16:17:48 +02:00