summaryrefslogtreecommitdiff
path: root/libavformat/movenc.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-02-23 02:33:21 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-02-23 04:31:55 +0100
commite99f1a8cc8b90926209b7390ae3f50d519c0e63f (patch)
treeb50f42ffe92fdb5fb2bc1efeaf9625d208e9c6ca /libavformat/movenc.c
parent094673ff1b1a0f83584f3aeea76a3e9c9e3129bf (diff)
parent562ebc30775db243941db3c96396e7bf8a0e0a44 (diff)
downloadffmpeg-e99f1a8cc8b90926209b7390ae3f50d519c0e63f.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: dxva2: don't check for DXVA_PictureParameters->wDecodedPictureIndex img2: split muxer and demuxer into separate files rm: prevent infinite loops for index parsing. aac: fix infinite loop on end-of-frame with sequence of 1-bits. mov: Add more HDV and XDCAM FourCCs. lavf: don't set AVCodecContext.has_b_frames in compute_pkt_fields(). rmdec: when using INT4 deinterleaving, error out if sub_packet_h <= 1. cdxl: correctly synchronize video timestamps to audio mlpdec_parser: fix a few channel layouts. Add channel names to channel_names[] array for channels added in b2890f5 movenc: Buffer the mdat for the initial moov fragment, too flvdec: Ignore the index if the ignidx flag is set flvdec: Fix indentation movdec: Don't parse all fragments if ignidx is set movdec: Restart parsing root-level atoms at the right spot prores: use natural integer type for the codebook index mov: Add support for MPEG2 HDV 720p24 (hdv4) swscale: K&R formatting cosmetics (part I) swscale: variable declaration and placement cosmetics Conflicts: configure libavcodec/aacdec.c libavcodec/mlp_parser.c libavformat/flvdec.c libavformat/img2.c libavformat/isom.h libavformat/mov.c libavformat/movenc.c libswscale/rgb2rgb.c libswscale/rgb2rgb_template.c libswscale/yuv2rgb.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r--libavformat/movenc.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index b5e8770353..138c00fcb4 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -99,9 +99,9 @@ static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
if(!track->cluster[i].chunkNum)
continue;
if(mode64 == 1)
- avio_wb64(pb, track->cluster[i].pos);
+ avio_wb64(pb, track->cluster[i].pos + track->data_offset);
else
- avio_wb32(pb, track->cluster[i].pos);
+ avio_wb32(pb, track->cluster[i].pos + track->data_offset);
}
return update_size(pb, pos);
}
@@ -2036,6 +2036,8 @@ static void build_chunks(MOVTrack *trk)
MOVIentry *chunk= &trk->cluster[0];
uint64_t chunkSize = chunk->size;
chunk->chunkNum= 1;
+ if (trk->chunkCount)
+ return;
trk->chunkCount= 1;
for(i=1; i<trk->entry; i++){
if(chunk->pos + chunkSize == trk->cluster[i].pos &&
@@ -2739,6 +2741,10 @@ static int mov_flush_fragment(AVFormatContext *s)
if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) && mov->fragments == 0) {
int64_t pos = avio_tell(s->pb);
+ int ret;
+ AVIOContext *moov_buf;
+ uint8_t *buf;
+ int buf_size;
for (i = 0; i < mov->nb_streams; i++)
if (!mov->tracks[i].entry)
@@ -2746,10 +2752,24 @@ static int mov_flush_fragment(AVFormatContext *s)
/* Don't write the initial moov unless all tracks have data */
if (i < mov->nb_streams)
return 0;
- avio_seek(s->pb, mov->mdat_pos, SEEK_SET);
- avio_wb32(s->pb, mov->mdat_size + 8);
- avio_seek(s->pb, pos, SEEK_SET);
+
+ if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
+ return ret;
+ mov_write_moov_tag(moov_buf, mov, s);
+ buf_size = avio_close_dyn_buf(moov_buf, &buf);
+ av_free(buf);
+ for (i = 0; i < mov->nb_streams; i++)
+ mov->tracks[i].data_offset = pos + buf_size + 8;
+
mov_write_moov_tag(s->pb, mov, s);
+
+ buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
+ mov->mdat_buf = NULL;
+ avio_wb32(s->pb, buf_size + 8);
+ ffio_wfourcc(s->pb, "mdat");
+ avio_write(s->pb, buf, buf_size);
+ av_free(buf);
+
mov->fragments++;
mov->mdat_size = 0;
for (i = 0; i < mov->nb_streams; i++) {
@@ -2862,13 +2882,21 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
mov_flush_fragment(s);
}
- if (mov->flags & FF_MOV_FLAG_FRAGMENT && mov->fragments > 0) {
- if (!trk->mdat_buf) {
- int ret;
- if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
- return ret;
+ if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
+ int ret;
+ if (mov->fragments > 0) {
+ if (!trk->mdat_buf) {
+ if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
+ return ret;
+ }
+ pb = trk->mdat_buf;
+ } else {
+ if (!mov->mdat_buf) {
+ if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
+ return ret;
+ }
+ pb = mov->mdat_buf;
}
- pb = trk->mdat_buf;
}
if (enc->codec_id == CODEC_ID_AMR_NB) {
@@ -3038,11 +3066,18 @@ static int mov_write_header(AVFormatContext *s)
AVDictionaryEntry *t;
int i, hint_track = 0;
- /* Non-seekable output is ok if EMPTY_MOOV is set, or if using the ismv
- * format (which sets EMPTY_MOOV later in this function). If ism_lookahead
+ /* Set the FRAGMENT flag if any of the fragmentation methods are
+ * enabled. */
+ if (mov->max_fragment_duration || mov->max_fragment_size ||
+ mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
+ FF_MOV_FLAG_FRAG_KEYFRAME |
+ FF_MOV_FLAG_FRAG_CUSTOM))
+ mov->flags |= FF_MOV_FLAG_FRAGMENT;
+
+ /* 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 &&
- ((!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) &&
+ ((!(mov->flags & FF_MOV_FLAG_FRAGMENT) &&
!(s->oformat && !strcmp(s->oformat->name, "ismv")))
|| mov->ism_lookahead)) {
av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
@@ -3181,7 +3216,8 @@ static int mov_write_header(AVFormatContext *s)
FF_MOV_FLAG_FRAG_CUSTOM)) &&
!mov->max_fragment_duration && !mov->max_fragment_size)
mov->max_fragment_duration = 5000000;
- mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF;
+ mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
+ FF_MOV_FLAG_FRAGMENT;
}
if(mov->reserved_moov_size){
@@ -3189,15 +3225,7 @@ static int mov_write_header(AVFormatContext *s)
avio_skip(pb, mov->reserved_moov_size);
}
- /* Set the FRAGMENT flag if any of the fragmentation methods are
- * enabled. */
- if (mov->max_fragment_duration || mov->max_fragment_size ||
- mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
- FF_MOV_FLAG_FRAG_KEYFRAME |
- FF_MOV_FLAG_FRAG_CUSTOM))
- mov->flags |= FF_MOV_FLAG_FRAGMENT;
-
- if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV))
+ if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
mov_write_mdat_tag(pb, mov);
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))