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>
This commit is contained in:
Martin Storsjö 2015-10-20 22:30:03 +03:00
parent e02dcdf6bb
commit 5ea5a24eb7
1 changed files with 8 additions and 8 deletions

View File

@ -3167,7 +3167,7 @@ static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
return 0; return 0;
} }
static int mov_flush_fragment(AVFormatContext *s) static int mov_flush_fragment(AVFormatContext *s, int force)
{ {
MOVMuxContext *mov = s->priv_data; MOVMuxContext *mov = s->priv_data;
int i, first_track = -1; int i, first_track = -1;
@ -3214,7 +3214,7 @@ static int mov_flush_fragment(AVFormatContext *s)
if (!mov->tracks[i].entry) if (!mov->tracks[i].entry)
break; break;
/* Don't write the initial moov unless all tracks have data */ /* Don't write the initial moov unless all tracks have data */
if (i < mov->nb_streams) if (i < mov->nb_streams && !force)
return 0; return 0;
if ((ret = ffio_open_null_buf(&moov_buf)) < 0) if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
@ -3343,17 +3343,17 @@ static int mov_flush_fragment(AVFormatContext *s)
return 0; return 0;
} }
static int mov_auto_flush_fragment(AVFormatContext *s) static int mov_auto_flush_fragment(AVFormatContext *s, int force)
{ {
MOVMuxContext *mov = s->priv_data; MOVMuxContext *mov = s->priv_data;
int had_moov = mov->moov_written; int had_moov = mov->moov_written;
int ret = mov_flush_fragment(s); int ret = mov_flush_fragment(s, force);
if (ret < 0) if (ret < 0)
return ret; return ret;
// If using delay_moov, the first flush only wrote the moov, // If using delay_moov, the first flush only wrote the moov,
// not the actual moof+mdat pair, thus flush once again. // not the actual moof+mdat pair, thus flush once again.
if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV) if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
ret = mov_flush_fragment(s); ret = mov_flush_fragment(s, force);
return ret; return ret;
} }
@ -3568,7 +3568,7 @@ err:
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
{ {
if (!pkt) { if (!pkt) {
mov_flush_fragment(s); mov_flush_fragment(s, 1);
return 1; return 1;
} else { } else {
MOVMuxContext *mov = s->priv_data; MOVMuxContext *mov = s->priv_data;
@ -3604,7 +3604,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
// for the other ones that are flushed at the same time. // for the other ones that are flushed at the same time.
trk->track_duration = pkt->dts - trk->start_dts; trk->track_duration = pkt->dts - trk->start_dts;
trk->end_pts = pkt->pts; trk->end_pts = pkt->pts;
mov_auto_flush_fragment(s); mov_auto_flush_fragment(s, 0);
} }
} }
@ -4243,7 +4243,7 @@ static int mov_write_trailer(AVFormatContext *s)
mov_write_moov_tag(pb, mov, s); mov_write_moov_tag(pb, mov, s);
} }
} else { } else {
mov_auto_flush_fragment(s); mov_auto_flush_fragment(s, 1);
for (i = 0; i < mov->nb_streams; i++) for (i = 0; i < mov->nb_streams; i++)
mov->tracks[i].data_offset = 0; mov->tracks[i].data_offset = 0;
if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) { if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {