2 more missing consts found by -Wwrite-strings.

git-svn-id: a4d7c1866f8397a4106e0b57fc4fbf792bbdaaaf@11849 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

--- libavformat/movenc.c
+++ libavformat/movenc.c
@@ -0,0 +1,1712 @@
+/*
+ * MOV, 3GP, MP4 muxer
+ * Copyright (c) 2003 Thomas Raivio.
+ * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>.
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "avformat.h"
+#include "riff.h"
+#include "avio.h"
+#include "isom.h"
+#include "avc.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+#define MOV_INDEX_CLUSTER_SIZE 16384
+#define globalTimescale 1000
+
+#define MODE_MP4 0
+#define MODE_MOV 1
+#define MODE_3GP 2
+#define MODE_PSP 3 // example working PSP command line:
+// ffmpeg -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
+#define MODE_3G2 4
+
+typedef struct MOVIentry {
+    unsigned int flags, size;
+    uint64_t     pos;
+    unsigned int samplesInChunk;
+    char         key_frame;
+    unsigned int entries;
+    int64_t      cts;
+    int64_t      dts;
+} MOVIentry;
+
+typedef struct MOVIndex {
+    int         mode;
+    int         entry;
+    long        timescale;
+    long        time;
+    int64_t     trackDuration;
+    long        sampleCount;
+    long        sampleSize;
+    int         hasKeyframes;
+    int         hasBframes;
+    int         language;
+    int         trackID;
+    int         tag; ///< stsd fourcc
+    AVCodecContext *enc;
+
+    int         vosLen;
+    uint8_t     *vosData;
+    MOVIentry   *cluster;
+    int         audio_vbr;
+} MOVTrack;
+
+typedef struct MOVContext {
+    int     mode;
+    int64_t time;
+    int     nb_streams;
+    offset_t mdat_pos;
+    uint64_t mdat_size;
+    long    timescale;
+    MOVTrack tracks[MAX_STREAMS];
+} MOVContext;
+
+//FIXME support 64 bit variant with wide placeholders
+static offset_t updateSize (ByteIOContext *pb, offset_t pos)
+{
+    offset_t 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;
+}
+
+/* Chunk offset atom */
+static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    int i;
+    int mode64 = 0; //   use 32 bit size variant if possible
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    if (pos > UINT32_MAX) {
+        mode64 = 1;
+        put_tag(pb, "co64");
+    } else
+        put_tag(pb, "stco");
+    put_be32(pb, 0); /* version & flags */
+    put_be32(pb, track->entry); /* entry count */
+    for (i=0; i<track->entry; i++) {
+        if(mode64 == 1)
+            put_be64(pb, track->cluster[i].pos);
+        else
+            put_be32(pb, track->cluster[i].pos);
+    }
+    return updateSize (pb, pos);
+}
+
+/* Sample size atom */
+static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    int equalChunks = 1;
+    int i, j, entries = 0, tst = -1, oldtst = -1;
+
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "stsz");
+    put_be32(pb, 0); /* version & flags */
+
+    for (i=0; i<track->entry; i++) {
+        tst = track->cluster[i].size/track->cluster[i].entries;
+        if(oldtst != -1 && tst != oldtst) {
+            equalChunks = 0;
+        }
+        oldtst = tst;
+        entries += track->cluster[i].entries;
+    }
+    if (equalChunks) {
+        int sSize = track->cluster[0].size/track->cluster[0].entries;
+        put_be32(pb, sSize); // sample size
+        put_be32(pb, entries); // sample count
+    }
+    else {
+        put_be32(pb, 0); // sample size
+        put_be32(pb, entries); // sample count
+        for (i=0; i<track->entry; i++) {
+            for ( j=0; j<track->cluster[i].entries; j++) {
+                put_be32(pb, track->cluster[i].size /
+                         track->cluster[i].entries);
+            }
+        }
+    }
+    return updateSize (pb, pos);
+}
+
+/* Sample to chunk atom */
+static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    int index = 0, oldval = -1, i;
+    offset_t entryPos, curpos;
+
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "stsc");
+    put_be32(pb, 0); // version & flags
+    entryPos = url_ftell(pb);
+    put_be32(pb, track->entry); // entry count
+    for (i=0; i<track->entry; i++) {
+        if(oldval != track->cluster[i].samplesInChunk)
+        {
+            put_be32(pb, i+1); // first chunk
+            put_be32(pb, track->cluster[i].samplesInChunk); // samples per chunk
+            put_be32(pb, 0x1); // sample description index
+            oldval = track->cluster[i].samplesInChunk;
+            index++;
+        }
+    }
+    curpos = url_ftell(pb);
+    url_fseek(pb, entryPos, SEEK_SET);
+    put_be32(pb, index); // rewrite size
+    url_fseek(pb, curpos, SEEK_SET);
+
+    return updateSize (pb, pos);
+}
+
+/* Sync sample atom */
+static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t curpos, entryPos;
+    int i, index = 0;
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); // size
+    put_tag(pb, "stss");
+    put_be32(pb, 0); // version & flags
+    entryPos = url_ftell(pb);
+    put_be32(pb, track->entry); // entry count
+    for (i=0; i<track->entry; i++) {
+        if(track->cluster[i].key_frame == 1) {
+            put_be32(pb, i+1);
+            index++;
+        }
+    }
+    curpos = url_ftell(pb);
+    url_fseek(pb, entryPos, SEEK_SET);
+    put_be32(pb, index); // rewrite size
+    url_fseek(pb, curpos, SEEK_SET);
+    return updateSize (pb, pos);
+}
+
+static int mov_write_amr_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    put_be32(pb, 0x11); /* size */
+    if (track->mode == MODE_MOV) put_tag(pb, "samr");
+    else                         put_tag(pb, "damr");
+    put_tag(pb, "FFMP");
+    put_byte(pb, 0); /* decoder version */
+
+    put_be16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
+    put_byte(pb, 0x00); /* Mode change period (no restriction) */
+    put_byte(pb, 0x01); /* Frames per sample */
+    return 0x11;
+}
+
+static int mov_write_enda_tag(ByteIOContext *pb)
+{
+    put_be32(pb, 10);
+    put_tag(pb, "enda");
+    put_be16(pb, 1); /* little endian */
+    return 10;
+}
+
+static unsigned int descrLength(unsigned int len)
+{
+    int i;
+    for(i=1; len>>(7*i); i++);
+    return len + 1 + i;
+}
+
+static void putDescr(ByteIOContext *pb, int tag, unsigned int size)
+{
+    int i= descrLength(size) - size - 2;
+    put_byte(pb, tag);
+    for(; i>0; i--)
+        put_byte(pb, (size>>(7*i)) | 0x80);
+    put_byte(pb, size & 0x7F);
+}
+
+static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
+{
+    offset_t pos = url_ftell(pb);
+    int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
+
+    put_be32(pb, 0);               // size
+    put_tag(pb, "esds");
+    put_be32(pb, 0);               // Version
+
+    // ES descriptor
+    putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
+             descrLength(1));
+    put_be16(pb, track->trackID);
+    put_byte(pb, 0x00);            // flags (= no flags)
+
+    // DecoderConfig descriptor
+    putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
+
+    // Object type indication
+    put_byte(pb, codec_get_tag(ff_mp4_obj_type, track->enc->codec_id));
+
+    // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
+    // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
+    if(track->enc->codec_type == CODEC_TYPE_AUDIO)
+        put_byte(pb, 0x15);            // flags (= Audiostream)
+    else
+        put_byte(pb, 0x11);            // flags (= Visualstream)
+
+    put_byte(pb,  track->enc->rc_buffer_size>>(3+16));             // Buffersize DB (24 bits)
+    put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF);          // Buffersize DB
+
+    put_be32(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)
+        put_be32(pb, 0);     // vbr
+    else
+        put_be32(pb, track->enc->rc_max_rate);     // avg bitrate
+
+    if (track->vosLen)
+    {
+        // DecoderSpecific info descriptor
+        putDescr(pb, 0x05, track->vosLen);
+        put_buffer(pb, track->vosData, track->vosLen);
+    }
+
+
+    // SL descriptor
+    putDescr(pb, 0x06, 1);
+    put_byte(pb, 0x02);
+    return updateSize (pb, pos);
+}
+
+static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t pos = url_ftell(pb);
+
+    put_be32(pb, 0);     /* size */
+    put_tag(pb, "wave");
+
+    put_be32(pb, 12);    /* size */
+    put_tag(pb, "frma");
+    put_le32(pb, track->tag);
+
+    if (track->enc->codec_id == CODEC_ID_AAC) {
+        /* useless atom needed by mplayer, ipod, not needed by quicktime */
+        put_be32(pb, 12); /* size */
+        put_tag(pb, "mp4a");
+        put_be32(pb, 0);
+        mov_write_esds_tag(pb, track);
+    } else if (track->enc->codec_id == CODEC_ID_PCM_S24LE ||
+               track->enc->codec_id == CODEC_ID_PCM_S32LE) {
+        mov_write_enda_tag(pb);
+    } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
+        mov_write_amr_tag(pb, track);
+    }
+
+    put_be32(pb, 8);     /* size */
+    put_be32(pb, 0);     /* null tag */
+
+    return updateSize (pb, pos);
+}
+
+static int mov_write_glbl_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    put_be32(pb, track->vosLen+8);
+    put_tag(pb, "glbl");
+    put_buffer(pb, track->vosData, track->vosLen);
+    return 8+track->vosLen;
+}
+
+static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t pos = url_ftell(pb);
+    int version = track->mode == MODE_MOV &&
+        (track->audio_vbr ||
+         track->enc->codec_id == CODEC_ID_PCM_S32LE ||
+         track->enc->codec_id == CODEC_ID_PCM_S24LE);
+
+    put_be32(pb, 0); /* size */
+    put_le32(pb, track->tag); // store it byteswapped
+    put_be32(pb, 0); /* Reserved */
+    put_be16(pb, 0); /* Reserved */
+    put_be16(pb, 1); /* Data-reference index, XXX  == 1 */
+
+    /* SoundDescription */
+    put_be16(pb, version); /* Version */
+    put_be16(pb, 0); /* Revision level */
+    put_be32(pb, 0); /* Reserved */
+
+    if (track->mode == MODE_MOV) {
+        put_be16(pb, track->enc->channels);
+        if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
+            track->enc->codec_id == CODEC_ID_PCM_S8)
+            put_be16(pb, 8); /* bits per sample */
+        else
+            put_be16(pb, 16);
+        put_be16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
+    } else { /* reserved for mp4/3gp */
+        put_be16(pb, 2);
+        put_be16(pb, 16);
+        put_be16(pb, 0);
+    }
+
+    put_be16(pb, 0); /* packet size (= 0) */
+    put_be16(pb, track->timescale); /* Time scale */
+    put_be16(pb, 0); /* Reserved */
+
+    if(version == 1) { /* SoundDescription V1 extended info */
+        put_be32(pb, track->enc->frame_size); /* Samples per packet */
+        put_be32(pb, track->sampleSize / track->enc->channels); /* Bytes per packet */
+        put_be32(pb, track->sampleSize); /* Bytes per frame */
+        put_be32(pb, 2); /* Bytes per sample */
+    }
+
+    if(track->mode == MODE_MOV &&
+       (track->enc->codec_id == CODEC_ID_AAC ||
+        track->enc->codec_id == CODEC_ID_AMR_NB ||
+        track->enc->codec_id == CODEC_ID_PCM_S24LE ||
+        track->enc->codec_id == CODEC_ID_PCM_S32LE))
+        mov_write_wave_tag(pb, track);
+    else if(track->tag == MKTAG('m','p','4','a'))
+        mov_write_esds_tag(pb, track);
+    else if(track->enc->codec_id == CODEC_ID_AMR_NB)
+        mov_write_amr_tag(pb, track);
+    else if(track->vosLen > 0)
+        mov_write_glbl_tag(pb, track);
+
+    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_byte(pb, 0); /* decoder version */
+    /* FIXME use AVCodecContext level/profile, when encoder will set values */
+    put_byte(pb, 0xa); /* level */
+    put_byte(pb, 0); /* profile */
+    return 0xf;
+}
+
+/* TODO: No idea about these values */
+static int mov_write_svq3_tag(ByteIOContext *pb)
+{
+    put_be32(pb, 0x15);
+    put_tag(pb, "SMI ");
+    put_tag(pb, "SEQH");
+    put_be32(pb, 0x5);
+    put_be32(pb, 0xe2c0211d);
+    put_be32(pb, 0xc0000000);
+    put_byte(pb, 0);
+    return 0x15;
+}
+
+static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    offset_t pos = url_ftell(pb);
+
+    put_be32(pb, 0);
+    put_tag(pb, "avcC");
+    ff_isom_write_avcc(pb, track->vosData, track->vosLen);
+    return updateSize(pb, pos);
+}
+
+/* also used by all avid codecs (dv, imx, meridien) and their variants */
+static int mov_write_avid_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    int i;
+    put_be32(pb, 24); /* size */
+    put_tag(pb, "ACLR");
+    put_tag(pb, "ACLR");
+    put_tag(pb, "0001");
+    put_be32(pb, 1); /* yuv 1 / rgb 2 ? */
+    put_be32(pb, 0); /* unknown */
+
+    put_be32(pb, 24); /* size */
+    put_tag(pb, "APRG");
+    put_tag(pb, "APRG");
+    put_tag(pb, "0001");
+    put_be32(pb, 1); /* unknown */
+    put_be32(pb, 0); /* unknown */
+
+    put_be32(pb, 120); /* size */
+    put_tag(pb, "ARES");
+    put_tag(pb, "ARES");
+    put_tag(pb, "0001");
+    put_be32(pb, AV_RB32(track->vosData + 0x28)); /* dnxhd cid, some id ? */
+    put_be32(pb, track->enc->width);
+    /* values below are based on samples created with quicktime and avid codecs */
+    if (track->vosData[5] & 2) { // interlaced
+        put_be32(pb, track->enc->height/2);
+        put_be32(pb, 2); /* unknown */
+        put_be32(pb, 0); /* unknown */
+        put_be32(pb, 4); /* unknown */
+    } else {
+        put_be32(pb, track->enc->height);
+        put_be32(pb, 1); /* unknown */
+        put_be32(pb, 0); /* unknown */
+        if (track->enc->height == 1080)
+            put_be32(pb, 5); /* unknown */
+        else
+            put_be32(pb, 6); /* unknown */
+    }
+    /* padding */
+    for (i = 0; i < 10; i++)
+        put_be64(pb, 0);
+
+    /* extra padding for stsd needed */
+    put_be32(pb, 0);
+    return 0;
+}
+
+static const AVCodecTag codec_3gp_tags[] = {
+    { CODEC_ID_H263,   MKTAG('s','2','6','3') },
+    { CODEC_ID_H264,   MKTAG('a','v','c','1') },
+    { CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
+    { CODEC_ID_AAC,    MKTAG('m','p','4','a') },
+    { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
+    { CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
+};
+
+static const AVCodecTag mov_pix_fmt_tags[] = {
+    { PIX_FMT_YUYV422, MKTAG('y','u','v','s') },
+    { PIX_FMT_UYVY422, MKTAG('2','v','u','y') },
+    { PIX_FMT_BGR555,  MKTAG('r','a','w',' ') },
+    { PIX_FMT_RGB24,   MKTAG('r','a','w',' ') },
+    { PIX_FMT_BGR32_1, MKTAG('r','a','w',' ') },
+};
+
+static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
+{
+    int tag = track->enc->codec_tag;
+    if (track->mode == MODE_MP4 || track->mode == MODE_PSP) {
+        if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
+            return 0;
+        if (track->enc->codec_id == CODEC_ID_H264)           tag = MKTAG('a','v','c','1');
+        else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
+        else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
+    } else if (track->mode == MODE_3GP || track->mode == MODE_3G2) {
+        tag = codec_get_tag(codec_3gp_tags, track->enc->codec_id);
+    } else if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
+                        (tag == MKTAG('d','v','c','p') ||
+                         track->enc->codec_id == CODEC_ID_RAWVIDEO))) {
+        if (track->enc->codec_id == CODEC_ID_DVVIDEO) {
+            if (track->enc->height == 480) /* NTSC */
+                if  (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
+                else                                         tag = MKTAG('d','v','c',' ');
+            else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
+            else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
+            else                                             tag = MKTAG('d','v','p','p');
+        } else if (track->enc->codec_id == CODEC_ID_RAWVIDEO) {
+            tag = codec_get_tag(mov_pix_fmt_tags, track->enc->pix_fmt);
+            if (!tag) // restore tag
+                tag = track->enc->codec_tag;
+        } else {
+            if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
+                tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);
+                if (!tag) { // if no mac fcc found, try with Microsoft tags
+                    tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);
+                    if (tag)
+                        av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "
+                               "the file may be unplayable!\n");
+                }
+            } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {
+                tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
+                if (!tag) { // if no mac fcc found, try with Microsoft tags
+                    int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id);
+                    if (ms_tag) {
+                        tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
+                        av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "
+                               "the file may be unplayable!\n");
+                    }
+                }
+            }
+        }
+    }
+    return tag;
+}
+
+static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t pos = url_ftell(pb);
+    char compressor_name[32];
+
+    put_be32(pb, 0); /* size */
+    put_le32(pb, track->tag); // store it byteswapped
+    put_be32(pb, 0); /* Reserved */
+    put_be16(pb, 0); /* Reserved */
+    put_be16(pb, 1); /* Data-reference index */
+
+    put_be16(pb, 0); /* Codec stream version */
+    put_be16(pb, 0); /* Codec stream revision (=0) */
+    if (track->mode == MODE_MOV) {
+        put_tag(pb, "FFMP"); /* Vendor */
+        if(track->enc->codec_id == CODEC_ID_RAWVIDEO) {
+            put_be32(pb, 0); /* Temporal Quality */
+            put_be32(pb, 0x400); /* Spatial Quality = lossless*/
+        } else {
+            put_be32(pb, 0x200); /* Temporal Quality = normal */
+            put_be32(pb, 0x200); /* Spatial Quality = normal */
+        }
+    } else {
+        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); /* Horizontal resolution 72dpi */
+    put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */
+    put_be32(pb, 0); /* Data size (= 0) */
+    put_be16(pb, 1); /* Frame count (= 1) */
+
+    memset(compressor_name,0,32);
+    /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
+    if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
+        strncpy(compressor_name,track->enc->codec->name,31);
+    put_byte(pb, strlen(compressor_name));
+    put_buffer(pb, compressor_name, 31);
+
+    if (track->mode == MODE_MOV && track->enc->bits_per_sample)
+        put_be16(pb, track->enc->bits_per_sample);
+    else
+        put_be16(pb, 0x18); /* Reserved */
+    put_be16(pb, 0xffff); /* Reserved */
+    if(track->tag == MKTAG('m','p','4','v'))
+        mov_write_esds_tag(pb, track);
+    else if(track->enc->codec_id == CODEC_ID_H263)
+        mov_write_d263_tag(pb);
+    else if(track->enc->codec_id == CODEC_ID_SVQ3)
+        mov_write_svq3_tag(pb);
+    else if(track->enc->codec_id == CODEC_ID_H264)
+        mov_write_avcc_tag(pb, track);
+    else if(track->enc->codec_id == CODEC_ID_DNXHD)
+        mov_write_avid_tag(pb, track);
+    else if(track->vosLen > 0)
+        mov_write_glbl_tag(pb, track);
+
+    return updateSize (pb, pos);
+}
+
+static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t 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)
+        mov_write_video_tag(pb, track);
+    else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
+        mov_write_audio_tag(pb, track);
+    return updateSize(pb, pos);
+}
+
+static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    MOV_stts_t *ctts_entries;
+    uint32_t entries = 0;
+    uint32_t atom_size;
+    int i;
+
+    ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
+    ctts_entries[0].count = 1;
+    ctts_entries[0].duration = track->cluster[0].cts;
+    for (i=1; i<track->entry; i++) {
+        if (track->cluster[i].cts == ctts_entries[entries].duration) {
+            ctts_entries[entries].count++; /* compress */
+        } else {
+            entries++;
+            ctts_entries[entries].duration = track->cluster[i].cts;
+            ctts_entries[entries].count = 1;
+        }
+    }
+    entries++; /* last one */
+    atom_size = 16 + (entries * 8);
+    put_be32(pb, atom_size); /* size */
+    put_tag(pb, "ctts");
+    put_be32(pb, 0); /* version & flags */
+    put_be32(pb, entries); /* entry count */
+    for (i=0; i<entries; i++) {
+        put_be32(pb, ctts_entries[i].count);
+        put_be32(pb, ctts_entries[i].duration);
+    }
+    av_free(ctts_entries);
+    return atom_size;
+}
+
+/* Time to sample atom */
+static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    MOV_stts_t *stts_entries;
+    uint32_t entries = -1;
+    uint32_t atom_size;
+    int i;
+
+    if (track->enc->codec_type == CODEC_TYPE_AUDIO && !track->audio_vbr) {
+        stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
+        stts_entries[0].count = track->sampleCount;
+        stts_entries[0].duration = 1;
+        entries = 1;
+    } else {
+        stts_entries = av_malloc(track->entry * sizeof(*stts_entries)); /* worst case */
+        for (i=0; i<track->entry; i++) {
+            int64_t duration = i + 1 == track->entry ?
+                track->trackDuration - track->cluster[i].dts + track->cluster[0].dts : /* readjusting */
+                track->cluster[i+1].dts - track->cluster[i].dts;
+            if (i && duration == stts_entries[entries].duration) {
+                stts_entries[entries].count++; /* compress */
+            } else {
+                entries++;
+                stts_entries[entries].duration = duration;
+                stts_entries[entries].count = 1;
+            }
+        }
+        entries++; /* last one */
+    }
+    atom_size = 16 + (entries * 8);
+    put_be32(pb, atom_size); /* size */
+    put_tag(pb, "stts");
+    put_be32(pb, 0); /* version & flags */
+    put_be32(pb, entries); /* entry count */
+    for (i=0; i<entries; i++) {
+        put_be32(pb, stts_entries[i].count);
+        put_be32(pb, stts_entries[i].duration);
+    }
+    av_free(stts_entries);
+    return atom_size;
+}
+
+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)
+{
+    offset_t 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 &&
+        track->hasKeyframes < track->entry)
+        mov_write_stss_tag(pb, track);
+    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
+        track->hasBframes)
+        mov_write_ctts_tag(pb, track);
+    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)
+{
+    offset_t 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_hdlr_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    const char *descr, *hdlr, *hdlr_type;
+    offset_t pos = url_ftell(pb);
+
+    if (!track) { /* no media --> data handler */
+        hdlr = "dhlr";
+        hdlr_type = "url ";
+        descr = "DataHandler";
+    } else {
+        hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
+        if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
+            hdlr_type = "vide";
+            descr = "VideoHandler";
+        } else {
+            hdlr_type = "soun";
+            descr = "SoundHandler";
+        }
+    }
+
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "hdlr");
+    put_be32(pb, 0); /* Version & flags */
+    put_buffer(pb, hdlr, 4); /* handler */
+    put_tag(pb, hdlr_type); /* handler type */
+    put_be32(pb ,0); /* reserved */
+    put_be32(pb ,0); /* reserved */
+    put_be32(pb ,0); /* reserved */
+    put_byte(pb, strlen(descr)); /* string counter */
+    put_buffer(pb, descr, strlen(descr)); /* handler description */
+    return updateSize(pb, pos);
+}
+
+static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t 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);
+    if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
+        mov_write_hdlr_tag(pb, NULL);
+    mov_write_dinf_tag(pb);
+    mov_write_stbl_tag(pb, track);
+    return updateSize(pb, pos);
+}
+
+static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    int version = track->trackDuration < INT32_MAX ? 0 : 1;
+
+    (version == 1) ? put_be32(pb, 44) : put_be32(pb, 32); /* size */
+    put_tag(pb, "mdhd");
+    put_byte(pb, version);
+    put_be24(pb, 0); /* flags */
+    if (version == 1) {
+        put_be64(pb, track->time);
+        put_be64(pb, track->time);
+    } else {
+        put_be32(pb, track->time); /* creation time */
+        put_be32(pb, track->time); /* modification time */
+    }
+    put_be32(pb, track->timescale); /* time scale (sample rate for audio) */
+    (version == 1) ? put_be64(pb, track->trackDuration) : put_be32(pb, track->trackDuration); /* duration */
+    put_be16(pb, track->language); /* language */
+    put_be16(pb, 0); /* reserved (quality) */
+
+    if(version!=0 && track->mode == MODE_MOV){
+        av_log(NULL, AV_LOG_ERROR,
+            "FATAL error, file duration too long for timebase, this file will not be\n"
+            "playable with quicktime. Choose a different timebase or a different\n"
+            "container format\n");
+    }
+
+    return 32;
+}
+
+static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t 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)
+{
+    int64_t duration = av_rescale_rnd(track->trackDuration, globalTimescale, track->timescale, AV_ROUND_UP);
+    int version = duration < INT32_MAX ? 0 : 1;
+
+    (version == 1) ? put_be32(pb, 104) : put_be32(pb, 92); /* size */
+    put_tag(pb, "tkhd");
+    put_byte(pb, version);
+    put_be24(pb, 0xf); /* flags (track enabled) */
+    if (version == 1) {
+        put_be64(pb, track->time);
+        put_be64(pb, track->time);
+    } else {
+        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 */
+    (version == 1) ? put_be64(pb, duration) : put_be32(pb, 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) {
+        double sample_aspect_ratio = av_q2d(track->enc->sample_aspect_ratio);
+        if( !sample_aspect_ratio ) sample_aspect_ratio = 1;
+        put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000);
+        put_be32(pb, track->enc->height*0x10000);
+    }
+    else {
+        put_be32(pb, 0);
+        put_be32(pb, 0);
+    }
+    return 0x5c;
+}
+
+// This box seems important for the psp playback ... without it the movie seems to hang
+static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    put_be32(pb, 0x24); /* size  */
+    put_tag(pb, "edts");
+    put_be32(pb, 0x1c); /* size  */
+    put_tag(pb, "elst");
+    put_be32(pb, 0x0);
+    put_be32(pb, 0x1);
+
+    put_be32(pb, av_rescale_rnd(track->trackDuration, globalTimescale, track->timescale, AV_ROUND_UP)); /* duration   ... doesn't seem to effect psp */
+
+    put_be32(pb, track->cluster[0].cts); /* first pts is cts since dts is 0 */
+    put_be32(pb, 0x00010000);
+    return 0x24;
+}
+
+// goes at the end of each track!  ... Critical for PSP playback ("Incompatible data" without it)
+static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov)
+{
+    put_be32(pb, 0x34); /* size ... reports as 28 in mp4box! */
+    put_tag(pb, "uuid");
+    put_tag(pb, "USMT");
+    put_be32(pb, 0x21d24fce);
+    put_be32(pb, 0xbb88695c);
+    put_be32(pb, 0xfac9c740);
+    put_be32(pb, 0x1c);     // another size here!
+    put_tag(pb, "MTDT");
+    put_be32(pb, 0x00010012);
+    put_be32(pb, 0x0a);
+    put_be32(pb, 0x55c40000);
+    put_be32(pb, 0x1);
+    put_be32(pb, 0x0);
+    return 0x34;
+}
+
+static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track)
+{
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "trak");
+    mov_write_tkhd_tag(pb, track);
+    if (track->mode == MODE_PSP || track->hasBframes)
+        mov_write_edts_tag(pb, track);  // PSP Movies require edts box
+    mov_write_mdia_tag(pb, track);
+    if (track->mode == MODE_PSP)
+        mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box
+    return updateSize(pb, pos);
+}
+
+#if 0
+/* 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;
+}
+#endif
+
+static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov)
+{
+    int maxTrackID = 1, i;
+    int64_t maxTrackLenTemp, maxTrackLen = 0;
+    int version;
+
+    for (i=0; i<mov->nb_streams; i++) {
+        if(mov->tracks[i].entry > 0) {
+            maxTrackLenTemp = av_rescale_rnd(mov->tracks[i].trackDuration, globalTimescale, mov->tracks[i].timescale, AV_ROUND_UP);
+            if(maxTrackLen < maxTrackLenTemp)
+                maxTrackLen = maxTrackLenTemp;
+            if(maxTrackID < mov->tracks[i].trackID)
+                maxTrackID = mov->tracks[i].trackID;
+        }
+    }
+
+    version = maxTrackLen < UINT32_MAX ? 0 : 1;
+    (version == 1) ? put_be32(pb, 120) : put_be32(pb, 108); /* size */
+    put_tag(pb, "mvhd");
+    put_byte(pb, version);
+    put_be24(pb, 0); /* flags */
+    if (version == 1) {
+        put_be64(pb, mov->time);
+        put_be64(pb, mov->time);
+    } else {
+        put_be32(pb, mov->time); /* creation time */
+        put_be32(pb, mov->time); /* modification time */
+    }
+    put_be32(pb, mov->timescale); /* timescale */
+    (version == 1) ? put_be64(pb, maxTrackLen) : 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_itunes_hdlr_tag(ByteIOContext *pb, MOVContext* mov,
+                                     AVFormatContext *s)
+{
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "hdlr");
+    put_be32(pb, 0);
+    put_be32(pb, 0);
+    put_tag(pb, "mdir");
+    put_tag(pb, "appl");
+    put_be32(pb, 0);
+    put_be32(pb, 0);
+    put_be16(pb, 0);
+    return updateSize(pb, pos);
+}
+
+/* helper function to write a data tag with the specified string as data */
+static int mov_write_string_data_tag(ByteIOContext *pb, const char *data, int long_style)
+{
+    if(long_style){
+        offset_t pos = url_ftell(pb);
+        put_be32(pb, 0); /* size */
+        put_tag(pb, "data");
+        put_be32(pb, 1);
+        put_be32(pb, 0);
+        put_buffer(pb, data, strlen(data));
+        return updateSize(pb, pos);
+    }else{
+        put_be16(pb, strlen(data)); /* string length */
+        put_be16(pb, 0);
+        put_buffer(pb, data, strlen(data));
+        return strlen(data) + 4;
+    }
+}
+
+static int mov_write_string_tag(ByteIOContext *pb, const char *name, const char *value, int long_style){
+    int size = 0;
+    if ( value && value[0] ) {
+        offset_t pos = url_ftell(pb);
+        put_be32(pb, 0); /* size */
+        put_tag(pb, name);
+        mov_write_string_data_tag(pb, value, long_style);
+        size= updateSize(pb, pos);
+    }
+    return size;
+}
+
+/* iTunes year */
+static int mov_write_day_tag(ByteIOContext *pb, int year, int long_style)
+{
+    if(year){
+        char year_str[5];
+        snprintf(year_str, sizeof(year_str), "%04d", year);
+        return mov_write_string_tag(pb, "\251day", year_str, long_style);
+    }else
+        return 0;
+}
+
+/* iTunes track number */
+static int mov_write_trkn_tag(ByteIOContext *pb, MOVContext* mov,
+                              AVFormatContext *s)
+{
+    int size = 0;
+    if ( s->track ) {
+        offset_t pos = url_ftell(pb);
+        put_be32(pb, 0); /* size */
+        put_tag(pb, "trkn");
+        {
+            offset_t pos = url_ftell(pb);
+            put_be32(pb, 0); /* size */
+            put_tag(pb, "data");
+            put_be32(pb, 0);        // 8 bytes empty
+            put_be32(pb, 0);
+            put_be16(pb, 0);        // empty
+            put_be16(pb, s->track); // track number
+            put_be16(pb, 0);        // total track number
+            put_be16(pb, 0);        // empty
+            updateSize(pb, pos);
+        }
+        size = updateSize(pb, pos);
+    }
+    return size;
+}
+
+/* iTunes meta data list */
+static int mov_write_ilst_tag(ByteIOContext *pb, MOVContext* mov,
+                              AVFormatContext *s)
+{
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size */
+    put_tag(pb, "ilst");
+    mov_write_string_tag(pb, "\251nam", s->title         , 1);
+    mov_write_string_tag(pb, "\251ART", s->author        , 1);
+    mov_write_string_tag(pb, "\251wrt", s->author        , 1);
+    mov_write_string_tag(pb, "\251alb", s->album         , 1);
+    mov_write_day_tag(pb, s->year ,1);
+    if(mov->tracks[0].enc && !(mov->tracks[0].enc->flags & CODEC_FLAG_BITEXACT))
+        mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 1);
+    mov_write_string_tag(pb, "\251cmt", s->comment       , 1);
+    mov_write_string_tag(pb, "\251gen", s->genre         , 1);
+    mov_write_trkn_tag(pb, mov, s);
+    return updateSize(pb, pos);
+}
+
+/* iTunes meta data tag */
+static int mov_write_meta_tag(ByteIOContext *pb, MOVContext* mov,
+                              AVFormatContext *s)
+{
+    int size = 0;
+
+    // only save meta tag if required
+    if ( s->title[0] || s->author[0] || s->album[0] || s->year ||
+         s->comment[0] || s->genre[0] || s->track ) {
+        offset_t pos = url_ftell(pb);
+        put_be32(pb, 0); /* size */
+        put_tag(pb, "meta");
+        put_be32(pb, 0);
+        mov_write_itunes_hdlr_tag(pb, mov, s);
+        mov_write_ilst_tag(pb, mov, s);
+        size = updateSize(pb, pos);
+    }
+    return size;
+}
+
+static int mov_write_udta_tag(ByteIOContext *pb, MOVContext* mov,
+                              AVFormatContext *s)
+{
+    int i, req = 0;
+
+    /* Requirements */
+    for (i=0; i<mov->nb_streams; i++) {
+        if(mov->tracks[i].entry <= 0) continue;
+        if (mov->tracks[i].enc->codec_id == CODEC_ID_AAC ||
+            mov->tracks[i].enc->codec_id == CODEC_ID_MPEG4) {
+            req = 1;
+            break;
+        }
+    }
+
+    if (s->title[0]   || s->author[0] || s->album[0] || s->year ||
+        s->comment[0] || s->genre[0]  || s->track ||
+       (mov->mode == MODE_MOV &&
+      ((mov->tracks[0].enc && !mov->tracks[0].enc->flags & CODEC_FLAG_BITEXACT) || req))) {
+        offset_t pos = url_ftell(pb);
+
+        put_be32(pb, 0); /* size */
+        put_tag(pb, "udta");
+
+        /* iTunes meta data */
+        mov_write_meta_tag(pb, mov, s);
+
+        if(mov->mode == MODE_MOV){ // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
+            /* Requirements */
+            if (req)
+                mov_write_string_tag(pb, "\251req", "QuickTime 6.0 or greater", 0);
+
+            mov_write_string_tag(pb, "\251nam", s->title         , 0);
+            mov_write_string_tag(pb, "\251aut", s->author        , 0);
+            mov_write_string_tag(pb, "\251alb", s->album         , 0);
+            mov_write_day_tag(pb, s->year, 0);
+            if(mov->tracks[0].enc && !(mov->tracks[0].enc->flags & CODEC_FLAG_BITEXACT))
+                mov_write_string_tag(pb, "\251enc", LIBAVFORMAT_IDENT, 0);
+            mov_write_string_tag(pb, "\251des", s->comment       , 0);
+            mov_write_string_tag(pb, "\251gen", s->genre         , 0);
+        }
+
+        return updateSize(pb, pos);
+    }
+
+    return 0;
+}
+
+static int utf8len(const uint8_t *b){
+    int len=0;
+    int val;
+    while(*b){
+        GET_UTF8(val, *b++, return -1;)
+        len++;
+    }
+    return len;
+}
+
+static int ascii_to_wc (ByteIOContext *pb, const uint8_t *b)
+{
+    int val;
+    while(*b){
+        GET_UTF8(val, *b++, return -1;)
+        put_be16(pb, val);
+    }
+    put_be16(pb, 0x00);
+    return 0;
+}
+
+static uint16_t language_code (const char *str)
+{
+    return ((((str[0]-0x60) & 0x1F)<<10) + (((str[1]-0x60) & 0x1F)<<5) + ((str[2]-0x60) & 0x1F));
+}
+
+static int mov_write_uuidusmt_tag (ByteIOContext *pb, AVFormatContext *s)
+{
+    size_t len, size;
+    offset_t pos, curpos;
+
+    size = 0;
+    if (s->title[0]) {
+        pos = url_ftell(pb);
+        put_be32(pb, 0); /* size placeholder*/
+        put_tag(pb, "uuid");
+        put_tag(pb, "USMT");
+        put_be32(pb, 0x21d24fce ); /* 96 bit UUID */
+        put_be32(pb, 0xbb88695c );
+        put_be32(pb, 0xfac9c740 );
+        size += 24;
+
+        put_be32(pb, 0); /* size placeholder*/
+        put_tag(pb, "MTDT");
+        put_be16(pb, 4);
+        size += 10;
+
+        // ?
+        put_be16(pb, 0x0C);                 /* size */
+        put_be32(pb, 0x0B);                 /* type */
+        put_be16(pb, language_code("und")); /* language */
+        put_be16(pb, 0x0);                  /* ? */
+        put_be16(pb, 0x021C);               /* data */
+        size += 12;
+
+        // Encoder
+        len = utf8len(LIBAVCODEC_IDENT)+1;
+        if(len<=0)
+            goto not_utf8;
+        put_be16(pb, len*2+10);             /* size */
+        put_be32(pb, 0x04);                 /* type */
+        put_be16(pb, language_code("eng")); /* language */
+        put_be16(pb, 0x01);                 /* ? */
+        ascii_to_wc(pb, LIBAVCODEC_IDENT);
+        size += len*2+10;
+
+        // Title
+        len = utf8len(s->title)+1;
+        if(len<=0)
+            goto not_utf8;
+        put_be16(pb, len*2+10);             /* size */
+        put_be32(pb, 0x01);                 /* type */
+        put_be16(pb, language_code("eng")); /* language */
+        put_be16(pb, 0x01);                 /* ? */
+        ascii_to_wc (pb, s->title);
+        size += len*2+10;
+
+        // Date
+//        snprintf(dt,32,"%04d/%02d/%02d %02d:%02d:%02d",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
+        len = utf8len("2006/04/01 11:11:11")+1;
+        if(len<=0)
+            goto not_utf8;
+        put_be16(pb, len*2+10);    /* size */
+        put_be32(pb, 0x03);        /* type */
+        put_be16(pb, language_code("und")); /* language */
+        put_be16(pb, 0x01);        /* ? */
+        ascii_to_wc (pb, "2006/04/01 11:11:11");
+        size += len*2+10;
+
+        // size
+        curpos = url_ftell(pb);
+        url_fseek(pb, pos, SEEK_SET);
+        put_be32(pb, size);
+        url_fseek(pb, pos+24, SEEK_SET);
+        put_be32(pb, size-24);
+        url_fseek(pb, curpos, SEEK_SET);
+    }
+
+    return size;
+not_utf8:
+    av_log(s, AV_LOG_ERROR, "not utf8\n");
+    return -1;
+}
+
+static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
+                              AVFormatContext *s)
+{
+    int i;
+    offset_t pos = url_ftell(pb);
+    put_be32(pb, 0); /* size placeholder*/
+    put_tag(pb, "moov");
+    mov->timescale = globalTimescale;
+
+    for (i=0; i<mov->nb_streams; i++) {
+        if(mov->tracks[i].entry <= 0) continue;
+
+        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; i<mov->nb_streams; i++) {
+        if(mov->tracks[i].entry > 0) {
+            mov_write_trak_tag(pb, &(mov->tracks[i]));
+        }
+    }
+
+    if (mov->mode == MODE_PSP)
+        mov_write_uuidusmt_tag(pb, s);
+    else if (mov->mode != MODE_3GP && mov->mode != MODE_3G2)
+        mov_write_udta_tag(pb, mov, s);
+
+    return updateSize(pb, pos);
+}
+
+static int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov)
+{
+    put_be32(pb, 8);    // placeholder for extended size field (64 bit)
+    put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free");
+
+    mov->mdat_pos = url_ftell(pb);
+    put_be32(pb, 0); /* size placeholder*/
+    put_tag(pb, "mdat");
+    return 0;
+}
+
+/* TODO: This needs to be more general */
+static void mov_write_ftyp_tag (ByteIOContext *pb, AVFormatContext *s)
+{
+    MOVContext *mov = s->priv_data;
+
+    put_be32(pb, 0x14 ); /* size */
+    put_tag(pb, "ftyp");
+
+    if ( mov->mode == MODE_3GP )
+        put_tag(pb, "3gp4");
+    else if ( mov->mode == MODE_3G2 )
+        put_tag(pb, "3g2a");
+    else if ( mov->mode == MODE_PSP )
+        put_tag(pb, "MSNV");
+    else if ( mov->mode == MODE_MP4 )
+        put_tag(pb, "isom");
+    else
+        put_tag(pb, "qt  ");
+
+    put_be32(pb, 0x200 );
+
+    if ( mov->mode == MODE_3GP )
+        put_tag(pb, "3gp4");
+    else if ( mov->mode == MODE_3G2 )
+        put_tag(pb, "3g2a");
+    else if ( mov->mode == MODE_PSP )
+        put_tag(pb, "MSNV");
+    else if ( mov->mode == MODE_MP4 )
+        put_tag(pb, "mp41");
+    else
+        put_tag(pb, "qt  ");
+}
+
+static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
+{
+    AVCodecContext *VideoCodec = s->streams[0]->codec;
+    AVCodecContext *AudioCodec = s->streams[1]->codec;
+    int AudioRate = AudioCodec->sample_rate;
+    int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);
+    int audio_kbitrate= AudioCodec->bit_rate / 1000;
+    int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate);
+
+    put_be32(pb, 0x94 ); /* size */
+    put_tag(pb, "uuid");
+    put_tag(pb, "PROF");
+
+    put_be32(pb, 0x21d24fce ); /* 96 bit UUID */
+    put_be32(pb, 0xbb88695c );
+    put_be32(pb, 0xfac9c740 );
+
+    put_be32(pb, 0x0 );  /* ? */
+    put_be32(pb, 0x3 );  /* 3 sections ? */
+
+    put_be32(pb, 0x14 ); /* size */
+    put_tag(pb, "FPRF");
+    put_be32(pb, 0x0 );  /* ? */
+    put_be32(pb, 0x0 );  /* ? */
+    put_be32(pb, 0x0 );  /* ? */
+
+    put_be32(pb, 0x2c );  /* size */
+    put_tag(pb, "APRF");   /* audio */
+    put_be32(pb, 0x0 );
+    put_be32(pb, 0x2 );   /* TrackID */
+    put_tag(pb, "mp4a");
+    put_be32(pb, 0x20f );
+    put_be32(pb, 0x0 );
+    put_be32(pb, audio_kbitrate);
+    put_be32(pb, audio_kbitrate);
+    put_be32(pb, AudioRate );
+    put_be32(pb, AudioCodec->channels );
+
+    put_be32(pb, 0x34 );  /* size */
+    put_tag(pb, "VPRF");   /* video */
+    put_be32(pb, 0x0 );
+    put_be32(pb, 0x1 );    /* TrackID */
+    if (VideoCodec->codec_id == CODEC_ID_H264) {
+        put_tag(pb, "avc1");
+        put_be16(pb, 0x014D );
+        put_be16(pb, 0x0015 );
+    } else {
+        put_tag(pb, "mp4v");
+        put_be16(pb, 0x0000 );
+        put_be16(pb, 0x0103 );
+    }
+    put_be32(pb, 0x0 );
+    put_be32(pb, video_kbitrate);
+    put_be32(pb, video_kbitrate);
+    put_be32(pb, FrameRate);
+    put_be32(pb, FrameRate);
+    put_be16(pb, VideoCodec->width);
+    put_be16(pb, VideoCodec->height);
+    put_be32(pb, 0x010001); /* ? */
+}
+
+static int mov_write_header(AVFormatContext *s)
+{
+    ByteIOContext *pb = s->pb;
+    MOVContext *mov = s->priv_data;
+    int i;
+
+    if (url_is_streamed(s->pb)) {
+        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
+        return -1;
+    }
+
+    /* Default mode == MP4 */
+    mov->mode = MODE_MP4;
+
+    if (s->oformat != NULL) {
+        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
+        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2;
+        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
+        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
+
+        mov_write_ftyp_tag(pb,s);
+        if ( mov->mode == MODE_PSP ) {
+            if ( s->nb_streams != 2 ) {
+                av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
+                return -1;
+            }
+            mov_write_uuidprof_tag(pb,s);
+        }
+    }
+
+    for(i=0; i<s->nb_streams; i++){
+        AVStream *st= s->streams[i];
+        MOVTrack *track= &mov->tracks[i];
+
+        track->enc = st->codec;
+        track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);
+        track->mode = mov->mode;
+        track->tag = mov_find_codec_tag(s, track);
+        if (!track->tag) {
+            av_log(s, AV_LOG_ERROR, "track %d: could not find tag for codec\n", i);
+            return -1;
+        }
+        if(st->codec->codec_type == CODEC_TYPE_VIDEO){
+            track->timescale = st->codec->time_base.den;
+            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
+            if (track->mode == MODE_MOV && track->timescale > 100000)
+                av_log(s, AV_LOG_WARNING,
+                       "WARNING codec timebase is very high. If duration is too long,\n"
+                       "file may not be playable by quicktime. Specify a shorter timebase\n"
+                       "or choose different container.\n");
+        }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){
+            track->timescale = st->codec->sample_rate;
+            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            if(!st->codec->frame_size){
+                av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
+                return -1;
+            }else if(st->codec->frame_size > 1){ /* assume compressed audio */
+                track->audio_vbr = 1;
+            }else{
+                track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
+            }
+        }
+    }
+
+    mov_write_mdat_tag(pb, mov);
+    mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based
+    mov->nb_streams = s->nb_streams;
+
+    put_flush_packet(pb);
+
+    return 0;
+}
+
+static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MOVContext *mov = s->priv_data;
+    ByteIOContext *pb = s->pb;
+    MOVTrack *trk = &mov->tracks[pkt->stream_index];
+    AVCodecContext *enc = trk->enc;
+    unsigned int samplesInChunk = 0;
+    int size= pkt->size;
+
+    if (url_is_streamed(s->pb)) return 0; /* Can't handle that */
+    if (!size) return 0; /* Discard 0 sized packets */
+
+    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};
+        int len = 0;
+
+        while (len < size && samplesInChunk < 100) {
+            len += packed_size[(pkt->data[len] >> 3) & 0x0F];
+            samplesInChunk++;
+        }
+        if(samplesInChunk > 1){
+            av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
+            return -1;
+        }
+    } else if (trk->sampleSize)
+        samplesInChunk = size/trk->sampleSize;
+    else
+        samplesInChunk = 1;
+
+    /* copy extradata if it exists */
+    if (trk->vosLen == 0 && enc->extradata_size > 0) {
+        trk->vosLen = enc->extradata_size;
+        trk->vosData = av_malloc(trk->vosLen);
+        memcpy(trk->vosData, enc->extradata, trk->vosLen);
+    }
+
+    if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) {
+        /* from x264 or from bytestream h264 */
+        /* nal reformating needed */
+        int ret = ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size);
+        if (ret < 0)
+            return ret;
+        assert(pkt->size);
+        size = pkt->size;
+    } else if (enc->codec_id == CODEC_ID_DNXHD && !trk->vosLen) {
+        /* copy frame header to create needed atoms */
+        if (size < 640)
+            return -1;
+        trk->vosLen = 640;
+        trk->vosData = av_malloc(trk->vosLen);
+        memcpy(trk->vosData, pkt->data, 640);
+    }
+
+    if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
+        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
+        if (!trk->cluster)
+            return -1;
+    }
+
+    trk->cluster[trk->entry].pos = url_ftell(pb);
+    trk->cluster[trk->entry].samplesInChunk = samplesInChunk;
+    trk->cluster[trk->entry].size = size;
+    trk->cluster[trk->entry].entries = samplesInChunk;
+    trk->cluster[trk->entry].dts = pkt->dts;
+    trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration;
+
+    if(enc->codec_type == CODEC_TYPE_VIDEO) {
+        if (pkt->dts != pkt->pts)
+            trk->hasBframes = 1;
+        trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
+        trk->cluster[trk->entry].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
+        if(trk->cluster[trk->entry].key_frame)
+            trk->hasKeyframes++;
+    }
+    trk->entry++;
+    trk->sampleCount += samplesInChunk;
+    mov->mdat_size += size;
+
+    put_buffer(pb, pkt->data, 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;
+
+    offset_t moov_pos = url_ftell(pb);
+
+    /* Write size of mdat tag */
+    if (mov->mdat_size+8 <= UINT32_MAX) {
+        url_fseek(pb, mov->mdat_pos, SEEK_SET);
+        put_be32(pb, mov->mdat_size+8);
+    } else {
+        /* overwrite 'wide' placeholder atom */
+        url_fseek(pb, mov->mdat_pos - 8, SEEK_SET);
+        put_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */
+        put_tag(pb, "mdat");
+        put_be64(pb, mov->mdat_size+16);
+    }
+    url_fseek(pb, moov_pos, SEEK_SET);
+
+    mov_write_moov_tag(pb, mov, s);
+
+    for (i=0; i<mov->nb_streams; i++) {
+        av_freep(&mov->tracks[i].cluster);
+
+        if( mov->tracks[i].vosLen ) av_free( mov->tracks[i].vosData );
+
+    }
+
+    put_flush_packet(pb);
+
+    return res;
+}
+
+#ifdef CONFIG_MOV_MUXER
+AVOutputFormat mov_muxer = {
+    "mov",
+    "mov format",
+    NULL,
+    "mov",
+    sizeof(MOVContext),
+    CODEC_ID_AAC,
+    CODEC_ID_MPEG4,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){codec_movvideo_tags, codec_movaudio_tags, 0},
+};
+#endif
+#ifdef CONFIG_TGP_MUXER
+AVOutputFormat tgp_muxer = {
+    "3gp",
+    "3gp format",
+    NULL,
+    "3gp",
+    sizeof(MOVContext),
+    CODEC_ID_AMR_NB,
+    CODEC_ID_H263,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},
+};
+#endif
+#ifdef CONFIG_MP4_MUXER
+AVOutputFormat mp4_muxer = {
+    "mp4",
+    "mp4 format",
+    "application/mp4",
+    "mp4,m4a",
+    sizeof(MOVContext),
+    CODEC_ID_AAC,
+    CODEC_ID_MPEG4,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},
+};
+#endif
+#ifdef CONFIG_PSP_MUXER
+AVOutputFormat psp_muxer = {
+    "psp",
+    "psp mp4 format",
+    NULL,
+    "mp4,psp",
+    sizeof(MOVContext),
+    CODEC_ID_AAC,
+    CODEC_ID_MPEG4,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},
+};
+#endif
+#ifdef CONFIG_TG2_MUXER
+AVOutputFormat tg2_muxer = {
+    "3g2",
+    "3gp2 format",
+    NULL,
+    "3g2",
+    sizeof(MOVContext),
+    CODEC_ID_AMR_NB,
+    CODEC_ID_H263,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},
+};
+#endif


