--- ffmpeg-ace432f/libavformat/movenc.c	2011-04-26 06:44:19.000000000 -0400
+++ changes/movenc.c	2011-10-12 14:58:21.000000000 -0400
@@ -20,6 +20,15 @@
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+//------------------------------------------------------Modifications History
+// DATE       DESCRIPTION
+// 06/09/2011 Resolution update for H264 reimplementation.
+// 05/27/2011 Added writing 'btrt' bitrate info box in H263
+// 03/07/2011 Write the AVCodecContext image size values to
+//            output file.
+// 02/28/2011 added support for max NAL size
+// 02/17/2011 Fixed handling of no data AMR frames
+// 02-22-2011 added support for max bitrate
 
 #include "movenc.h"
 #include "avformat.h"
@@ -473,16 +482,40 @@
     return updateSize(pb, pos);
 }
 
-static int mov_write_d263_tag(ByteIOContext *pb)
+/* Writes optional H263 specific 'bitr' box */
+static int mov_write_bitr_tag(ByteIOContext *pb, MOVTrack *track)
 {
-    put_be32(pb, 0xf); /* size */
+    put_be32(pb, 16);
+    put_tag(pb, "bitr");
+
+    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
+
+    put_be32(pb, track->enc->rc_max_rate); 
+    
+    return 16;
+}
+
+static int mov_write_d263_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = url_ftell(pb);
+
+    put_be32(pb, 0); /* size placeholder */
     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;
+
+    /* Write optional H263 specific 'bitr' box, which holds
+       the bitrate info */
+    mov_write_bitr_tag(pb, track);
+
+    return updateSize(pb, pos);
 }
 
 /* TODO: No idea about these values */
@@ -744,6 +777,57 @@
     return updateSize(pb, pos);
 }
 
+// Write the optional MP4 'btrt' box, in H264 case it comes after avcC
+// inside avc1. Not suitable for H263, which has its own special 'bitr' box.
+static int mov_write_btrt_tag(ByteIOContext *pb, MOVTrack *track)
+{
+    put_be32(pb, 20);
+    put_tag(pb, "btrt");
+    put_be32(pb,  track->enc->rc_buffer_size); // Buffersize DB (32 bits)
+
+    put_be32(pb, track->enc->rc_max_rate); 
+    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
+
+    return 20;
+}
+
+// Write the non-standard 'cmvt' box at "stsd" level
+static int mov_write_cmvt_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
+{
+    AVMetadataTag *pAVMetadataTag = NULL;
+    int nNalSize = 0;
+    if ( NULL == st )
+    {
+        av_log(NULL, AV_LOG_ERROR,
+             "mov_write_cmvt_tag() st is NULL !!!\n");
+        return 0;
+    }
+    if ( NULL ==st->metadata )
+    {
+        av_log(NULL, AV_LOG_ERROR,
+             "mov_write_cmvt_tag() st->metadata is NULL !!!\n");
+    }
+    pAVMetadataTag = av_metadata_get(st->metadata, "NALSize", NULL, 0);
+
+    if (!pAVMetadataTag || !strlen(pAVMetadataTag->value))
+    {
+        av_log(NULL, AV_LOG_ERROR,
+            "mov_write_cmvt_tag() pAVMetadataTag is NULL or bad value\n");
+        return 0;
+    }
+    nNalSize = atoi(pAVMetadataTag->value);
+    put_be32(pb, 20);
+    put_tag(pb, "cmvt");
+    put_be32(pb, nNalSize); // NAL size (32 bits)
+    put_be32(pb, 0); // empty
+    put_be32(pb, 0); // empty
+    return 20;
+}
+
 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track)
 {
     int64_t pos = url_ftell(pb);
@@ -771,8 +855,13 @@
         put_be32(pb, 0); /* Reserved */
         put_be32(pb, 0); /* Reserved */
     }
