diff options
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r-- | libavformat/movenc.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index fb8749c..efa0b92 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -4,20 +4,20 @@ * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org> * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -44,6 +44,7 @@ static const AVOption options[] = { { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 }, FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), { NULL }, }; @@ -267,10 +268,20 @@ static void putDescr(AVIOContext *pb, int tag, unsigned int size) avio_w8(pb, size & 0x7F); } +static unsigned compute_avg_bitrate(MOVTrack *track) +{ + uint64_t size = 0; + int i; + for (i = 0; i < track->entry; i++) + size += track->cluster[i].size; + return size * 8 * track->timescale / track->trackDuration; +} + static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic { int64_t pos = avio_tell(pb); int decoderSpecificInfoLen = track->vosLen ? 5+track->vosLen : 0; + unsigned avg_bitrate; avio_wb32(pb, 0); // size ffio_wfourcc(pb, "esds"); @@ -302,11 +313,10 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic avio_w8(pb, track->enc->rc_buffer_size>>(3+16)); // Buffersize DB (24 bits) avio_wb16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB - avio_wb32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window) - if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0) - avio_wb32(pb, 0); // vbr - else - avio_wb32(pb, track->enc->rc_max_rate); // avg bitrate + avg_bitrate = compute_avg_bitrate(track); + // maxbitrate (FIXME should be max rate in any 1 sec window) + avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate)); + avio_wb32(pb, avg_bitrate); if (track->vosLen) { // DecoderSpecific info descriptor @@ -2004,7 +2014,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if (enc->codec_id == CODEC_ID_AMR_NB) { /* We must find out how many AMR blocks there are in one packet */ static uint16_t packed_size[16] = - {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0}; + {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1}; int len = 0; while (len < size && samplesInChunk < 100) { @@ -2034,6 +2044,10 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) /* from x264 or from bytestream h264 */ /* nal reformating needed */ size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); + } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 && + (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { + av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n"); + return -1; } else { avio_write(pb, pkt->data, size); } @@ -2049,7 +2063,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) { - trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster)); + trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE)); if (!trk->cluster) return -1; } @@ -2261,6 +2275,11 @@ static int mov_write_header(AVFormatContext *s) av_set_pts_info(st, 64, 1, track->timescale); } + if(mov->reserved_moov_size){ + mov->reserved_moov_pos= avio_tell(pb); + avio_skip(pb, mov->reserved_moov_size); + } + mov_write_mdat_tag(pb, mov); #if FF_API_TIMESTAMP @@ -2315,9 +2334,21 @@ static int mov_write_trailer(AVFormatContext *s) ffio_wfourcc(pb, "mdat"); avio_wb64(pb, mov->mdat_size+16); } - avio_seek(pb, moov_pos, SEEK_SET); + avio_seek(pb, mov->reserved_moov_size ? mov->reserved_moov_pos : moov_pos, SEEK_SET); mov_write_moov_tag(pb, mov, s); + if(mov->reserved_moov_size){ + int64_t size= mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos); + if(size < 8){ + av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %Ld additional\n", 8-size); + return -1; + } + avio_wb32(pb, size); + ffio_wfourcc(pb, "free"); + for(i=0; i<size; i++) + avio_w8(pb, 0); + avio_seek(pb, moov_pos, SEEK_SET); + } if (mov->chapter_track) av_freep(&mov->tracks[mov->chapter_track].enc); |