simplify meta tag writing code

simplify meta tag writing code

git-svn-id: a4d7c1866f8397a4106e0b57fc4fbf792bbdaaaf@5403 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

--- libavformat/movenc.c
+++ libavformat/movenc.c
@@ -1066,135 +1066,45 @@
 }

 /* helper function to write a data tag with the specified string as data */
-static int mov_write_string_data_tag(ByteIOContext *pb, MOVContext* mov,
-                                     AVFormatContext *s, const char *data)
-{
-    offset_t pos = url_ftell(pb);
-    put_be32(pb, 0); /* size */
-    put_tag(pb, "data");
-    put_be32(pb, 1);
-    put_be32(pb, 0);
-    put_buffer(pb, data, strlen(data));
-    return updateSize(pb, pos);
-}
-
-/* iTunes name of the song/movie */
-static int mov_write_nam_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    int size = 0;
-    if ( s->title[0] ) {
+static int mov_write_string_data_tag(ByteIOContext *pb, const char *data, int long_style)
+{
+    if(long_style){
         offset_t pos = url_ftell(pb);
         put_be32(pb, 0); /* size */
-        put_tag(pb, "\251nam");
-        mov_write_string_data_tag(pb, mov, s, s->title);
-        size = updateSize(pb, pos);
-    }
-    return size;
-}
-
-/* iTunes name of the artist/performer */
-static int mov_write_ART_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
+        put_tag(pb, "data");
+        put_be32(pb, 1);
+        put_be32(pb, 0);
+        put_buffer(pb, data, strlen(data));
+        return updateSize(pb, pos);
+    }else{
+        put_be16(pb, strlen(data)); /* string length */
+        put_be16(pb, 0);
+        put_buffer(pb, data, strlen(data));
+        return strlen(data) + 4;
+    }
+}
+
+static int mov_write_string_tag(ByteIOContext *pb, char *name, char *value, int long_style){
     int size = 0;
-    if ( s->author[0] ) {
+    if ( value && value[0] ) {
         offset_t pos = url_ftell(pb);
         put_be32(pb, 0); /* size */
-        put_tag(pb, "\251ART");
-        // we use the author here as this is the only thing that we have...
-        mov_write_string_data_tag(pb, mov, s, s->author);
-        size = updateSize(pb, pos);
+        put_tag(pb, name);
+        mov_write_string_data_tag(pb, value, long_style);
+        size= updateSize(pb, pos);
     }
     return size;
 }

-/* iTunes name of the writer */
-static int mov_write_wrt_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    int size = 0;
-    if ( s->author[0] ) {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251wrt");
-        mov_write_string_data_tag(pb, mov, s, s->author);
-        size = updateSize(pb, pos);
-    }
-    return size;
-}
-
-/* iTunes name of the album */
-static int mov_write_alb_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    int size = 0;
-    if ( s->album[0] ) {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251alb");
-        mov_write_string_data_tag(pb, mov, s, s->album);
-        size = updateSize(pb, pos);
-    }
-    return size;
-}
-
 /* iTunes year */
