mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-04 14:12:03 +00:00
Merge commit '2cb9c2fc59c9267ad2631c07c81c188058502259'
* commit '2cb9c2fc59c9267ad2631c07c81c188058502259': movenc: Allow interleaving samples when writing fragmented files Conflicts: libavformat/movenc.c libavformat/movenc.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
ae65cc7ed3
@ -81,6 +81,7 @@ static const AVOption options[] = {
|
|||||||
{ "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, 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},
|
||||||
{ "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
{ "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
||||||
{ "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
|
{ "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
|
||||||
|
{ "frag_interleave", "Interleave samples within fragments (max number of consecutive samples, lower is tighter interleaving, but with more overhead)", offsetof(MOVMuxContext, frag_interleave), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4056,6 +4057,32 @@ static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
|
||||||
|
{
|
||||||
|
MOVMuxContext *mov = s->priv_data;
|
||||||
|
int ret, buf_size;
|
||||||
|
uint8_t *buf;
|
||||||
|
int i, offset;
|
||||||
|
|
||||||
|
if (!track->mdat_buf)
|
||||||
|
return 0;
|
||||||
|
if (!mov->mdat_buf) {
|
||||||
|
if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
|
||||||
|
track->mdat_buf = NULL;
|
||||||
|
|
||||||
|
offset = avio_tell(mov->mdat_buf);
|
||||||
|
avio_write(mov->mdat_buf, buf, buf_size);
|
||||||
|
av_free(buf);
|
||||||
|
|
||||||
|
for (i = track->entries_flushed; i < track->entry; i++)
|
||||||
|
track->cluster[i].pos += offset;
|
||||||
|
track->entries_flushed = track->entry;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mov_flush_fragment(AVFormatContext *s)
|
static int mov_flush_fragment(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
MOVMuxContext *mov = s->priv_data;
|
MOVMuxContext *mov = s->priv_data;
|
||||||
@ -4115,15 +4142,29 @@ static int mov_flush_fragment(AVFormatContext *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mov->frag_interleave) {
|
||||||
|
for (i = 0; i < mov->nb_streams; i++) {
|
||||||
|
MOVTrack *track = &mov->tracks[i];
|
||||||
|
int ret;
|
||||||
|
if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mov->mdat_buf)
|
||||||
|
return 0;
|
||||||
|
mdat_size = avio_tell(mov->mdat_buf);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < mov->nb_streams; i++) {
|
for (i = 0; i < mov->nb_streams; i++) {
|
||||||
MOVTrack *track = &mov->tracks[i];
|
MOVTrack *track = &mov->tracks[i];
|
||||||
if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF)
|
if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
|
||||||
track->data_offset = 0;
|
track->data_offset = 0;
|
||||||
else
|
else
|
||||||
track->data_offset = mdat_size;
|
track->data_offset = mdat_size;
|
||||||
if (!track->mdat_buf)
|
if (!track->entry)
|
||||||
continue;
|
continue;
|
||||||
mdat_size += avio_tell(track->mdat_buf);
|
if (track->mdat_buf)
|
||||||
|
mdat_size += avio_tell(track->mdat_buf);
|
||||||
if (first_track < 0)
|
if (first_track < 0)
|
||||||
first_track = i;
|
first_track = i;
|
||||||
}
|
}
|
||||||
@ -4162,10 +4203,18 @@ static int mov_flush_fragment(AVFormatContext *s)
|
|||||||
if (track->entry)
|
if (track->entry)
|
||||||
track->frag_start += duration;
|
track->frag_start += duration;
|
||||||
track->entry = 0;
|
track->entry = 0;
|
||||||
if (!track->mdat_buf)
|
track->entries_flushed = 0;
|
||||||
continue;
|
if (!mov->frag_interleave) {
|
||||||
buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
|
if (!track->mdat_buf)
|
||||||
track->mdat_buf = NULL;
|
continue;
|
||||||
|
buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
|
||||||
|
track->mdat_buf = NULL;
|
||||||
|
} else {
|
||||||
|
if (!mov->mdat_buf)
|
||||||
|
continue;
|
||||||
|
buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
|
||||||
|
mov->mdat_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
avio_write(s->pb, buf, buf_size);
|
avio_write(s->pb, buf, buf_size);
|
||||||
av_free(buf);
|
av_free(buf);
|
||||||
@ -4219,6 +4268,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
|
if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
|
||||||
int ret;
|
int ret;
|
||||||
if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
|
if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
|
||||||
|
if (mov->frag_interleave && mov->fragments > 0) {
|
||||||
|
if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
|
||||||
|
if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!trk->mdat_buf) {
|
if (!trk->mdat_buf) {
|
||||||
if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
|
if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -4882,6 +4938,21 @@ static int mov_write_header(AVFormatContext *s)
|
|||||||
if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
|
if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
|
||||||
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
|
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
|
||||||
|
|
||||||
|
/* Clear the omit_tfhd_offset flag if default_base_moof is set;
|
||||||
|
* if the latter is set that's enough and omit_tfhd_offset doesn't
|
||||||
|
* add anything extra on top of that. */
|
||||||
|
if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
|
||||||
|
mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
|
||||||
|
mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;
|
||||||
|
|
||||||
|
if (mov->frag_interleave &&
|
||||||
|
mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {
|
||||||
|
av_log(s, AV_LOG_ERROR,
|
||||||
|
"Sample interleaving in fragments is mutually exclusive with "
|
||||||
|
"omit_tfhd_offset and separate_moof\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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 &&
|
||||||
|
@ -131,6 +131,7 @@ typedef struct MOVTrack {
|
|||||||
int64_t data_offset;
|
int64_t data_offset;
|
||||||
int64_t frag_start;
|
int64_t frag_start;
|
||||||
int frag_discont;
|
int frag_discont;
|
||||||
|
int entries_flushed;
|
||||||
|
|
||||||
int nb_frag_info;
|
int nb_frag_info;
|
||||||
MOVFragmentInfo *frag_info;
|
MOVFragmentInfo *frag_info;
|
||||||
@ -189,6 +190,8 @@ typedef struct MOVMuxContext {
|
|||||||
|
|
||||||
int use_editlist;
|
int use_editlist;
|
||||||
float gamma;
|
float gamma;
|
||||||
|
|
||||||
|
int frag_interleave;
|
||||||
} MOVMuxContext;
|
} MOVMuxContext;
|
||||||
|
|
||||||
#define FF_MOV_FLAG_RTP_HINT (1 << 0)
|
#define FF_MOV_FLAG_RTP_HINT (1 << 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user