X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;ds=sidebyside;f=synfig-core%2Ftags%2Fsynfig_0_61_04%2Fsynfig-core%2Fsrc%2Fmodules%2Fmod_libavcodec%2Flibavformat%2Fmovenc.c;fp=synfig-core%2Ftags%2Fsynfig_0_61_04%2Fsynfig-core%2Fsrc%2Fmodules%2Fmod_libavcodec%2Flibavformat%2Fmovenc.c;h=0000000000000000000000000000000000000000;hb=6fa8f2f38d4b0b35f8539bf94e27ae27015c7689;hp=e3e612ff6c90cf729b9b5a8f35ebbd09e02d6be8;hpb=47fce282611fbba1044921d22ca887f9b53ad91a;p=synfig.git diff --git a/synfig-core/tags/synfig_0_61_04/synfig-core/src/modules/mod_libavcodec/libavformat/movenc.c b/synfig-core/tags/synfig_0_61_04/synfig-core/src/modules/mod_libavcodec/libavformat/movenc.c deleted file mode 100644 index e3e612f..0000000 --- a/synfig-core/tags/synfig_0_61_04/synfig-core/src/modules/mod_libavcodec/libavformat/movenc.c +++ /dev/null @@ -1,826 +0,0 @@ -/* - * MOV, 3GP, MP4 encoder. - * Copyright (c) 2003 Thomas Raivio. - * - * This library 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 of the License, or (at your option) any later version. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "avformat.h" -#include "avio.h" -#include - -#undef NDEBUG -#include - -/* - * Limitations - * - Currently supports h.263, MPEG4 video codecs, and AMR audio codec. - */ - -#define MOV_INDEX_CLUSTER_SIZE 16384 -#define globalTimescale 1000 - -typedef struct MOVIentry { - unsigned int flags, pos, len; - unsigned int entries; -} MOVIentry; - -typedef struct MOVIndex { - int entry; - int samples; - int mdat_size; - offset_t mdat_pos; - int ents_allocated; - long timescale; - long time; - long frameDuration; - long sampleDelta; - int trackID; - AVCodecContext *enc; - - int vosLen; - uint8_t *vosData; - MOVIentry** cluster; -} MOVTrack; - -typedef struct { - long time; - int nb_streams; - offset_t movi_list; - long timescale; - MOVTrack tracks[MAX_STREAMS]; -} MOVContext; - -//FIXME supprt 64bit varaint with wide placeholders -static int updateSize (ByteIOContext *pb, int pos) -{ - long curpos = url_ftell(pb); - url_fseek(pb, pos, SEEK_SET); - put_be32(pb, curpos - pos); /* rewrite size */ - url_fseek(pb, curpos, SEEK_SET); - - return curpos - pos; -} - -static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack* track) -{ - int i; - put_be32(pb, 16+track->entry*4); /* size */ - put_tag(pb, "stco"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, track->entry); /* entry count */ - for (i=0; ientry; i++) { - int cl = i / MOV_INDEX_CLUSTER_SIZE; - int id = i % MOV_INDEX_CLUSTER_SIZE; - put_be32(pb, track->cluster[cl][id].pos); - } - return 16+track->entry*4; -} - -static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack* track) -{ - int i, size; - - if(track->cluster[0][0].entries != 0) - size = 20; - else - size = 20+track->samples*4; - put_be32(pb, size); /* size */ - put_tag(pb, "stsz"); - put_be32(pb, 0); /* version & flags */ - - /* TODO: Ugly (and false) assumption: if we have a chunk of samples, assume - * all sizes are same */ - if(track->cluster[0][0].entries != 0) { - int sSize = track->cluster[0][0].len/track->cluster[0][0].entries; - put_be32(pb, sSize); /* sample size */ - put_be32(pb, track->samples); /* sample count */ - } - else - { - put_be32(pb, 0); /* sample size */ - put_be32(pb, track->samples); /* sample count */ - for (i=0; isamples; i++) { - int cl = i / MOV_INDEX_CLUSTER_SIZE; - int id = i % MOV_INDEX_CLUSTER_SIZE; - put_be32(pb, track->cluster[cl][id].len); - } - } - return size; -} - -static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack* track) -{ - int size; - if(track->cluster[0][0].entries != 0) - size = 16+track->entry*4*3; - else - size = 0x1c; - put_be32(pb, size); // size - put_tag(pb, "stsc"); - put_be32(pb, 0); // version & flags - if(track->cluster[0][0].entries != 0) { - int i; - put_be32(pb, track->entry); // entry count - for (i=0; ientry; i++) { - int cl = i / MOV_INDEX_CLUSTER_SIZE; - int id = i % MOV_INDEX_CLUSTER_SIZE; - put_be32(pb, i+1); // first chunk - put_be32(pb, track->cluster[cl][id].entries); - put_be32(pb, 0x1); // sample description index - } - } - else { - put_be32(pb, 1); // entry count - put_be32(pb, 0x1); // first chunk - put_be32(pb, 0x1); // samples per chunk - put_be32(pb, 0x1); // sample description index - } - - return size; -} - -//FIXME keyframes? -static int mov_write_stss_tag(ByteIOContext *pb) //TRA OK -{ - put_be32(pb, 0x14); /* size */ - put_tag(pb, "stss"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, 1); /* entry count */ - put_be32(pb, 0x1); /* sample number */ - return 0x14; -} - -static int mov_write_damr_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x11); /* size */ - put_tag(pb, "damr"); - put_tag(pb, "FFMP"); - put_byte(pb, 0); - put_be16(pb, 0x81ff); /* Mode set (all modes for AMR_NB) */ - put_be16(pb, 1); /* Mode change period (no restriction) */ - return 0x11; -} - -static int mov_write_samr_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - /* "samr" for AMR NB, "sawb" for AMR WB */ - put_tag(pb, "samr"); - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index, XXX == 1 */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - - put_be16(pb, 2); /* Reserved */ - put_be16(pb, 0x10); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be16(pb, track->timescale); /* Time scale */ - put_be16(pb, 0); /* Reserved */ - - mov_write_damr_tag(pb); - return updateSize (pb, pos); -} - -static int mov_write_d263_tag(ByteIOContext *pb) -{ - put_be32(pb, 0xf); /* size */ - put_tag(pb, "d263"); - put_tag(pb, "FFMP"); - put_be16(pb, 0x0a); - put_byte(pb, 0); - return 0xf; -} - -static int mov_write_s263_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "s263"); - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be16(pb, track->enc->width); /* Video width */ - put_be16(pb, track->enc->height); /* Video height */ - put_be32(pb, 0x00480000); /* Reserved */ - put_be32(pb, 0x00480000); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0x18); /* Reserved */ - put_be16(pb, 0xffff); /* Reserved */ - mov_write_d263_tag(pb); - return updateSize (pb, pos); -} - -static unsigned int esdsLength(unsigned int len) -{ - unsigned int result = 0; - unsigned char b = len & 0x7f; - result += b; - b = (len >> 8) & 0x7f; - result += (b + 0x80) << 8; - b = (len >> 16) & 0x7f; - result += (b + 0x80) << 16; - b = (len >> 24) & 0x7f; - result += (b + 0x80) << 24; - return result; -} - -static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic -{ - put_be32(pb, track->vosLen+18+14+17); - put_tag(pb, "esds"); - put_be32(pb, 0); // Version - - put_byte(pb, 0x03); // tag = ES_DescriptorTag - put_be32(pb, esdsLength(track->vosLen+18+14)); // Length - put_be16(pb, 0x0001); // ID (= 1) - put_byte(pb, 0x00); // flags (= no flags) - -// Decoderconfigdescriptor = 4 - put_byte(pb, 0x04); // tag = DecoderConfigDescriptor - put_be32(pb, esdsLength(track->vosLen+18)); // Length - put_byte(pb, 0x20); // Object type indication (Visual 14496-2) - put_byte(pb, 0x11); // flags (= Visualstream) - put_byte(pb, 0x0); // Buffersize DB (24 bits) - put_be16(pb, 0x0dd2); // Buffersize DB - - // TODO: find real values for these - put_be32(pb, 0x0002e918); // maxbitrate - put_be32(pb, 0x00017e6b); // avg bitrate - -// Decoderspecific info Tag = 5 - put_byte(pb, 0x05); // tag = Decoderspecific info - put_be32(pb, esdsLength(track->vosLen)); // length - put_buffer(pb, track->vosData, track->vosLen); - - put_byte(pb, 0x06); - put_be32(pb, esdsLength(1)); // length - put_byte(pb, 0x02); - return track->vosLen+18+14+17; -} - -static int mov_write_mp4v_tag(ByteIOContext *pb, MOVTrack* track) // Basic -{ - int pos = url_ftell(pb); - - put_be32(pb, 0); - put_tag(pb, "mp4v"); - put_be32(pb, 0); // Reserved - put_be16(pb, 0); // Reserved - put_be16(pb, 1); // Data-reference index - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be16(pb, track->enc->width); // Width - put_be16(pb, track->enc->height); // Height - put_be32(pb, 0x00480000); // Reserved - put_be32(pb, 0x00480000); // Reserved - put_be32(pb, 0); // Reserved - put_be16(pb, 1); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be32(pb, 0); // Reserved - put_be16(pb, 24); // Reserved - put_be16(pb, 0xFFFF); // Reserved - mov_write_esds_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "stsd"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, 1); /* entry count */ - if (track->enc->codec_type == CODEC_TYPE_VIDEO) { - if (track->enc->codec_id == CODEC_ID_H263) - mov_write_s263_tag(pb, track); - else if (track->enc->codec_id == CODEC_ID_MPEG4) - mov_write_mp4v_tag(pb, track); - } - else if (track->enc->codec_type == CODEC_TYPE_AUDIO) { - if (track->enc->codec_id == CODEC_ID_AMR_NB) - mov_write_samr_tag(pb, track); - } - return updateSize(pb, pos); -} - -static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track) -{ - put_be32(pb, 0x18); /* size */ - put_tag(pb, "stts"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, 1); /* entry count */ - - put_be32(pb, track->samples); /* sample count */ - put_be32(pb, track->sampleDelta); /* sample delta */ - return 0x18; -} - -static int mov_write_dref_tag(ByteIOContext *pb) -{ - put_be32(pb, 28); /* size */ - put_tag(pb, "dref"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, 1); /* entry count */ - - put_be32(pb, 0xc); /* size */ - put_tag(pb, "url "); - put_be32(pb, 1); /* version & flags */ - - return 28; -} - -static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "stbl"); - mov_write_stsd_tag(pb, track); - mov_write_stts_tag(pb, track); - if (track->enc->codec_type == CODEC_TYPE_VIDEO) - mov_write_stss_tag(pb); - mov_write_stsc_tag(pb, track); - mov_write_stsz_tag(pb, track); - mov_write_stco_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_dinf_tag(ByteIOContext *pb) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "dinf"); - mov_write_dref_tag(pb); - return updateSize(pb, pos); -} - -static int mov_write_smhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 16); /* size */ - put_tag(pb, "smhd"); - put_be32(pb, 0); /* version & flags */ - put_be16(pb, 0); /* reserved (balance, normally = 0) */ - put_be16(pb, 0); /* reserved */ - return 16; -} - -static int mov_write_vmhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x14); /* size (always 0x14) */ - put_tag(pb, "vmhd"); - put_be32(pb, 0x01); /* version & flags */ - put_be64(pb, 0); /* reserved (graphics mode = copy) */ - return 0x14; -} - -static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "minf"); - if(track->enc->codec_type == CODEC_TYPE_VIDEO) - mov_write_vmhd_tag(pb); - else - mov_write_smhd_tag(pb); - mov_write_dinf_tag(pb); - mov_write_stbl_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track) -{ - int size = 0; - size = 45; - put_be32(pb, size); /* size */ - put_tag(pb, "hdlr"); - put_be32(pb, 0); /* Version & flags */ - put_be32(pb, 0); /* reserved */ - if(track->enc->codec_type == CODEC_TYPE_VIDEO) - put_tag(pb, "vide"); /* handler type */ - else - put_tag(pb, "soun"); /* handler type */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - put_byte(pb, 0); /* reserved */ - if(track->enc->codec_type == CODEC_TYPE_VIDEO) - put_buffer(pb, "VideoHandler", 13); - else - put_buffer(pb, "SoundHandler", 13); - return size; -} - -static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track) -{ - put_be32(pb, 32); /* size */ - put_tag(pb, "mdhd"); - put_be32(pb, 0); /* Version & flags */ - put_be32(pb, track->time); /* creation time */ - put_be32(pb, track->time); /* modification time */ - put_be32(pb, track->timescale); /* time scale */ - - put_be32(pb, track->timescale*track->entry*track->frameDuration/globalTimescale); /* duration */ - put_be16(pb, 0); /* language, 0 = english */ - put_be16(pb, 0); /* reserved (quality) */ - return 32; -} - -static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "mdia"); - mov_write_mdhd_tag(pb, track); - mov_write_hdlr_tag(pb, track); - mov_write_minf_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track) -{ - put_be32(pb, 0x5c); /* size (always 0x5c) */ - put_tag(pb, "tkhd"); - put_be32(pb, 1); /* version & flags (track enabled) */ - put_be32(pb, track->time); /* creation time */ - put_be32(pb, track->time); /* modification time */ - put_be32(pb, track->trackID); /* track-id */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, track->entry*track->frameDuration); /* duration */ - - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */ - /* Volume, only for audio */ - if(track->enc->codec_type == CODEC_TYPE_AUDIO) - put_be16(pb, 0x0100); - else - put_be16(pb, 0); - put_be16(pb, 0); /* reserved */ - - /* Matrix structure */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x40000000); /* reserved */ - - /* Track width and height, for visual only */ - if(track->enc->codec_type == CODEC_TYPE_VIDEO) { - put_be32(pb, 0x01400000); - put_be32(pb, 0x00f00000); - } - else { - put_be32(pb, 0); - put_be32(pb, 0); - } - return 0x5c; -} - -static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track) -{ - int pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "trak"); - mov_write_tkhd_tag(pb, track); - mov_write_mdia_tag(pb, track); - return updateSize(pb, pos); -} - -/* TODO: Not sorted out, but not necessary either */ -static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov) -{ - put_be32(pb, 0x15); /* size */ - put_tag(pb, "iods"); - put_be32(pb, 0); /* version & flags */ - put_be16(pb, 0x1007); - put_byte(pb, 0); - put_be16(pb, 0x4fff); - put_be16(pb, 0xfffe); - put_be16(pb, 0x01ff); - return 0x15; -} - -static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov) -{ - int maxTrackID = 1, maxTrackLen = 0, i; - - put_be32(pb, 0x6c); /* size (always 0x6c) */ - put_tag(pb, "mvhd"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, mov->time); /* creation time */ - put_be32(pb, mov->time); /* modification time */ - put_be32(pb, mov->timescale); /* timescale */ - for (i=0; itracks[i].entry > 0) { - if(maxTrackLen < mov->tracks[i].entry*mov->tracks[i].frameDuration) - maxTrackLen = mov->tracks[i].entry*mov->tracks[i].frameDuration; - if(maxTrackID < mov->tracks[i].trackID) - maxTrackID = mov->tracks[i].trackID; - } - } - put_be32(pb, maxTrackLen); /* duration of longest track */ - - put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */ - put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */ - put_be16(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - - /* Matrix structure */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x40000000); /* reserved */ - - put_be32(pb, 0); /* reserved (preview time) */ - put_be32(pb, 0); /* reserved (preview duration) */ - put_be32(pb, 0); /* reserved (poster time) */ - put_be32(pb, 0); /* reserved (selection time) */ - put_be32(pb, 0); /* reserved (selection duration) */ - put_be32(pb, 0); /* reserved (current time) */ - put_be32(pb, maxTrackID+1); /* Next track id */ - return 0x6c; -} - -static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov) -{ - int pos, i; - pos = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "moov"); - mov->timescale = globalTimescale; - - for (i=0; itracks[i].entry > 0) { - if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) { - mov->tracks[i].timescale = globalTimescale; - mov->tracks[i].sampleDelta = mov->tracks[i].frameDuration = - globalTimescale*mov->tracks[i].enc->frame_rate_base/mov->tracks[i].enc->frame_rate; - } - else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) { - /* If AMR, track timescale = 8000, AMR_WB = 16000 */ - if(mov->tracks[i].enc->codec_id == CODEC_ID_AMR_NB) { - mov->tracks[i].frameDuration = 20; - mov->tracks[i].sampleDelta = 160; - mov->tracks[i].timescale = 8000; - } - else { - mov->tracks[i].timescale = globalTimescale; - mov->tracks[i].frameDuration = - globalTimescale*mov->tracks[i].enc->frame_rate_base/mov->tracks[i].enc->frame_rate; - } - } - mov->tracks[i].time = mov->time; - mov->tracks[i].trackID = i+1; - } - } - - mov_write_mvhd_tag(pb, mov); - //mov_write_iods_tag(pb, mov); - for (i=0; itracks[i].entry > 0) { - mov_write_trak_tag(pb, &(mov->tracks[i])); - } - } - - return updateSize(pb, pos); -} - -int mov_write_mdat_tag(ByteIOContext *pb, MOVTrack* track) -{ - track->mdat_pos = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "mdat"); - return 0; -} - -/* TODO: This needs to be more general */ -int mov_write_ftyp_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x14 ); /* size */ - put_tag(pb, "ftyp"); - put_tag(pb, "3gp4"); - put_be32(pb, 0x200 ); - put_tag(pb, "3gp4"); - return 0x14; -} - -static int mov_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - - /* write ftyp */ - mov_write_ftyp_tag(pb); - - put_flush_packet(pb); - - return 0; -} - -static int Timestamp() { - time_t ltime; - time ( <ime ); - return ltime+(24107*86400); -} - -static int mov_write_packet(AVFormatContext *s, int stream_index, - const uint8_t *buf, int size, int64_t pts) -{ - MOVContext *mov = s->priv_data; - ByteIOContext *pb = &s->pb; - AVCodecContext *enc; - int cl, id; - - enc = &s->streams[stream_index]->codec; - if (!url_is_streamed(&s->pb)) { - MOVTrack* trk = &mov->tracks[stream_index]; - int sampleCount = 0; - - /* We must find out how many AMR blocks there are in one packet */ - if(enc->codec_id == CODEC_ID_AMR_NB) { - static uint16_t packed_size[16] = {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0}; - int len = 0; - - while(len < size && sampleCount < 100) { - len += packed_size[(buf[len] >> 3) & 0x0F]; - sampleCount++; - } - } - - if(enc->codec_id == CODEC_ID_MPEG4 && - trk->vosLen == 0) - { - assert(enc->extradata_size); - - trk->vosLen = enc->extradata_size; - trk->vosData = av_malloc(trk->vosLen); - memcpy(trk->vosData, enc->extradata, trk->vosLen); - } - - cl = trk->entry / MOV_INDEX_CLUSTER_SIZE; - id = trk->entry % MOV_INDEX_CLUSTER_SIZE; - - if (trk->ents_allocated <= trk->entry) { - trk->cluster = av_realloc(trk->cluster, (cl+1)*sizeof(void*)); - if (!trk->cluster) - return -1; - trk->cluster[cl] = av_malloc(MOV_INDEX_CLUSTER_SIZE*sizeof(MOVIentry)); - if (!trk->cluster[cl]) - return -1; - trk->ents_allocated += MOV_INDEX_CLUSTER_SIZE; - } - if(stream_index == 0 && trk->entry == 0) { - mov_write_mdat_tag(pb, trk); - mov->time = Timestamp(); - } - - trk->cluster[cl][id].pos = url_ftell(pb) - mov->movi_list; - trk->cluster[cl][id].len = size; - trk->cluster[cl][id].entries = sampleCount; - trk->enc = enc; - trk->entry++; - if(sampleCount == 0) - trk->samples++; - else - trk->samples += sampleCount; - trk->mdat_size += size; - } - put_buffer(pb, buf, size); - - put_flush_packet(pb); - return 0; -} - -static int mov_write_trailer(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - ByteIOContext *pb = &s->pb; - int res = 0; - int i, j; - offset_t file_size; - - file_size = url_ftell(pb); - j = 0; - - /* Write size of mdat tag */ - for (i=0; itracks[i].ents_allocated > 0) { - j += mov->tracks[i].mdat_size; - } - } - url_fseek(pb, mov->tracks[0].mdat_pos, SEEK_SET); - put_be32(pb, j+8); - url_fseek(pb, file_size, SEEK_SET); - - mov_write_moov_tag(pb, mov); - - for (i=0; itracks[i].ents_allocated/MOV_INDEX_CLUSTER_SIZE; j++) { - av_free(mov->tracks[i].cluster[j]); - } - av_free(mov->tracks[i].cluster); - mov->tracks[i].cluster = NULL; - mov->tracks[i].ents_allocated = mov->tracks[i].entry = 0; - } - put_flush_packet(pb); - - return res; -} - -static AVOutputFormat mov_oformat = { - "mov", - "mov format", - NULL, - "mov", - sizeof(MOVContext), - CODEC_ID_MP2, - CODEC_ID_MPEG4, - mov_write_header, - mov_write_packet, - mov_write_trailer, -}; - -static AVOutputFormat _3gp_oformat = { - "3gp", - "3gp format", - NULL, - "3gp", - sizeof(MOVContext), - CODEC_ID_AMR_NB, - CODEC_ID_H263, - mov_write_header, - mov_write_packet, - mov_write_trailer, -}; - -static AVOutputFormat mp4_oformat = { - "mp4", - "mp4 format", - NULL, - "mp4", - sizeof(MOVContext), - CODEC_ID_AAC, - CODEC_ID_MPEG4, - mov_write_header, - mov_write_packet, - mov_write_trailer, -}; - -int movenc_init(void) -{ - av_register_output_format(&mov_oformat); - av_register_output_format(&_3gp_oformat); - av_register_output_format(&mp4_oformat); - return 0; -}