-static int mov_write_day_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    char year[5];
-    int size = 0;
-    if ( s->year ) {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251day");
-        snprintf(year, 5, "%04d", s->year);
-        mov_write_string_data_tag(pb, mov, s, year);
-        size = updateSize(pb, pos);
-    }
-    return size;
-}
-
-/* iTunes tool used to create the file */
-static int mov_write_too_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    offset_t pos = url_ftell(pb);
-    put_be32(pb, 0); /* size */
-    put_tag(pb, "\251too");
-    mov_write_string_data_tag(pb, mov, s, LIBAVFORMAT_IDENT);
-    return updateSize(pb, pos);
-}
-
-/* iTunes comment */
-static int mov_write_cmt_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    int size = 0;
-    if ( s->comment[0] ) {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251cmt");
-        mov_write_string_data_tag(pb, mov, s, s->comment);
-        size = updateSize(pb, pos);
-    }
-    return size;
-}
-
-/* iTunes custom genre */
-static int mov_write_gen_tag(ByteIOContext *pb, MOVContext* mov,
-                             AVFormatContext *s)
-{
-    int size = 0;
-    if ( s->genre[0] ) {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251gen");
-        mov_write_string_data_tag(pb, mov, s, s->genre);
-        size = updateSize(pb, pos);
-    }
-    return size;
+static int mov_write_day_tag(ByteIOContext *pb, int year, int long_style)
+{
+    if(year){
+        char year_str[5];
+        snprintf(year_str, sizeof(year_str), "%04d", year);
+        return mov_write_string_tag(pb, "\251day", year_str, long_style);
+    }else
+        return 0;
 }

 /* iTunes track number */
@@ -1230,14 +1140,14 @@
     offset_t pos = url_ftell(pb);
     put_be32(pb, 0); /* size */
     put_tag(pb, "ilst");
-    mov_write_nam_tag(pb, mov, s);
-    mov_write_ART_tag(pb, mov, s);
-    mov_write_wrt_tag(pb, mov, s);
-    mov_write_alb_tag(pb, mov, s);
-    mov_write_day_tag(pb, mov, s);
-    mov_write_too_tag(pb, mov, s);
-    mov_write_cmt_tag(pb, mov, s);
-    mov_write_gen_tag(pb, mov, s);
+    mov_write_string_tag(pb, "\251nam", s->title         , 1);
+    mov_write_string_tag(pb, "\251ART", s->author        , 1);
+    mov_write_string_tag(pb, "\251wrt", s->author        , 1);
+    mov_write_string_tag(pb, "\251alb", s->album         , 1);
+    mov_write_day_tag(pb, s->year ,1);
+    mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 1);
+    mov_write_string_tag(pb, "\251cmt", s->comment       , 1);
+    mov_write_string_tag(pb, "\251gen", s->genre         , 1);
     mov_write_trkn_tag(pb, mov, s);
     return updateSize(pb, pos);
 }
@@ -1279,62 +1189,19 @@
         if(mov->tracks[i].entry <= 0) continue;
         if (mov->tracks[i].enc->codec_id == CODEC_ID_AAC ||
             mov->tracks[i].enc->codec_id == CODEC_ID_MPEG4) {
-            offset_t pos = url_ftell(pb);
-            put_be32(pb, 0); /* size */
-            put_tag(pb, "\251req");
-            put_be16(pb, sizeof("QuickTime 6.0 or greater") - 1);
-            put_be16(pb, 0);
-            put_buffer(pb, "QuickTime 6.0 or greater",
-                       sizeof("QuickTime 6.0 or greater") - 1);
-            updateSize(pb, pos);
+            mov_write_string_tag(pb, "\251req", "QuickTime 6.0 or greater", 0);
             break;
         }
     }

-    /* Encoder */
+    mov_write_string_tag(pb, "\251nam", s->title         , 0);
+    mov_write_string_tag(pb, "\251aut", s->author        , 0);
+    mov_write_string_tag(pb, "\251alb", s->album         , 0);
+    mov_write_day_tag(pb, s->year, 0);
     if(mov->tracks[0].enc && !(mov->tracks[0].enc->flags & CODEC_FLAG_BITEXACT))
-    {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251enc");
-        put_be16(pb, sizeof(LIBAVFORMAT_IDENT) - 1); /* string length */
-        put_be16(pb, 0);
-        put_buffer(pb, LIBAVFORMAT_IDENT, sizeof(LIBAVFORMAT_IDENT) - 1);
-        updateSize(pb, pos);
-    }
-
-    if( s->title[0] )
-    {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251nam");
-        put_be16(pb, strlen(s->title)); /* string length */
-        put_be16(pb, 0);
-        put_buffer(pb, s->title, strlen(s->title));
-        updateSize(pb, pos);
-    }
-
-    if( s->author[0] )
-    {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, /*"\251aut"*/ "\251day" );
-        put_be16(pb, strlen(s->author)); /* string length */
-        put_be16(pb, 0);
-        put_buffer(pb, s->author, strlen(s->author));
-        updateSize(pb, pos);
-    }
-
-    if( s->comment[0] )
-    {
-        offset_t pos = url_ftell(pb);
-        put_be32(pb, 0); /* size */
-        put_tag(pb, "\251des");
-        put_be16(pb, strlen(s->comment)); /* string length */
-        put_be16(pb, 0);
-        put_buffer(pb, s->comment, strlen(s->comment));
-        updateSize(pb, pos);
-    }
+        mov_write_string_tag(pb, "\251enc", LIBAVFORMAT_IDENT, 0);
+    mov_write_string_tag(pb, "\251des", s->comment       , 0);
+    mov_write_string_tag(pb, "\251gen", s->genre         , 0);

     return updateSize(pb, pos);
 }