-    put_be16(pb, track->enc->width); /* Video width */
-    put_be16(pb, track->height); /* Video height */
+
+    put_be16(pb, track->enc->width); /* Video width - for it 'enc' is always used */
+    /* Video height - in most cases should be the same as 'enc'.
+       If explicitly updating picture size after mov_write_header, 
+       make sure to call cms_mov_update_dimensions(). */
+    put_be16(pb, track->height); 
+
     put_be32(pb, 0x00480000); /* Horizontal resolution 72dpi */
     put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */
     put_be32(pb, 0); /* Data size (= 0) */
@@ -792,14 +881,17 @@
     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_H263)
+    {
+        mov_write_d263_tag(pb, track);
+    }
     else if(track->enc->codec_id == CODEC_ID_SVQ3)
         mov_write_svq3_tag(pb);
     else if(track->enc->codec_id == CODEC_ID_DNXHD)
         mov_write_avid_tag(pb, track);
     else if(track->enc->codec_id == CODEC_ID_H264) {
         mov_write_avcc_tag(pb, track);
+        mov_write_btrt_tag(pb, track);
         if(track->mode == MODE_IPOD)
             mov_write_uuid_tag_ipod(pb);
     } else if(track->vosLen > 0)
@@ -1266,6 +1358,8 @@
     if (track->tref_tag)
         mov_write_tref_tag(pb, track);
     mov_write_mdia_tag(pb, track);
+    if ( st && st->codec && CODEC_ID_H264 == st->codec->codec_id)
+        mov_write_cmvt_tag(pb, track, st);
     if (track->mode == MODE_PSP)
         mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box
     if (track->tag == MKTAG('r','t','p',' '))
@@ -2180,6 +2281,77 @@
     return res;
 }
 
+/* That function is used to update video resolution after mov_write_header. */
+int cms_mov_update_dimensions(AVFormatContext *s, int streamNumber,
+                              unsigned int imageWidthInPixels, 
+                              unsigned int imageHeightInPixels, 
+                              AVRational *sampleAspectRatio)
+{
+    MOVMuxContext *mov;
+    MOVTrack *track;
+
+    if ((s == NULL) || (streamNumber >= s->nb_streams))
+    {
+        // inexistent stream
+        av_log(s, AV_LOG_ERROR, "Stream %d does not exist\n",
+               streamNumber);
+        return -1;
+    }
+
+    if (s->streams[streamNumber]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+    {
+        // We only update resolution for video streams
+        av_log(s, AV_LOG_ERROR, "Stream %d is not video\n",
+               streamNumber);
+        return -2;
+    }
+
+    // Internal, .mov specific parts
+    mov = s->priv_data;
+
+    if (!mov)
+    {
+        av_log(s, AV_LOG_ERROR, "MOV context does not exist\n");
+        return -3;
+    }
+
+    track = &mov->tracks[streamNumber];
+
+    if (!track)
+    {
+        av_log(s, AV_LOG_ERROR, "MOV track %d does not exist\n",
+               streamNumber);
+        return -4;
+    }
+
+    /* Special handling for D-10/IMX */
+    if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
+        track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
+        track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) 
+    {
+        if ((imageWidthInPixels != 720) || 
+            ((imageHeightInPixels != 608) && (imageHeightInPixels != 512)))
+        {
+           av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
+           return -5;
+        }
+        
+        track->height = track->tag>>24 == 'n' ? 486 : 576;
+    }
+    else
+    {
+        track->height = imageHeightInPixels;
+    }
+
+    // High level (visible outside) parts
+    s->streams[streamNumber]->codec->width = imageWidthInPixels;
+    s->streams[streamNumber]->codec->height = imageHeightInPixels;
+    s->streams[streamNumber]->sample_aspect_ratio = *sampleAspectRatio;
+    s->streams[streamNumber]->codec->sample_aspect_ratio = *sampleAspectRatio;
+
+    return 0;
+}
+
 #if CONFIG_MOV_MUXER
 AVOutputFormat mov_muxer = {
     "mov",
