|
|
@@ -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}, |
|
|
{ "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}, |
|
|
{ "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 }, |
|
|
{ "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 }, |
|
|
{ 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 || |
|
|
if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS || |
|
|
(track->entry && track->cluster[0].dts) || |
|
|
(track->entry && track->cluster[0].dts) || |
|
|
is_clcp_track(track)) { |
|
|
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) |
|
|
if (track->tref_tag) |
|
|
mov_write_tref_tag(pb, track); |
|
|
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. */ |
|
|
* of this packet to be what the previous packets duration implies. */ |
|
|
trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration; |
|
|
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) { |
|
|
if (trk->start_dts == AV_NOPTS_VALUE) { |
|
|
trk->start_dts = pkt->dts; |
|
|
trk->start_dts = pkt->dts; |
|
|
if (pkt->dts && mov->flags & FF_MOV_FLAG_EMPTY_MOOV) |
|
|
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 |
|
|
/* Non-seekable output is ok if using fragmentation. If ism_lookahead |
|
|
* is enabled, we don't support non-seekable output at all. */ |
|
|
* is enabled, we don't support non-seekable output at all. */ |
|
|
if (!s->pb->seekable && |
|
|
if (!s->pb->seekable && |
|
|
|