need to keep __check_rhosts_file exported for proper rhost control

--- libc/inet/rpc/rcmd.c
+++ libc/inet/rpc/rcmd.c
@@ -368,7 +368,11 @@
 }
 libc_hidden_def(rresvport)

-static int  __check_rhosts_file = 1;
+/* This needs to be exported ... while it is not a documented interface
+ * for rcp related apps, it's a required one that is used to control the
+ * rhost behavior.  Legacy sucks.
+ */
+int  __check_rhosts_file = 1;

 int ruserok(rhost, superuser, ruser, luser)
 	const char *rhost, *ruser, *luser;


fileref: Pass toplevel window to file dialog

It's discouraged to open a dialog that's not associated with a parent
window. Here, we fetch the toplevel window containing the ChimaraGlk
widget to pass to the file dialog.

--- libchimara/fileref.c
+++ libchimara/fileref.c
@@ -229,10 +229,12 @@

 	gdk_threads_enter();

+	GtkWindow *toplevel = GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET(glk_data->self) ) );
+
 	switch(fmode)
 	{
 		case filemode_Read:
-			chooser = gtk_file_chooser_dialog_new("Select a file to open", NULL,
+			chooser = gtk_file_chooser_dialog_new("Select a file to open", toplevel,
 				GTK_FILE_CHOOSER_ACTION_OPEN,
 				_("_Cancel"), GTK_RESPONSE_CANCEL,
 				_("_Open"), GTK_RESPONSE_ACCEPT,
@@ -240,7 +242,7 @@
 			gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser), GTK_FILE_CHOOSER_ACTION_OPEN);
 			break;
 		case filemode_Write:
-			chooser = gtk_file_chooser_dialog_new("Select a file to save to", NULL,
+			chooser = gtk_file_chooser_dialog_new("Select a file to save to", toplevel,
 				GTK_FILE_CHOOSER_ACTION_SAVE,
 				_("_Cancel"), GTK_RESPONSE_CANCEL,
 				_("_Save"), GTK_RESPONSE_ACCEPT,
@@ -250,7 +252,7 @@
 			break;
 		case filemode_ReadWrite:
 		case filemode_WriteAppend:
-			chooser = gtk_file_chooser_dialog_new("Select a file to save to", NULL,
+			chooser = gtk_file_chooser_dialog_new("Select a file to save to", toplevel,
 				GTK_FILE_CHOOSER_ACTION_SAVE,
 				_("_Cancel"), GTK_RESPONSE_CANCEL,
 				_("_Save"), GTK_RESPONSE_ACCEPT,


all-filtered hold time changed to 120s

all-filtered hold time changed to 120s

--- services/bloomfilter.c
+++ services/bloomfilter.c
@@ -828,7 +828,7 @@
 	}
       } else if(p->state == 1) {
 	if(p->count >= bloomfilter->threshold * 2
-	   && now - p->laststatechanged > 60) {
+	   && now - p->laststatechanged > 120) {
 	  log_info("added all-filtered domain: %s numreq=%zu", buf, p->count);
 	  p->state = 2;
 	  p->laststatechanged = now;


Remove old debug print

Remove old debug print

--- libdcpu-vm/dcpuops.c
+++ libdcpu-vm/dcpuops.c
@@ -705,8 +705,6 @@

     *store_a = vm_hw_count(vm);

-    if (vm->debug) printf("\nhwn: %d devices", *store_a);
-
     VM_HOOK_FIRE(store_a);
     vm->skip = false;
 }


Changed comments to use multi-line comment syntax.

Apparently, you cannot use single-line comments within multi-line macros.

--- reflection.h
+++ reflection.h
@@ -83,19 +83,19 @@
         }                                                                                \
     };                                                                                \
                                                                                \
-    //! Here, we basically replace the reflected member-function,                                           \
-    //! by defining a new member-function template with the same name,                                      \
-    //! which simply forwards to the implementation of the reflect member-function.                         \
-    //! This forwarding happens indirectly, because at the point this function is defined,                  \
-    //! the implementation function is not yet available.                                                   \
+    /* Here, we basically replace the reflected member-function,                                        */  \
+    /* by defining a new member-function template with the same name,                                   */  \
+    /* which simply forwards to the implementation of the reflect member-function.                      */  \
+    /* This forwarding happens indirectly, because at the point this function is defined,               */  \
+    /* the implementation function is not yet available.                                                */  \
     template<typename... Args>                                                                              \
     auto name(Args &&... args) -> decltype(__reflect_tag_##name(std::forward<Args>(args)...))               \
     {                                                                                \
         reflection::Delayed<__reflect_thunker_##name, Args...>::thunk(*this, std::forward<Args>(args)...);  \
     }                                                                                \
                                                                                \
-    //! Here, we define a member-function that will contain the implementation                              \
-    //! of the reflected member-function.                                                                   \
+    /* Here, we define a member-function that will contain the implementation                           */  \
+    /* of the reflected member-function.                                                                */  \
     auto __reflect_thunk_##name                                                                             \

 struct Foo {};


Minor fix for keeping trie clean.

Minor fix for keeping trie clean.

--- libethereum/TrieDB.h
+++ libethereum/TrieDB.h
@@ -706,9 +706,10 @@
 		n = _orig[1];
 	else
 	{
-		// remove second item from the trie.
-		s = node(_orig[1].toHash<h256>());
-		killNode(_orig[1]);
+		// remove second item from the trie after derefrencing it into s & n.
+		auto lh = _orig[1].toHash<h256>();
+		s = node(lh);
+		killNode(lh);
 		n = RLP(s);
 	}
 	assert(n.itemCount() == 2);


2004-10-16  Lutz Mueller <lutz@users.sourceforge.net>

	Martin Willers <willers@xm-arts.de> found an off-by-one error:

	* libexif/exif-entry.c: libexif forget to add 1
	  to tm_mon from struct tm

--- libexif/exif-entry.c
+++ libexif/exif-entry.c
@@ -1224,7 +1224,7 @@
 		if (!e->data) break;
 		snprintf ((char *) e->data, e->size,
 			  "%04i:%02i:%02i %02i:%02i:%02i",
-			  tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
+			  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 			  tm->tm_hour, tm->tm_min, tm->tm_sec);
 		break;


runtime: Initialize variable to avoid compiler warning.

R=iant
CC=gofrontend-dev
https://golang.org/cl/101090043

--- libgo/runtime/chan.c
+++ libgo/runtime/chan.c
@@ -481,7 +481,7 @@
 _Bool
 runtime_chanrecv2(ChanType *t, Hchan* c, byte* v)
 {
-	bool received;
+	bool received = false;

 	chanrecv(t, c, v, true, &received);
 	return received;


Ignore reclaimed stat

Ignore reclaimed stat

--- libmemcached/stats.c
+++ libmemcached/stats.c
@@ -151,7 +151,8 @@
              strcmp("listen_disabled_num", key) == 0 ||
              strcmp("conn_yields", key) == 0 ||
              strcmp("auth_cmds", key) == 0 ||
-             strcmp("auth_errors", key) == 0))
+             strcmp("auth_errors", key) == 0 ||
+             strcmp("reclaimed", key) == 0))
   {
     WATCHPOINT_STRING(key);
     return MEMCACHED_UNKNOWN_STAT_KEY;


[32-bit clean] Use int64_t instead of size_t.

--- libndtypes/ndtypes.c
+++ libndtypes/ndtypes.c
@@ -1381,7 +1381,7 @@
     size = round_up(offset, maxalign, &overflow);

     if (shape > 0) {
-        size_t n = (size - offsets[shape-1]) - fields[shape-1].type->datasize;
+        int64_t n = (size - offsets[shape-1]) - fields[shape-1].type->datasize;
         pad[shape-1] = (uint16_t)n;
     }


hud: add widget margin and padding

hud: add widget margin and padding

--- libnodegl/node_hud.c
+++ libnodegl/node_hud.c
@@ -186,6 +186,9 @@
     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 };

