mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
movenc: Allow to request not to use edit lists
In this case, shift tracks to start from zero instead (potentially stretching the first sample in tracks that start later than the first one). Some software does not support edit lists at all, the adobe flash player seems to be one of these. This results in AV sync errors when edit lists are used to adjust AV sync. Some players, such as QuickTime, don't respect the duration for audio packets, so if an audio track starts later than the video track and the first audio sample gets a duration longer than the actual amount of data in it, the result will be out of sync. Based on patches by Michael Niedermayer. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
897d5c3a42
commit
1d8a0c1b43
@ -68,6 +68,7 @@ static const AVOption options[] = {
|
||||
{ "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
||||
{ "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
||||
{ "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
|
||||
{ "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@ -1773,7 +1774,11 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
|
||||
if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||
|
||||
(track->entry && track->cluster[0].dts) ||
|
||||
is_clcp_track(track)) {
|
||||
mov_write_edts_tag(pb, mov, track); // PSP Movies require edts box
|
||||
if (mov->use_editlist)
|
||||
mov_write_edts_tag(pb, mov, track); // PSP Movies require edts box
|
||||
else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
|
||||
av_log(mov->fc, AV_LOG_WARNING,
|
||||
"Not writing any edit list even though one would have been required\n");
|
||||
}
|
||||
if (track->tref_tag)
|
||||
mov_write_tref_tag(pb, track);
|
||||
@ -3148,6 +3153,15 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
* of this packet to be what the previous packets duration implies. */
|
||||
trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
|
||||
}
|
||||
if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
|
||||
s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
|
||||
/* Not using edit lists and shifting the first track to start from zero.
|
||||
* If the other streams start from a later timestamp, we won't be able
|
||||
* to signal the difference in starting time without an edit list.
|
||||
* Thus move the timestamp for this first sample to 0, increasing
|
||||
* its duration instead. */
|
||||
trk->cluster[trk->entry].dts = trk->start_dts = 0;
|
||||
}
|
||||
if (trk->start_dts == AV_NOPTS_VALUE) {
|
||||
trk->start_dts = pkt->dts;
|
||||
if (pkt->dts && mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
|
||||
@ -3462,6 +3476,23 @@ static int mov_write_header(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (mov->use_editlist < 0) {
|
||||
mov->use_editlist = 1;
|
||||
if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
|
||||
// If we can avoid needing an edit list by shifting the
|
||||
// tracks, prefer that over (trying to) write edit lists
|
||||
// in fragmented output.
|
||||
if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
|
||||
s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
|
||||
mov->use_editlist = 0;
|
||||
}
|
||||
}
|
||||
if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && mov->use_editlist)
|
||||
av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov\n");
|
||||
|
||||
if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
|
||||
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
|
||||
|
||||
/* Non-seekable output is ok if using fragmentation. If ism_lookahead
|
||||
* is enabled, we don't support non-seekable output at all. */
|
||||
if (!s->pb->seekable &&
|
||||
|
@ -166,6 +166,8 @@ typedef struct MOVMuxContext {
|
||||
|
||||
int per_stream_grouping;
|
||||
AVFormatContext *fc;
|
||||
|
||||
int use_editlist;
|
||||
} MOVMuxContext;
|
||||
|
||||
#define FF_MOV_FLAG_RTP_HINT (1 << 0)
|
||||
|
Loading…
Reference in New Issue
Block a user