+#define WIDGET_PADDING 4
+#define WIDGET_MARGIN  2
+
 enum {
     LATENCY_UPDATE_CPU,
     LATENCY_UPDATE_GPU,
@@ -590,15 +593,19 @@
 static inline int get_widget_width(enum widget_type type)
 {
     const struct widget_spec *spec = &widget_specs[type];
+    const int horizontal_layout = !spec->graph_h;
     return spec->graph_w
-         + spec->text_cols * FONT_W;
+         + spec->text_cols * FONT_W
+         + WIDGET_PADDING * (2 + horizontal_layout);
 }

 static inline int get_widget_height(enum widget_type type)
 {
     const struct widget_spec *spec = &widget_specs[type];
+    const int vertical_layout = !!spec->graph_h;
     return spec->graph_h
-         + spec->text_rows * FONT_H;
+         + spec->text_rows * FONT_H
+         + WIDGET_PADDING * (2 + vertical_layout);
 }

 static int create_widget(struct hud *s, enum widget_type type, const void *user_data, int x, int y)
@@ -621,20 +628,20 @@
         .rect.y    = y,
         .rect.w    = get_widget_width(type),
         .rect.h    = get_widget_height(type),
-        .text_x    = x,
-        .text_y    = y,
+        .text_x    = x + WIDGET_PADDING,
+        .text_y    = y + WIDGET_PADDING,
         .user_data = user_data,
     };

     if (horizontal_layout) {
-        widget.graph_rect.x = x + spec->text_cols * FONT_W;
-        widget.graph_rect.y = y;
+        widget.graph_rect.x = x + spec->text_cols * FONT_W + WIDGET_PADDING * 2;
+        widget.graph_rect.y = y + WIDGET_PADDING;
         widget.graph_rect.w = spec->graph_w;
-        widget.graph_rect.h = widget.rect.h;
+        widget.graph_rect.h = widget.rect.h - WIDGET_PADDING * 2;
     } else {
-        widget.graph_rect.x = x;
-        widget.graph_rect.y = y + spec->text_rows * FONT_H;
-        widget.graph_rect.w = widget.rect.w;
+        widget.graph_rect.x = x + WIDGET_PADDING;
+        widget.graph_rect.y = y + spec->text_rows * FONT_H + WIDGET_PADDING * 2;
+        widget.graph_rect.w = widget.rect.w - WIDGET_PADDING * 2;
         widget.graph_rect.h = spec->graph_h;
     }

@@ -667,8 +674,10 @@
     ngli_darray_init(&s->widgets, sizeof(struct widget), 0);

     /* Smallest dimensions possible (in pixels) */
-    const int min_width  = get_widget_width(WIDGET_LATENCY);
-    const int min_height = get_widget_height(WIDGET_LATENCY);
+    const int min_width  = WIDGET_MARGIN * 2
+                         + get_widget_width(WIDGET_LATENCY);
+    const int min_height = WIDGET_MARGIN * 2
+                         + get_widget_height(WIDGET_LATENCY);

     /* Compute buffer dimensions according to user specified aspect ratio and
      * minimal dimensions */
@@ -681,7 +690,9 @@
     }

     /* Latency widget in the top-left */
-    int ret = create_widget(s, WIDGET_LATENCY, NULL, 0, 0);
+    const int x_latency = WIDGET_MARGIN;
+    const int y_latency = WIDGET_MARGIN;
+    int ret = create_widget(s, WIDGET_LATENCY, NULL, x_latency, y_latency);
     if (ret < 0)
         return ret;


fixed a bug in GridFile_exists

fixed a bug in GridFile_exists

--- src/gridfs.c
+++ src/gridfs.c
@@ -340,7 +340,7 @@
 bson_bool_t GridFile_exists(GridFile* oGridFile)

 {
-  return (bson_bool_t)(oGridFile != NULL);
+  return (bson_bool_t)(oGridFile != NULL || oGridFile->obj == NULL);
 }

 /*--------------------------------------------------------------------*/


rtt: restore clear_color after rendertarget and viewport

--- libnodegl/node_rtt.c
+++ libnodegl/node_rtt.c
@@ -331,17 +331,17 @@

     ngli_node_draw(s->child);

+    if (s->samples > 0)
+        ngli_rendertarget_blit(rt, &s->rt, 0);
+
+    if (s->invalidate_depth_stencil)
+        ngli_gctx_invalidate_depth_stencil(ctx);
+
+    ngli_gctx_set_rendertarget(ctx, prev_rt);
+    ngli_gctx_set_viewport(ctx, prev_vp);
+
     if (s->use_clear_color)
         ngli_gctx_set_clear_color(ctx, prev_clear_color);
-
-    if (s->samples > 0)
-        ngli_rendertarget_blit(rt, &s->rt, 0);
-
-    if (s->invalidate_depth_stencil)
-        ngli_gctx_invalidate_depth_stencil(ctx);
-
-    ngli_gctx_set_rendertarget(ctx, prev_rt);
-    ngli_gctx_set_viewport(ctx, prev_vp);

     for (int i = 0; i < s->nb_color_textures; i++) {
         struct texture_priv *texture_priv = s->color_textures[i]->priv_data;


Updating operation parameters types in login and create object functions

Change-Id: Ia23172c473f852acdde0db90e0a23f7be50314fc
Signed-off-by: TanelDettenborn <b78e06a93b55ca1de0e9b602be506ea7b7368e0f@intel.com>

--- src/hal_gp.c
+++ src/hal_gp.c
@@ -316,7 +316,7 @@
 	operation.params[2].value.b = sig_len;
 	operation.params[3].value.a = hSession;
 	operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE,
-						TEEC_VALUE_INOUT, TEEC_VALUE_INOUT);
+						TEEC_VALUE_INPUT, TEEC_VALUE_INOUT);

 	/* Hand over execution to TEE */
 	teec_rv = TEEC_InvokeCommand(g_control_session, TEE_VERIFY, &operation, NULL);
@@ -535,7 +535,7 @@
 	operation.params[3].value.a = hSession;

 	operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_OUTPUT,
-						TEEC_VALUE_INOUT, TEEC_VALUE_INPUT);
+						TEEC_VALUE_INPUT, TEEC_VALUE_INPUT);

 	/* Hand over execution to TEE */
 	teec_ret = TEEC_InvokeCommand(g_control_session, TEE_CREATE_OBJECT, &operation, NULL);


Silly spelling error

Silly spelling error

--- libpthread/pthread.c
+++ libpthread/pthread.c
@@ -1,6 +1,6 @@
 /* vi: set sw=4 ts=4: */
 /*
- * A simple clopne based pthread implementation
+ * A simple clone based pthread implementation
  *
  * Copyright (C) 2001 by Erik Andersen <andersee@debian.org>
  *


use the right case

use the right case

svn path=/trunk/kdesupport/phonon/; revision=812239

--- phonon/phonon_export.h
+++ phonon/phonon_export.h
@@ -24,7 +24,7 @@

 #ifndef PHONON_EXPORT
 # if defined _WIN32 || defined _WIN64
-#  ifdef PHONON_EXPORTS /* We are building this library */
+#  ifdef phonon_EXPORTS /* We are building this library */
 #   define PHONON_EXPORT Q_DECL_EXPORT
 #  else /* We are using this library */
 #   define PHONON_EXPORT Q_DECL_IMPORT


Avoid using <string.h> in the "call0" test

--- tests/call0.c
+++ tests/call0.c
@@ -30,7 +30,6 @@

 #include <inttypes.h>
 #include <stdio.h>
-#include <string.h>
 #include "System/Marshall.h"

 #ifndef PROGNAME
@@ -110,7 +109,7 @@
 	float f = -1.0;
 	int32_t r32 = -1;
 	int64_t r64 = -1;
-	char * s;
+	String * s;

 	/* VT_INT32 */
 	if((res = variable_new(VT_INT32, r32)) == NULL)
@@ -160,7 +159,8 @@
 	variable_delete(res);
 	if(ret != 0)
 		return 15;
-	if(strcmp(s, "_call0_string") != 0)
+	if(string_compare(s, "_call0_string") != 0)
 		return 16;
+	string_delete(s);
 	return 0;
 }


memset

memset

error: pathspec 'linux/memset.c' did not match any file(s) known to git


Allow bonding during periodic inquiry

Allow bonding during periodic inquiry

--- hcid/adapter.c
+++ hcid/adapter.c
@@ -2792,7 +2792,7 @@
 	str2ba(address, &bdaddr);

 	/* check if there is a pending discover: requested by D-Bus/non clients */
-	if (adapter->discov_active || (adapter->pdiscov_active && !adapter->pinq_idle))
+	if (adapter->discov_active)
 		return in_progress(msg, "Discover in progress");

 	pending_remote_name_cancel(adapter);


Remove trailing whitespace(s) in src/connection/config_file.h

--- src/connection/config_file.h
+++ src/connection/config_file.h
@@ -57,4 +57,4 @@
 /**
  * @}
  */
-
+


gestures: Fix silly typo on get_center() implementation

Don't mix up coordinates when calculating the bounding box center

Signed-off-by: Carlos Garnacho <ab5e2bca84933118bbc9d48ffaccce3bac4eeb64@lanedo.com>
Acked-by: Simon Schampijer <088e16a1019277b15d58faf0541e11910eb756f6@laptop.org>
Tested-by: Manuel Kaufmann <54d769c38f2aa6d2679b577ce2986fc3d1abeaba@gmail.com>

--- src/sugar3/event-controller/sugar-touch-controller.c
+++ src/sugar3/event-controller/sugar-touch-controller.c
@@ -264,7 +264,7 @@
       x1 = MIN (x1, point->x);
       y1 = MIN (y1, point->y);
       x2 = MAX (x2, point->x);
-      y2 = MAX (y2, point->x);
+      y2 = MAX (y2, point->y);
     }

   if (center_x)


For avmshell, use direct thunks by default in DEBUGGER builds (bug 534279 r=stejohns+)

If an explicit AVMFEATURE_INDIRECT_NATIVE_THUNKS setting is not passed in via configure.py,
then we use direct thunks in DEBUGGER builds and indirect in release builds.  This way
both configurations get tested.  The code size increase for direct thunks is acceptable
in debugger builds.

--- shell/avmshell-features.h
+++ shell/avmshell-features.h
@@ -151,7 +151,12 @@
 #endif

 #ifndef AVMFEATURE_INDIRECT_NATIVE_THUNKS
-  #define AVMFEATURE_INDIRECT_NATIVE_THUNKS 1
+  // if not specified, default to direct thunks in DEBUGGER builds
+  #if AVMFEATURE_DEBUGGER
+    #define AVMFEATURE_INDIRECT_NATIVE_THUNKS 0
+  #else
+    #define AVMFEATURE_INDIRECT_NATIVE_THUNKS 1
+  #endif
 #endif

 #if !defined(_DEBUG) && !defined(DEBUG)


Added a note about 'Allocator sizeof operand mismatch' warning

--- ext/phalcon.c
+++ ext/phalcon.c
@@ -793,25 +793,30 @@

 	phalcon_globals->start_memory = start;

+	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
 	ALLOC_PERMANENT_ZVAL(phalcon_globals->z_null);
 	INIT_ZVAL(*phalcon_globals->z_null);
 	Z_ADDREF_P(phalcon_globals->z_null);

+	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
 	ALLOC_PERMANENT_ZVAL(phalcon_globals->z_false);
 	INIT_PZVAL(phalcon_globals->z_false);
 	Z_ADDREF_P(phalcon_globals->z_false);
 	ZVAL_FALSE(phalcon_globals->z_false);

+	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
 	ALLOC_PERMANENT_ZVAL(phalcon_globals->z_true);
 	INIT_PZVAL(phalcon_globals->z_true);
 	Z_ADDREF_P(phalcon_globals->z_true);
 	ZVAL_TRUE(phalcon_globals->z_true);

+	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
 	ALLOC_PERMANENT_ZVAL(phalcon_globals->z_zero);
 	INIT_PZVAL(phalcon_globals->z_zero);
 	Z_ADDREF_P(phalcon_globals->z_zero);
 	ZVAL_LONG(phalcon_globals->z_zero, 0);

+	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
 	ALLOC_PERMANENT_ZVAL(phalcon_globals->z_one);
 	INIT_PZVAL(phalcon_globals->z_one);
 	Z_ADDREF_P(phalcon_globals->z_one);


Add staticRoutes property

Add staticRoutes property

--- ext/php_mux.c
+++ ext/php_mux.c
@@ -50,9 +50,9 @@
     ce_pux_mux = zend_register_internal_class(&ce TSRMLS_CC);
     zend_declare_property_null(ce_pux_mux, "id", strlen("id"), ZEND_ACC_PUBLIC TSRMLS_CC);
     zend_declare_property_null(ce_pux_mux, "routes", strlen("routes"), ZEND_ACC_PUBLIC TSRMLS_CC);
+    zend_declare_property_null(ce_pux_mux, "staticRoutes", strlen("staticRoutes"), ZEND_ACC_PUBLIC TSRMLS_CC);
     zend_declare_property_null(ce_pux_mux, "submux", strlen("submux"), ZEND_ACC_PUBLIC TSRMLS_CC);
     zend_declare_property_bool(ce_pux_mux, "expand", strlen("expand"), 1, ZEND_ACC_PUBLIC TSRMLS_CC);
-    zend_declare_property_null(ce_pux_mux, "staticRoutes", strlen("staticRoutes"), ZEND_ACC_PUBLIC TSRMLS_CC);
     zend_declare_property_long(ce_pux_mux, "id_counter", strlen("id_counter"), 0, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC TSRMLS_CC);
 }

@@ -134,6 +134,7 @@

     zval **z_id = NULL;
     zval **z_routes = NULL;
+    zval **z_static_routes = NULL;
     zval **z_submux = NULL;
     zval **z_expand = NULL;

@@ -145,6 +146,11 @@
     if ( zend_hash_find(z_array_hash, "routes", sizeof("routes"), (void**)&z_routes) == FAILURE ) {
         ALLOC_INIT_ZVAL(*z_routes);
         array_init(*z_routes);
+    }
+
+    if ( zend_hash_find(z_array_hash, "staticRoutes", sizeof("staticRoutes"), (void**)&z_static_routes) == FAILURE ) {
+        ALLOC_INIT_ZVAL(*z_static_routes);
+        array_init(*z_static_routes);
     }

     if ( zend_hash_find(z_array_hash, "submux", sizeof("submux"), (void**)&z_submux) == FAILURE ) {
@@ -167,6 +173,7 @@
     zend_update_property(ce_pux_mux, new_object, "routes", sizeof("routes")-1, *z_routes TSRMLS_CC);
     zend_update_property(ce_pux_mux, new_object, "submux", sizeof("submux")-1, *z_submux TSRMLS_CC);
     zend_update_property(ce_pux_mux, new_object, "expand", sizeof("expand")-1, *z_expand TSRMLS_CC);
+    zend_update_property(ce_pux_mux, new_object, "staticRoutes", sizeof("staticRoutes")-1, *z_static_routes TSRMLS_CC);
     *return_value = *new_object;
     zval_copy_ctor(return_value);
     zval_ptr_dtor(&z_array);
@@ -659,8 +666,8 @@

     zend_function *fe; // method entry
-    zend_hash_find( &Z_OBJCE_P(this_ptr)->function_table, "matchroute",    sizeof("matchroute"),    (void **) &fe);
-    zend_call_method( &this_ptr, ce_pux_mux, &fe, "matchroute", strlen("matchroute"), &z_return_route, 1, z_trimed_path, NULL TSRMLS_CC );
+    zend_hash_find( &Z_OBJCE_P(this_ptr)->function_table, "match",    sizeof("match"),    (void **) &fe);
+    zend_call_method( &this_ptr, ce_pux_mux, &fe, "match", strlen("match"), &z_return_route, 1, z_trimed_path, NULL TSRMLS_CC );

     if ( ! z_return_route || Z_TYPE_P(z_return_route) == IS_NULL ) {
         zval_ptr_dtor(&z_trimed_path);
@@ -922,6 +929,7 @@
             zend_throw_exception(ce_pux_exception, "Unable to compile route pattern.", 0 TSRMLS_CC);
             RETURN_FALSE;
         }
+        zval_ptr_dtor(&z_pattern);

         zval **z_compiled_route_pattern;
         if ( zend_hash_find( Z_ARRVAL_P(z_compiled_route) , "compiled", sizeof("compiled"), (void**)&z_compiled_route_pattern) == FAILURE ) {


Allow setting/getting of area position/angle

--- ext/rb_Area.c
+++ ext/rb_Area.c
@@ -2,10 +2,12 @@

 VALUE c_jgArea;

-VECTOR_GET(rb_jgAreaCenterOfMass, AREA, centerOfMass)
-VECTOR_GET(rb_jgAreaPosition,     AREA, derivedPosition)
-VECTOR_GET(rb_jgAreaVelocity,     AREA, derivedVelocity)
-FLOAT_GET( rb_jgAreaAngle,        AREA, derivedAngle)
+VECTOR_GET(rb_jgAreaCenterOfMass,    AREA, centerOfMass)
+VECTOR_GET(rb_jgAreaGetPosition,     AREA, derivedPosition)
+VECTOR_SET(rb_jgAreaSetPosition,     AREA, derivedPosition)
+VECTOR_GET(rb_jgAreaVelocity,        AREA, derivedVelocity)
+FLOAT_GET( rb_jgAreaGetAngle,        AREA, derivedAngle)
+FLOAT_SET( rb_jgAreaSetAngle,        AREA, derivedAngle)

 BOOL_GET(rb_jgAreaGetIsShapeMatching, AREA, isShapeMatching)
 BOOL_SET(rb_jgAreaSetIsShapeMatching, AREA, isShapeMatching)
@@ -103,9 +105,11 @@
      rb_define_method(c_jgArea, "area",             rb_jgAreaArea, 0);
      rb_define_method(c_jgArea, "center_of_mass",   rb_jgAreaCenterOfMass, 0);

-     rb_define_method(c_jgArea, "position",   rb_jgAreaPosition, 0);
+     rb_define_method(c_jgArea, "position",   rb_jgAreaGetPosition, 0);
+     rb_define_method(c_jgArea, "position=",  rb_jgAreaSetPosition, 1);
      rb_define_method(c_jgArea, "velocity",   rb_jgAreaVelocity, 0);
-     rb_define_method(c_jgArea, "angle",      rb_jgAreaAngle, 0);
+     rb_define_method(c_jgArea, "angle",      rb_jgAreaGetAngle, 0);
+     rb_define_method(c_jgArea, "angle=",     rb_jgAreaSetAngle, 1);

      rb_define_method(c_jgArea, "shape_matching?",    rb_jgAreaGetIsShapeMatching, 0);
      rb_define_method(c_jgArea, "shape_matching=",    rb_jgAreaSetIsShapeMatching, 1);


despotify_init_client now has high_bitrate and use_cache arguments Turn them both off for now

--- ext/session.c
+++ ext/session.c
@@ -64,7 +64,7 @@
 	rb_ds_session *session;
 	VALUE2SESSION(self, session);

-	if (!(session->real = despotify_init_client(rb_ds_session_callback, (void *) self))) {
+	if (!(session->real = despotify_init_client(rb_ds_session_callback, (void *) self, 0, 0))) {
 		rb_raise(rb_eNoMemError, "failed to allocate memory");
 		return Qnil;
 	}


Added File for serialised SMSG_ITEM_TEXT_QUERY_RESPONSE packet

error: pathspec 'src/world/Server/Packets/SmsgItemTextQueryResponse.h' did not match any file(s) known to git

--- src/world/Server/Packets/SmsgItemTextQueryResponse.h
+++ src/world/Server/Packets/SmsgItemTextQueryResponse.h
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2014-2018 AscEmu Team <http://www.ascemu.org>
+This file is released under the MIT license. See README-MIT for more information.
+*/
+
+#pragma once
+#include <cstdint>
+
+#include "ManagedPacket.h"
+
+namespace AscEmu { namespace Packets
+{
+    class SmsgItemTextQueryResponse : public ManagedPacket
+    {
+    public:
+        uint8_t result;
+        uint64_t guid;
+        std::string text;
+
+        SmsgItemTextQueryResponse() : SmsgItemTextQueryResponse(0, 0, "")
+        {
+        }
+
+        SmsgItemTextQueryResponse(uint8_t result, uint64_t guid, std::string text) :
+            ManagedPacket(SMSG_ITEM_TEXT_QUERY_RESPONSE, 0),
+            result(result),
+            guid(guid),
+            text(text)
+        {
+        }
+
+    protected:
+        size_t expectedSize() const override { return 1 + 8 + text.size(); }
+
+        bool internalSerialise(WorldPacket& packet) override
+        {
+            packet << result;
+            if (!result)
+                packet << guid << text;
+
+            return true;
+        }
+
+        bool internalDeserialise(WorldPacket& packet) override
+        {
+            return false;
+        }
+    };
+}}


Documented wsh_client_reset_dark_bg

Documented wsh_client_reset_dark_bg

--- library/src/client.h
+++ library/src/client.h
@@ -68,7 +68,6 @@
 gboolean wsh_client_get_dark_bg(void);

 /**
- * @internal
  * @brief Reset internal dark_bg val
  */
 void wsh_client_reset_dark_bg(void);


Remove blank lines

Remove blank lines

Signed-off-by: Gabor Mezei <73922791ae56b2f06debbf18b6e0a93a4bcd29f9@arm.com>

--- library/ssl_ticket.c
+++ library/ssl_ticket.c
@@ -88,7 +88,6 @@
         return( ret );

 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
     psa_set_key_usage_flags( &attributes,
                              PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
     psa_set_key_algorithm( &attributes, key->alg );
@@ -99,14 +98,11 @@
             psa_import_key( &attributes, buf,
                             PSA_BITS_TO_BYTES( key->key_bits ),
                             &key->key ) );
-
-#else
-
+#else
     /* With GCM and CCM, same context can encrypt & decrypt */
     ret = mbedtls_cipher_setkey( &key->ctx, buf,
                                  mbedtls_cipher_get_key_bitlen( &key->ctx ),
                                  MBEDTLS_ENCRYPT );
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

     mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -140,11 +136,9 @@
         ctx->active = 1 - ctx->active;

 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
         if( ( ret = psa_ssl_status_to_mbedtls(
                         psa_destroy_key( ctx->keys[ctx->active].key ) ) ) != 0 )
             return( ret );
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

         return( ssl_ticket_gen_key( ctx, ctx->active ) );
@@ -177,7 +171,6 @@
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );

 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
     if( ( ret = psa_ssl_status_to_mbedtls(
                     psa_destroy_key( key->key ) ) ) != 0 )
         return( ret );
@@ -193,13 +186,10 @@
                                     PSA_BITS_TO_BYTES( key->key_bits ),
                                     &key->key ) ) ) != 0 )
         return( ret );
-
-#else
-
+#else
     ret = mbedtls_cipher_setkey( &key->ctx, k, bitlen, MBEDTLS_ENCRYPT );
     if( ret != 0 )
         return( ret );
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

     ctx->active = idx;
@@ -246,7 +236,6 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );

 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
     if( mbedtls_ssl_cipher_to_psa( cipher_info->type, TICKET_AUTH_TAG_BYTES,
                                    &alg, &key_type, &key_bits ) != PSA_SUCCESS )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -258,15 +247,12 @@
     ctx->keys[1].alg = alg;
     ctx->keys[1].key_type = key_type;
     ctx->keys[1].key_bits = key_bits;
-
-#else
-
+#else
     if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 )
         return( ret );

     if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
         return( ret );
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

     if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 ||
@@ -506,15 +492,11 @@
 void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx )
 {
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
     psa_destroy_key( ctx->keys[0].key );
     psa_destroy_key( ctx->keys[1].key );
-
-#else
-
+#else
     mbedtls_cipher_free( &ctx->keys[0].ctx );
     mbedtls_cipher_free( &ctx->keys[1].ctx );
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

 #if defined(MBEDTLS_THREADING_C)