changeset 903:22ee74da2cd3 libavcodec

cleanup adding AVVideoFrame moving quality, pict_type, key_frame, qscale_table, ... to AVVideoFrame removing obsolete variables in AVCodecContext skiping of MBs in b frames correctly initalizing AVCodecContext picture buffer cleanup
author michaelni
date Wed, 04 Dec 2002 10:04:03 +0000
parents 6acc8394960d
children 06776293eabb
files avcodec.h dv.c error_resilience.c h263.c h263dec.c huffyuv.c mjpeg.c motion_est.c mpeg12.c mpegvideo.c mpegvideo.h msmpeg4.c ratecontrol.c rv10.c svq1.c utils.c
diffstat 16 files changed, 949 insertions(+), 863 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Tue Dec 03 19:40:35 2002 +0000
+++ b/avcodec.h	Wed Dec 04 10:04:03 2002 +0000
@@ -5,8 +5,8 @@
 
 #define LIBAVCODEC_VERSION_INT 0x000406
 #define LIBAVCODEC_VERSION     "0.4.6"
-#define LIBAVCODEC_BUILD       4640
-#define LIBAVCODEC_BUILD_STR   "4640"
+#define LIBAVCODEC_BUILD       4641
+#define LIBAVCODEC_BUILD_STR   "4641"
 
 enum CodecID {
     CODEC_ID_NONE, 
@@ -140,7 +140,6 @@
 #define CODEC_FLAG_EXTERN_HUFF 0x1000 /* use external huffman table (for mjpeg) */
 #define CODEC_FLAG_GRAY  0x2000   /* only decode/encode grayscale */
 #define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */
-#define CODEC_FLAG_DR1    0x8000  /* direct renderig type 1 (store internal frames in external buffers) */
 #define CODEC_FLAG_TRUNCATED  0x00010000 /* input bitstream might be truncated at a random location instead 
                                             of only at frame boundaries */
 #define CODEC_FLAG_NORMALIZE_AQP  0x00020000 /* normalize adaptive quantization */
@@ -159,6 +158,111 @@
 
 #define FRAME_RATE_BASE 10000
 
+#define FF_COMMON_PICTURE \
+    uint8_t *data[4];\
+    int linesize[4];\
+    /**\
+     * pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer
+     * this isnt used by lavc unless the default get/release_buffer() is used\
+     * encoding: \
+     * decoding: \
+     */\
+    uint8_t *base[4];\
+    /**\
+     * 1 -> keyframe, 0-> not\
+     * encoding: set by lavc\
+     * decoding: set by lavc\
+     */\
+    int key_frame;\
+\
+    /**\
+     * picture type of the frame, see ?_TYPE below\
+     * encoding: set by lavc for coded_picture (and set by user for input)\
+     * decoding: set by lavc\
+     */\
+    int pict_type;\
+\
+    /**\
+     * presentation timestamp in micro seconds (time when frame should be shown to user)\
+     * if 0 then the frame_rate will be used as reference\
+     * encoding: MUST be set by user\
+     * decoding: set by lavc\
+     */\
+    long long int pts;\
+\
+    /**\
+     * picture number in bitstream order.\
+     * encoding: set by\
+     * decoding: set by lavc\
+     */\
+    int coded_picture_number;\
+    /**\
+     * encoding: set by\
+     * decoding: set by lavc\
+     * picture number in display order.\
+     */\
+    int display_picture_number;\
+\
+    /**\
+     * quality (between 1 (good) and 31 (bad)) \
+     * encoding: set by lavc for coded_picture (and set by user for input)\
+     * decoding: set by lavc\
+     */\
+    float quality; \
+\
+    /**\
+     * buffer age (1->was last buffer and dint change, 2->..., ...).\
+     * set to something large if the buffer has not been used yet \
+     * encoding: unused\
+     * decoding: MUST be set by get_buffer()\
+     */\
+    int age;\
+\
+    /**\
+     * is this picture used as reference\
+     * encoding: unused\
+     * decoding: set by lavc (before get_buffer() call))\
+     */\
+    int reference;\
+\
+    /**\
+     * QP table\
+     * encoding: unused\
+     * decoding: set by lavc\
+     */\
+    int8_t *qscale_table;\
+    /**\
+     * QP store stride\
+     * encoding: unused\
+     * decoding: set by lavc\
+     */\
+    int qstride;\
+\
+    /**\
+     * mbskip_table[mb]>=1 if MB didnt change\
+     * stride= mb_width = (width+15)>>4\
+     * encoding: unused\
+     * decoding: set by lavc\
+     */\
+    uint8_t *mbskip_table;\
+\
+    /**\
+     * for some private data of the user\
+     * encoding: unused\
+     * decoding: set by user\
+     */\
+    void *opaque;\
+
+/* FIXME: these should have FF_ */
+#define I_TYPE 1 // Intra
+#define P_TYPE 2 // Predicted
+#define B_TYPE 3 // Bi-dir predicted
+#define S_TYPE 4 // S(GMC)-VOP MPEG4
+
+typedef struct AVVideoFrame {
+    FF_COMMON_PICTURE
+} AVVideoFrame;
+
 typedef struct AVCodecContext {
     /**
      * the average bitrate
@@ -191,7 +295,7 @@
 
     /**
      * motion estimation algorithm used for video coding
-     * encoding: set by user.
+     * encoding: MUST be set by user.
      * decoding: unused
      */
     int me_method;
@@ -212,21 +316,17 @@
      * frames per sec multiplied by FRAME_RATE_BASE
      * for variable fps this is the precission, so if the timestamps 
      * can be specified in msec precssion then this is 1000*FRAME_RATE_BASE
-     * encoding: set by user
+     * encoding: MUST be set by user
      * decoding: set by lavc. 0 or the frame_rate if available
      */
     int frame_rate;
 
     /**
-     * encoding: set by user.
+     * encoding: MUST be set by user. 
      * decoding: set by user, some codecs might override / change it during playback
      */
     int width, height;
     
-    /**
-     * Obsolete, will be removed
-     */
-    int aspect_ratio_info;
 #define FF_ASPECT_SQUARE 1
 #define FF_ASPECT_4_3_625 2
 #define FF_ASPECT_4_3_525 3
@@ -274,52 +374,23 @@
     int frame_number;   /* audio or video frame number */
     int real_pict_num;  /* returns the real picture number of
                            previous encoded frame */
-                           
+    
     /**
-     * 1 -> keyframe, 0-> not
+     * 1 -> keyframe, 0-> not (this if for audio only, for video, AVVideoFrame.key_frame should be used)
      * encoding: set by lavc (for the outputed bitstream, not the input frame)
      * decoding: set by lavc (for the decoded  bitstream, not the displayed frame)
      */
     int key_frame;
 
     /**
-     * picture type of the previous en/decoded frame, see ?_TYPE below
-     * encoding: set by lavc (for the outputed bitstream, not the input frame)
-     * decoding: set by lavc (for the decoded  bitstream, not the displayed frame)
-     */
-    int pict_type;
-/* FIXME: these should have FF_ */
-#define I_TYPE 1 // Intra
-#define P_TYPE 2 // Predicted
-#define B_TYPE 3 // Bi-dir predicted
-#define S_TYPE 4 // S(GMC)-VOP MPEG4
-
-    /**
      * number of frames the decoded output will be delayed relative to 
      * the encoded input
      * encoding: set by lavc.
      * decoding: unused
      */
     int delay;
-
-    /**
-     * mbskip_table[mb]=1 if MB didnt change, is only valid for I/P frames 
-     * stride= mb_width = (width+15)>>4 (FIXME export stride?)
-     * encoding: unused
-     * decoding: set by lavc
-     */
-    uint8_t *mbskip_table;
     
     /* encoding parameters */
-    /**
-     * quality (between 1 (good) and 31 (bad)) 
-     * encoding: set by user if CODEC_FLAG_QSCALE is set otherwise set by lavc
-     * decoding: set by lavc
-     */
-    int quality;      /* quality of the previous encoded frame 
-                         
-                         this is allso used to set the quality in vbr mode
-                         and the per frame quality in CODEC_FLAG_TYPE (second pass mode) */
     float qcompress;  /* amount of qscale change between easy & hard scenes (0.0-1.0)*/
     float qblur;      /* amount of qscale smoothing over time (0.0-1.0) */
     
@@ -485,46 +556,21 @@
     int error_resilience;
     
     /**
-     * obsolete, just here to keep ABI compatible (should be removed perhaps, dunno)
+     * called at the beginning of each frame to get a buffer for it.
+     * if pic.reference is set then the frame will be read later by lavc
+     * encoding: unused
+     * decoding: set by lavc, user can override
      */
-    int *quant_store;
-
-    /**
-     * QP store stride
-     * encoding: unused
-     * decoding: set by lavc
-     */
-    int qstride;
+    int (*get_buffer)(struct AVCodecContext *c, AVVideoFrame *pic);
     
     /**
-     * buffer, where the next picture should be decoded into
+     * called to release buffers which where allocated with get_buffer.
+     * a released buffer can be reused in get_buffer()
+     * pic.data[*] must be set to NULL
      * encoding: unused
-     * decoding: set by user in get_buffer_callback to a buffer into which the next part
-     *           of the bitstream will be decoded, and set by lavc at end of frame to the
-     *           next frame which needs to be displayed
-     */
-    uint8_t *dr_buffer[3];
-    
-    /**
-     * stride of the luminance part of the dr buffer
-     * encoding: unused
-     * decoding: set by user
+     * decoding: set by lavc, user can override
      */
-    int dr_stride;
-    
-    /**
-     * same behavior as dr_buffer, just for some private data of the user
-     * encoding: unused
-     * decoding: set by user in get_buffer_callback, and set by lavc at end of frame
-     */
-    void *dr_opaque_frame;
-    
-    /**
-     * called at the beginning of each frame to get a buffer for it
-     * encoding: unused
-     * decoding: set by user
-     */
-    int (*get_buffer_callback)(struct AVCodecContext *c, int width, int height, int pict_type);
+    void (*release_buffer)(struct AVCodecContext *c, AVVideoFrame *pic);
 
     /**
      * is 1 if the decoded stream contains b frames, 0 otherwise
@@ -532,20 +578,6 @@
      * decoding: set by lavc
      */
     int has_b_frames;
-
-    /**
-     * stride of the chrominance part of the dr buffer
-     * encoding: unused
-     * decoding: set by user
-     */
-    int dr_uvstride;
-    
-    /**
-     * number of dr buffers
-     * encoding: unused
-     * decoding: set by user
-     */
-    int dr_ip_buffer_count;
     
     int block_align; /* used by some WAV based audio codecs */
     
@@ -647,12 +679,6 @@
     float rc_initial_cplx;
 
     /**
-     * Obsolete, will be removed
-     */
-    int aspected_width;
-    int aspected_height;
-
-    /**
      * dct algorithm, see FF_DCT_* below
      * encoding: set by user
      * decoding: unused
@@ -664,14 +690,6 @@
 #define FF_DCT_MMX     3
 #define FF_DCT_MLIB    4
 #define FF_DCT_ALTIVEC 5
-
-    /**
-     * presentation timestamp in micro seconds (time when frame should be shown to user)
-     * if 0 then the frame_rate will be used as reference
-     * encoding: set by user
-     * decoding; set by lavc
-     */
-    long long int pts;
     
     /**
      * luminance masking (0-> disabled)
@@ -755,24 +773,6 @@
 #define FF_EC_DEBLOCK     2
 
     /**
-     * QP table of the currently decoded frame
-     * encoding; unused
-     * decoding: set by lavc
-     */
-    int8_t *current_qscale_table;
-    /**
-     * QP table of the currently displayed frame
-     * encoding; unused
-     * decoding: set by lavc
-     */
-    int8_t *display_qscale_table;
-    /**
-     * force specific pict_type.
-     * encoding; set by user (I/P/B_TYPE)
-     * decoding: unused
-     */
-    int force_type;
-    /**
      * dsp_mask could be used to disable unwanted
      * CPU features (i.e. MMX, SSE. ...)
      */
@@ -780,14 +780,14 @@
 
     /**
      * bits per sample/pixel from the demuxer (needed for huffyuv)
-     * encoding; set by lavc
+     * encoding: set by lavc
      * decoding: set by user
      */
      int bits_per_sample;
     
     /**
      * prediction method (needed for huffyuv)
-     * encoding; set by user
+     * encoding: set by user
      * decoding: unused
      */
      int prediction_method;
@@ -801,6 +801,13 @@
      * decoding: set by lavc.
      */
     float aspect_ratio;
+
+    /**
+     * the picture in the bitstream
+     * encoding: set by lavc
+     * decoding: set by lavc
+     */
+    AVVideoFrame *coded_picture;
 } AVCodecContext;
 
 typedef struct AVCodec {
@@ -928,6 +935,7 @@
 void avpicture_fill(AVPicture *picture, UINT8 *ptr,
                     int pix_fmt, int width, int height);
 int avpicture_get_size(int pix_fmt, int width, int height);
+void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift);
 
 /* convert among pixel formats */
 int img_convert(AVPicture *dst, int dst_pix_fmt,
@@ -957,12 +965,18 @@
 AVCodec *avcodec_find_decoder_by_name(const char *name);
 void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
 
+void avcodec_get_context_defaults(AVCodecContext *s);
 AVCodecContext *avcodec_alloc_context(void);
+AVVideoFrame *avcodec_alloc_picture(void);
+
+int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic);
+void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic);
+
 int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
 int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples, 
                          int *frame_size_ptr,
                          UINT8 *buf, int buf_size);
-int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, 
+int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture, 
                          int *got_picture_ptr,
                          UINT8 *buf, int buf_size);
 int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata, 
@@ -971,7 +985,7 @@
 int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, 
                          const short *samples);
 int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, 
-                         const AVPicture *pict);
+                         const AVVideoFrame *pict);
 
 int avcodec_close(AVCodecContext *avctx);
 
--- a/dv.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/dv.c	Wed Dec 04 10:04:03 2002 +0000
@@ -33,6 +33,7 @@
     int sampling_411; /* 0 = 420, 1 = 411 */
     int width, height;
     UINT8 *current_picture[3]; /* picture structure */
+    AVVideoFrame picture;
     int linesize[3];
     DCTELEM block[5*6][64] __align8;
     UINT8 dv_zigzag[2][64];
@@ -128,7 +129,7 @@
 
     /* XXX: do it only for constant case */
     dv_build_unquantize_tables(s);
-
+    
     return 0;
 }
 
@@ -499,7 +500,6 @@
     unsigned size;
     UINT8 *buf_ptr;
     const UINT16 *mb_pos_ptr;
-    AVPicture *picture;
     
     /* parse id */
     init_get_bits(&s->gb, buf, buf_size);
@@ -561,45 +561,20 @@
     avctx->width = width;
     avctx->height = height;
 
-    if (avctx->flags & CODEC_FLAG_DR1)
-    {
-	s->width = -1;
-	avctx->dr_buffer[0] = avctx->dr_buffer[1] = avctx->dr_buffer[2] = 0;
-	if(avctx->get_buffer_callback(avctx, width, height, I_TYPE) < 0
-	   && avctx->flags & CODEC_FLAG_DR1) {
-	    fprintf(stderr, "get_buffer() failed\n");
-	    return -1;
-	}
+    s->picture.reference= 0;
+    if(avctx->get_buffer(avctx, &s->picture) < 0) {
+        fprintf(stderr, "get_buffer() failed\n");
+        return -1;
     }
 
-    /* (re)alloc picture if needed */
-    if (s->width != width || s->height != height) {
-	if (!(avctx->flags & CODEC_FLAG_DR1))
-	    for(i=0;i<3;i++) {
-		if (avctx->dr_buffer[i] != s->current_picture[i])
-		    av_freep(&s->current_picture[i]);
-		avctx->dr_buffer[i] = 0;
-	    }
-
-        for(i=0;i<3;i++) {
-	    if (avctx->dr_buffer[i]) {
-		s->current_picture[i] = avctx->dr_buffer[i];
-		s->linesize[i] = (i == 0) ? avctx->dr_stride : avctx->dr_uvstride;
-	    } else {
-		size = width * height;
-		s->linesize[i] = width;
-		if (i >= 1) {
-		    size >>= 2;
-		    s->linesize[i] >>= s->sampling_411 ? 2 : 1;
-		}
-		s->current_picture[i] = av_malloc(size);
-	    }
-            if (!s->current_picture[i])
-                return -1;
-        }
-        s->width = width;
-        s->height = height;
+    for(i=0;i<3;i++) {
+        s->current_picture[i] = s->picture.data[i];
+        s->linesize[i] = s->picture.linesize[i];
+        if (!s->current_picture[i])
+            return -1;
     }
+    s->width = width;
+    s->height = height;
 
     /* for each DIF segment */
     buf_ptr = buf;
@@ -620,12 +595,11 @@
     emms_c();
 
     /* return image */
-    *data_size = sizeof(AVPicture);
-    picture = data;
-    for(i=0;i<3;i++) {
-        picture->data[i] = s->current_picture[i];
-        picture->linesize[i] = s->linesize[i];
-    }
+    *data_size = sizeof(AVVideoFrame);
+    *(AVVideoFrame*)data= s->picture;
+    
+    avctx->release_buffer(avctx, &s->picture);
+    
     return packet_size;
 }
 
@@ -633,10 +607,15 @@
 {
     DVVideoDecodeContext *s = avctx->priv_data;
     int i;
+    
+    if(avctx->get_buffer == avcodec_default_get_buffer){
+        for(i=0; i<4; i++){
+            av_freep(&s->picture.base[i]);
+            s->picture.data[i]= NULL;
+        }
+        av_freep(&s->picture.opaque);
+    }
 
-    for(i=0;i<3;i++)
-	if (avctx->dr_buffer[i] != s->current_picture[i])
-        av_freep(&s->current_picture[i]);
     return 0;
 }
 
--- a/error_resilience.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/error_resilience.c	Wed Dec 04 10:04:03 2002 +0000
@@ -464,7 +464,7 @@
                     s->mb_y= mb_y;
                     for(j=0; j<pred_count; j++){
                         int score=0;
-                        UINT8 *src= s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize;
+                        UINT8 *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
 
                         s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
                         s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
@@ -556,8 +556,8 @@
             if((j%skip_amount) != 0) continue; //skip a few to speed things up
     
             if(s->pict_type==I_TYPE){
-                UINT8 *mb_ptr     = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize;
-                UINT8 *last_mb_ptr= s->last_picture   [0] + mb_x*16 + mb_y*16*s->linesize;
+                UINT8 *mb_ptr     = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
+                UINT8 *last_mb_ptr= s->last_picture.data   [0] + mb_x*16 + mb_y*16*s->linesize;
     
 		is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr                    , s->linesize);
                 is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize);
@@ -802,9 +802,9 @@
             if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
 //            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
             
-            dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize;
-            dest_cb= s->current_picture[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
-            dest_cr= s->current_picture[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
+            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
+            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
+            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
            
             dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)];
             for(n=0; n<4; n++){
@@ -852,9 +852,9 @@
             if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter
             if(!(error&AC_ERROR)) continue;              //undamaged
             
-            dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize;
-            dest_cb= s->current_picture[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
-            dest_cr= s->current_picture[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
+            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
+            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
+            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
             
             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
         }
@@ -863,14 +863,14 @@
     
     if(s->avctx->error_concealment&FF_EC_DEBLOCK){
         /* filter horizontal block boundaries */
-        h_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
-        h_block_filter(s, s->current_picture[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
-        h_block_filter(s, s->current_picture[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
+        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
+        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
+        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
 
         /* filter vertical block boundaries */
-        v_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
-        v_block_filter(s, s->current_picture[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
-        v_block_filter(s, s->current_picture[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
+        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
+        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
+        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
     }
 
     /* clean a few tables */
--- a/h263.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/h263.c	Wed Dec 04 10:04:03 2002 +0000
@@ -272,6 +272,7 @@
 {
     int score0=0, score1=0;
     int i, n;
+    int8_t * const qscale_table= s->current_picture.qscale_table;
 
     for(n=0; n<6; n++){
         INT16 *ac_val, *ac_val1;
@@ -282,7 +283,7 @@
             const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width;
             /* top prediction */
             ac_val-= s->block_wrap[n]*16;
-            if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){
+            if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
                 /* same qscale */
                 for(i=1; i<8; i++){
                     const int level= block[n][s->idct_permutation[i   ]];
@@ -296,7 +297,7 @@
                 for(i=1; i<8; i++){
                     const int level= block[n][s->idct_permutation[i   ]];
                     score0+= ABS(level);
-                    score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale));
+                    score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale));
                     ac_val1[i  ]=    block[n][s->idct_permutation[i<<3]];
                     ac_val1[i+8]= level;
                 }
@@ -305,7 +306,7 @@
             const int xy= s->mb_x-1 + s->mb_y*s->mb_width;
             /* left prediction */
             ac_val-= 16;
-            if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){
+            if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
                 /* same qscale */
                 for(i=1; i<8; i++){
                     const int level= block[n][s->idct_permutation[i<<3]];
@@ -319,7 +320,7 @@
                 for(i=1; i<8; i++){
                     const int level= block[n][s->idct_permutation[i<<3]];
                     score0+= ABS(level);
-                    score1+= ABS(level - ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale));
+                    score1+= ABS(level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale));
                     ac_val1[i  ]= level;
                     ac_val1[i+8]=    block[n][s->idct_permutation[i   ]];
                 }
@@ -335,14 +336,15 @@
  */
 void ff_clean_h263_qscales(MpegEncContext *s){
     int i;
+    int8_t * const qscale_table= s->current_picture.qscale_table;
     
     for(i=1; i<s->mb_num; i++){
-        if(s->qscale_table[i] - s->qscale_table[i-1] >2)
-            s->qscale_table[i]= s->qscale_table[i-1]+2;
+        if(qscale_table[i] - qscale_table[i-1] >2)
+            qscale_table[i]= qscale_table[i-1]+2;
     }
     for(i=s->mb_num-2; i>=0; i--){
-        if(s->qscale_table[i] - s->qscale_table[i+1] >2)
-            s->qscale_table[i]= s->qscale_table[i+1]+2;
+        if(qscale_table[i] - qscale_table[i+1] >2)
+            qscale_table[i]= qscale_table[i+1]+2;
     }
 }
 
@@ -351,11 +353,12 @@
  */
 void ff_clean_mpeg4_qscales(MpegEncContext *s){
     int i;
-    
+    int8_t * const qscale_table= s->current_picture.qscale_table;
+
     ff_clean_h263_qscales(s);
     
     for(i=1; i<s->mb_num; i++){
-        if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){
+        if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){
             s->mb_type[i]&= ~MB_TYPE_INTER4V;
             s->mb_type[i]|= MB_TYPE_INTER;
         }
@@ -367,21 +370,21 @@
            for the actual adaptive quantization */
         
         for(i=0; i<s->mb_num; i++){
-            odd += s->qscale_table[i]&1;
+            odd += qscale_table[i]&1;
         }
         
         if(2*odd > s->mb_num) odd=1;
         else                  odd=0;
         
         for(i=0; i<s->mb_num; i++){
-            if((s->qscale_table[i]&1) != odd)
-                s->qscale_table[i]++;
-            if(s->qscale_table[i] > 31)
-                s->qscale_table[i]= 31;
+            if((qscale_table[i]&1) != odd)
+                qscale_table[i]++;
+            if(qscale_table[i] > 31)
+                qscale_table[i]= 31;
         }            
     
         for(i=1; i<s->mb_num; i++){
-            if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){
+            if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){
                 s->mb_type[i]&= ~MB_TYPE_DIRECT;
                 s->mb_type[i]|= MB_TYPE_BIDIR;
             }
@@ -427,7 +430,7 @@
             assert(mb_type>=0);
 
             /* nothing to do if this MB was skiped in the next P Frame */
-            if(s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ...
+            if(s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ...
                 s->skip_count++;
                 s->mv[0][0][0]= 
                 s->mv[0][0][1]= 
@@ -435,6 +438,8 @@
                 s->mv[1][0][1]= 0;
                 s->mv_dir= MV_DIR_FORWARD; //doesnt matter
                 s->qscale -= s->dquant;
+//                s->mb_skiped=1;
+
                 return;
             }
 
@@ -451,6 +456,7 @@
                 s->skip_count++;
                 return;
             }
+            
             put_bits(&s->pb, 1, 0);	/* mb coded modb1=0 */
             put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge
             put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we dont need it :)
@@ -547,16 +553,17 @@
                     if(y+16 > s->height) y= s->height-16;
 
                     offset= x + y*s->linesize;
-                    p_pic= s->new_picture[0] + offset;
+                    p_pic= s->new_picture.data[0] + offset;
                     
                     s->mb_skiped=1;
                     for(i=0; i<s->max_b_frames; i++){
                         uint8_t *b_pic;
                         int diff;
-
-                        if(s->coded_order[i+1].pict_type!=B_TYPE) break;
-
-                        b_pic= s->coded_order[i+1].picture[0] + offset;
+                        Picture *pic= s->reordered_input_picture[i+1];
+
+                        if(pic==NULL || pic->pict_type!=B_TYPE) break;
+
+                        b_pic= pic->data[0] + offset + 16; //FIXME +16
 			diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize);
                         if(diff>s->qscale*70){ //FIXME check that 70 is optimal
                             s->mb_skiped=0;
@@ -1493,8 +1500,8 @@
         s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
     }
     
-    if(s->avctx->pts)
-        s->time= (s->avctx->pts*s->time_increment_resolution + 500*1000)/(1000*1000);
+    if(s->current_picture.pts)
+        s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000);
     else
         s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
     time_div= s->time/s->time_increment_resolution;
@@ -1736,6 +1743,7 @@
 {
     int i;
     INT16 *ac_val, *ac_val1;
+    int8_t * const qscale_table= s->current_picture.qscale_table;
 
     /* find prediction */
     ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@@ -1746,7 +1754,7 @@
             /* left prediction */
             ac_val -= 16;
             
-            if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){
+            if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
                 /* same qscale */
                 for(i=1;i<8;i++) {
                     block[s->idct_permutation[i<<3]] += ac_val[i];
@@ -1754,7 +1762,7 @@
             }else{
                 /* different qscale, we must rescale */
                 for(i=1;i<8;i++) {
-                    block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale);
+                    block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
                 }
             }
         } else {
@@ -1762,7 +1770,7 @@
             /* top prediction */
             ac_val -= 16 * s->block_wrap[n];
 
-            if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){
+            if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
                 /* same qscale */
                 for(i=1;i<8;i++) {
                     block[s->idct_permutation[i]] += ac_val[i + 8];
@@ -1770,7 +1778,7 @@
             }else{
                 /* different qscale, we must rescale */
                 for(i=1;i<8;i++) {
-                    block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale);
+                    block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
                 }
             }
         }
@@ -1790,6 +1798,7 @@
 {
     int i;
     INT16 *ac_val;
+    int8_t * const qscale_table= s->current_picture.qscale_table;
 
     /* find prediction */
     ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@@ -1798,7 +1807,7 @@
         const int xy= s->mb_x-1 + s->mb_y*s->mb_width;
         /* left prediction */
         ac_val -= 16;
-        if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){
+        if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
             /* same qscale */
             for(i=1;i<8;i++) {
                 block[s->idct_permutation[i<<3]] -= ac_val[i];
@@ -1806,14 +1815,14 @@
         }else{
             /* different qscale, we must rescale */
             for(i=1;i<8;i++) {
-                block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale);
+                block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
             }
         }
     } else {
         const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width;
         /* top prediction */
         ac_val -= 16 * s->block_wrap[n];
-        if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){
+        if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
             /* same qscale */
             for(i=1;i<8;i++) {
                 block[s->idct_permutation[i]] -= ac_val[i + 8];
@@ -1821,7 +1830,7 @@
         }else{
             /* different qscale, we must rescale */
             for(i=1;i<8;i++) {
-                block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale);
+                block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
             }
         }
     }
@@ -2532,7 +2541,7 @@
                 if(cbpc & 4) {
                     change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
                 }
-                s->qscale_table[xy]= s->qscale;
+                s->current_picture.qscale_table[xy]= s->qscale;
 
                 s->mbintra_table[xy]= 1;
                 for(i=0; i<6; i++){
@@ -2704,7 +2713,7 @@
                     if(s->cbp_table[xy] & 8) {
                         change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
                     }
-                    s->qscale_table[xy]= s->qscale;
+                    s->current_picture.qscale_table[xy]= s->qscale;
 
                     for(i=0; i<6; i++){
                         int dc_pred_dir;
@@ -2721,7 +2730,7 @@
                     s->pred_dir_table[xy]= dir | (ac_pred<<7);
                     s->error_status_table[xy]&= ~DC_ERROR;
                 }else if(s->mb_type[xy]&MB_TYPE_SKIPED){
-                    s->qscale_table[xy]= s->qscale;
+                    s->current_picture.qscale_table[xy]= s->qscale;
                     s->cbp_table[xy]= 0;
                 }else{
                     int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
@@ -2734,7 +2743,7 @@
                     if(s->cbp_table[xy] & 8) {
                         change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
                     }
-                    s->qscale_table[xy]= s->qscale;
+                    s->current_picture.qscale_table[xy]= s->qscale;
 
                     s->cbp_table[xy]&= 3; //remove dquant
                     s->cbp_table[xy]|= (cbpy^0xf)<<2;
@@ -2801,8 +2810,8 @@
     mb_type= s->mb_type[xy];
     cbp = s->cbp_table[xy];
 
-    if(s->qscale_table[xy] != s->qscale){
-        s->qscale= s->qscale_table[xy];
+    if(s->current_picture.qscale_table[xy] != s->qscale){
+        s->qscale= s->current_picture.qscale_table[xy];
         s->y_dc_scale= s->y_dc_scale_table[ s->qscale ];
         s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];
     }
@@ -3054,7 +3063,7 @@
         }
 
         /* if we skipped it in the future P Frame than skip it now too */
-        s->mb_skiped= s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC
+        s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC
 
         if(s->mb_skiped){
                 /* skip mb */
@@ -3287,7 +3296,7 @@
         /* per-MB end of slice check */
     if(s->codec_id==CODEC_ID_MPEG4){
         if(mpeg4_is_resync(s)){
-            if(s->pict_type==B_TYPE && s->mbskip_table[s->mb_y * s->mb_width + s->mb_x+1])
+            if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x+1])
                 return SLICE_OK;
             return SLICE_END;
         }
@@ -4441,7 +4450,7 @@
                            - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
     }
     
-    s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution;
+    s->current_picture.pts= s->time*1000LL*1000LL / s->time_increment_resolution;
     
     if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){
         printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n");
--- a/h263dec.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/h263dec.c	Wed Dec 04 10:04:03 2002 +0000
@@ -199,6 +199,7 @@
             
             s->mv_dir = MV_DIR_FORWARD;
             s->mv_type = MV_TYPE_16X16;
+//            s->mb_skiped = 0;
 //printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));
             ret= s->decode_mb(s, s->block);
             
@@ -347,7 +348,7 @@
 {
     MpegEncContext *s = avctx->priv_data;
     int ret,i;
-    AVPicture *pict = data; 
+    AVVideoFrame *pict = data; 
     float new_aspect;
     
 #ifdef PRINT_FRAME_TIME
@@ -357,7 +358,6 @@
     printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
     printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
 #endif
-
     s->flags= avctx->flags;
 
     *data_size = 0;
@@ -523,8 +523,9 @@
         return -1;
     }
     
-    s->avctx->key_frame   = (s->pict_type == I_TYPE);
-    s->avctx->pict_type   = s->pict_type;
+    // for hurry_up==5
+    s->current_picture.pict_type= s->pict_type;
+    s->current_picture.key_frame= s->pict_type == I_TYPE;
 
     /* skip b frames if we dont have reference frames */
     if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
@@ -580,7 +581,9 @@
     }
 
     if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)
-        if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
+        if(msmpeg4_decode_ext_header(s, buf_size) < 0){
+            s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR;
+        }
     
     /* divx 5.01+ bistream reorder stuff */
     if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){
@@ -644,7 +647,7 @@
     int y= mb_y*16 + 8;
     for(mb_x=0; mb_x<s->mb_width; mb_x++){
       int x= mb_x*16 + 8;
-      uint8_t *ptr= s->last_picture[0];
+      uint8_t *ptr= s->last_picture.data[0];
       int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2);
       int mx= (s->motion_val[xy][0]>>1) + x;
       int my= (s->motion_val[xy][1]>>1) + y;
@@ -669,21 +672,12 @@
   }
 
 }
-#endif    
+#endif
     if(s->pict_type==B_TYPE || (!s->has_b_frames)){
-        pict->data[0] = s->current_picture[0];
-        pict->data[1] = s->current_picture[1];
-        pict->data[2] = s->current_picture[2];
+        *pict= *(AVVideoFrame*)&s->current_picture;
     } else {
-        pict->data[0] = s->last_picture[0];
-        pict->data[1] = s->last_picture[1];
-        pict->data[2] = s->last_picture[2];
+        *pict= *(AVVideoFrame*)&s->last_picture;
     }
-    pict->linesize[0] = s->linesize;
-    pict->linesize[1] = s->uvlinesize;
-    pict->linesize[2] = s->uvlinesize;
-
-    avctx->quality = s->qscale;
 
     /* Return the Picture timestamp as the frame number */
     /* we substract 1 because it is added on utils.c    */
@@ -692,7 +686,7 @@
     /* dont output the last pic after seeking 
        note we allready added +1 for the current pix in MPV_frame_end(s) */
     if(s->num_available_buffers>=2 || (!s->has_b_frames))
-        *data_size = sizeof(AVPicture);
+        *data_size = sizeof(AVVideoFrame);
 #ifdef PRINT_FRAME_TIME
 printf("%Ld\n", rdtsc()-time);
 #endif
--- a/huffyuv.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/huffyuv.c	Wed Dec 04 10:04:03 2002 +0000
@@ -30,7 +30,7 @@
 #endif
 
 #define VLC_BITS 11
-  
+
 typedef enum Predictor{
     LEFT= 0,
     PLANE,
@@ -52,13 +52,12 @@
     int flags;
     int picture_number;
     int last_slice_end;
-    int linesize[3];
     uint8_t __align8 temp[3][2500];
     uint64_t stats[3][256];
     uint8_t len[3][256];
     uint32_t bits[3][256];
     VLC vlc[3];
-    uint8_t __align8 *picture[3];
+    AVVideoFrame picture;
     uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
     DSPContext dsp; 
 }HYuvContext;
@@ -324,7 +323,7 @@
 static int decode_init(AVCodecContext *avctx)
 {
     HYuvContext *s = avctx->priv_data;
-    int width, height, y_size, c_size, stride;
+    int width, height;
 
     s->avctx= avctx;
     s->flags= avctx->flags;
@@ -333,6 +332,8 @@
     
     width= s->width= avctx->width;
     height= s->height= avctx->height;
+    avctx->coded_picture= &s->picture;
+
 s->bgr32=1;
     assert(width && height);
 //if(avctx->extradata)
@@ -388,52 +389,27 @@
     
     s->interlaced= height > 288;
     
-    c_size= 0;
     switch(s->bitstream_bpp){
     case 12:
         avctx->pix_fmt = PIX_FMT_YUV420P;
-        stride= (width+15)&~15;
-        c_size= height*stride/4;
         break;
     case 16:
         if(s->yuy2){
             avctx->pix_fmt = PIX_FMT_YUV422;
-            stride= (width*2+15)&~15;
         }else{
             avctx->pix_fmt = PIX_FMT_YUV422P;
-            stride= (width+15)&~15;
-            c_size= height*stride/2;
         }
         break;
     case 24:
     case 32:
         if(s->bgr32){
             avctx->pix_fmt = PIX_FMT_BGRA32;
-            stride= (width*4+15)&~15;
         }else{
             avctx->pix_fmt = PIX_FMT_BGR24;
-            stride= (width*3+15)&~15;
         }
         break;
     default:
         assert(0);
-        stride=0; //gcc fix
-    }
-    
-    y_size= height*stride;
-    
-    if(!(avctx->flags&CODEC_FLAG_DR1)){
-        s->linesize[0]= stride;
-        s->picture[0]= av_mallocz(y_size);
- 
-        if(c_size){
-            s->picture[1]= av_mallocz(c_size);
-            s->picture[2]= av_mallocz(c_size);
-            s->linesize[1]= s->linesize[2]= stride/2;
-        
-            memset(s->picture[1], 128, c_size);
-            memset(s->picture[2], 128, c_size);
-        }
     }
     
 //    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
@@ -484,6 +460,10 @@
     avctx->stats_out= av_mallocz(1024*10);
     s->version=2;
     
+    avctx->coded_picture= &s->picture;
+    s->picture.pict_type= I_TYPE;
+    s->picture.key_frame= 1;
+    
     switch(avctx->pix_fmt){
     case PIX_FMT_YUV420P:
         if(avctx->strict_std_compliance>=0){
@@ -674,12 +654,12 @@
         cy= y;
     }
     
-    src_ptr[0] = s->picture[0] + s->linesize[0]*y;
-    src_ptr[1] = s->picture[1] + s->linesize[1]*cy;
-    src_ptr[2] = s->picture[2] + s->linesize[2]*cy;
+    src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
+    src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
+    src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
     emms_c();
 
-    s->avctx->draw_horiz_band(s->avctx, src_ptr, s->linesize[0], y, s->width, h);
+    s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
     
     s->last_slice_end= y + h;
 }
@@ -690,9 +670,9 @@
     const int width2= s->width>>1;
     const int height= s->height;
     int fake_ystride, fake_ustride, fake_vstride;
-    int i;
+    AVVideoFrame * const p= &s->picture;
 
-    AVPicture *picture = data;
+    AVVideoFrame *picture = data;
 
     *data_size = 0;
 
@@ -704,22 +684,15 @@
     
     init_get_bits(&s->gb, s->bitstream_buffer, buf_size);
 
-    if(avctx->flags&CODEC_FLAG_DR1){
-        if(avctx->get_buffer_callback(avctx, s->width, s->height, I_TYPE) < 0){
-            fprintf(stderr, "get_buffer() failed\n");
-            return -1;
-        }
+    p->reference= 0;
+    if(avctx->get_buffer(avctx, p) < 0){
+        fprintf(stderr, "get_buffer() failed\n");
+        return -1;
+    }
 
-        s->linesize[0]= avctx->dr_stride;
-        s->linesize[1]=
-        s->linesize[2]= avctx->dr_uvstride;
-
-        for(i=0; i<3;i++)
-            s->picture[i]= avctx->dr_buffer[i];
-    }
-    fake_ystride= s->interlaced ? s->linesize[0]*2  : s->linesize[0];
-    fake_ustride= s->interlaced ? s->linesize[1]*2  : s->linesize[1];
-    fake_vstride= s->interlaced ? s->linesize[2]*2  : s->linesize[2];
+    fake_ystride= s->interlaced ? p->linesize[0]*2  : p->linesize[0];
+    fake_ustride= s->interlaced ? p->linesize[1]*2  : p->linesize[1];
+    fake_vstride= s->interlaced ? p->linesize[2]*2  : p->linesize[2];
     
     s->last_slice_end= 0;
         
@@ -729,28 +702,28 @@
         int lefttopy, lefttopu, lefttopv;
         
         if(s->yuy2){
-            s->picture[0][3]= get_bits(&s->gb, 8);
-            s->picture[0][2]= get_bits(&s->gb, 8);
-            s->picture[0][1]= get_bits(&s->gb, 8);
-            s->picture[0][0]= get_bits(&s->gb, 8);
+            p->data[0][3]= get_bits(&s->gb, 8);
+            p->data[0][2]= get_bits(&s->gb, 8);
+            p->data[0][1]= get_bits(&s->gb, 8);
+            p->data[0][0]= get_bits(&s->gb, 8);
             
             fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
             return -1;
         }else{
         
-            leftv= s->picture[2][0]= get_bits(&s->gb, 8);
-            lefty= s->picture[0][1]= get_bits(&s->gb, 8);
-            leftu= s->picture[1][0]= get_bits(&s->gb, 8);
-                   s->picture[0][0]= get_bits(&s->gb, 8);
+            leftv= p->data[2][0]= get_bits(&s->gb, 8);
+            lefty= p->data[0][1]= get_bits(&s->gb, 8);
+            leftu= p->data[1][0]= get_bits(&s->gb, 8);
+                   p->data[0][0]= get_bits(&s->gb, 8);
         
             switch(s->predictor){
             case LEFT:
             case PLANE:
                 decode_422_bitstream(s, width-2);
-                lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty);
+                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
                 if(!(s->flags&CODEC_FLAG_GRAY)){
-                    leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu);
-                    leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv);
+                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
+                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
                 }
 
                 for(cy=y=1; y<s->height; y++,cy++){
@@ -759,7 +732,7 @@
                     if(s->bitstream_bpp==12){
                         decode_gray_bitstream(s, width);
                     
-                        ydst= s->picture[0] + s->linesize[0]*y;
+                        ydst= p->data[0] + p->linesize[0]*y;
 
                         lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
                         if(s->predictor == PLANE){
@@ -772,12 +745,11 @@
                     
                     draw_slice(s, y);
                     
-                    ydst= s->picture[0] + s->linesize[0]*y;
-                    udst= s->picture[1] + s->linesize[1]*cy;
-                    vdst= s->picture[2] + s->linesize[2]*cy;
+                    ydst= p->data[0] + p->linesize[0]*y;
+                    udst= p->data[1] + p->linesize[1]*cy;
+                    vdst= p->data[2] + p->linesize[2]*cy;
                     
                     decode_422_bitstream(s, width);
-
                     lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
                     if(!(s->flags&CODEC_FLAG_GRAY)){
                         leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
@@ -799,10 +771,10 @@
             case MEDIAN:
                 /* first line except first 2 pixels is left predicted */
                 decode_422_bitstream(s, width-2);
-                lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty);
+                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
                 if(!(s->flags&CODEC_FLAG_GRAY)){
-                    leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu);
-                    leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv);
+                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
+                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
                 }
                 
                 cy=y=1;
@@ -810,31 +782,31 @@
                 /* second line is left predicted for interlaced case */
                 if(s->interlaced){
                     decode_422_bitstream(s, width);
-                    lefty= add_left_prediction(s->picture[0] + s->linesize[0], s->temp[0], width, lefty);
+                    lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
                     if(!(s->flags&CODEC_FLAG_GRAY)){
-                        leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu);
-                        leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv);
+                        leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
+                        leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
                     }
                     y++; cy++;
                 }
 
                 /* next 4 pixels are left predicted too */
                 decode_422_bitstream(s, 4);
-                lefty= add_left_prediction(s->picture[0] + fake_ystride, s->temp[0], 4, lefty);
+                lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
                 if(!(s->flags&CODEC_FLAG_GRAY)){
-                    leftu= add_left_prediction(s->picture[1] + fake_ustride, s->temp[1], 2, leftu);
-                    leftv= add_left_prediction(s->picture[2] + fake_vstride, s->temp[2], 2, leftv);
+                    leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
+                    leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
                 }
 
                 /* next line except the first 4 pixels is median predicted */
-                lefttopy= s->picture[0][3];
+                lefttopy= p->data[0][3];
                 decode_422_bitstream(s, width-4);
-                add_median_prediction(s->picture[0] + fake_ystride+4, s->picture[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
+                add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
                 if(!(s->flags&CODEC_FLAG_GRAY)){
-                    lefttopu= s->picture[1][1];
-                    lefttopv= s->picture[2][1];
-                    add_median_prediction(s->picture[1] + fake_ustride+2, s->picture[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
-                    add_median_prediction(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
+                    lefttopu= p->data[1][1];
+                    lefttopv= p->data[2][1];
+                    add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
+                    add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
                 }
                 y++; cy++;
                 
@@ -844,7 +816,7 @@
                     if(s->bitstream_bpp==12){
                         while(2*cy > y){
                             decode_gray_bitstream(s, width);
-                            ydst= s->picture[0] + s->linesize[0]*y;
+                            ydst= p->data[0] + p->linesize[0]*y;
                             add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
                             y++;
                         }
@@ -854,9 +826,9 @@
 
                     decode_422_bitstream(s, width);
 
-                    ydst= s->picture[0] + s->linesize[0]*y;
-                    udst= s->picture[1] + s->linesize[1]*cy;
-                    vdst= s->picture[2] + s->linesize[2]*cy;
+                    ydst= p->data[0] + p->linesize[0]*y;
+                    udst= p->data[1] + p->linesize[1]*cy;
+                    vdst= p->data[2] + p->linesize[2]*cy;
 
                     add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
                     if(!(s->flags&CODEC_FLAG_GRAY)){
@@ -872,17 +844,17 @@
     }else{
         int y;
         int leftr, leftg, leftb;
-        const int last_line= (height-1)*s->linesize[0];
+        const int last_line= (height-1)*p->linesize[0];
         
         if(s->bitstream_bpp==32){
-                   s->picture[0][last_line+3]= get_bits(&s->gb, 8);
-            leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8);
-            leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8);
-            leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8);
+                   p->data[0][last_line+3]= get_bits(&s->gb, 8);
+            leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
+            leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
+            leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
         }else{
-            leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8);
-            leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8);
-            leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8);
+            leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
+            leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
+            leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
             skip_bits(&s->gb, 8);
         }
         
@@ -891,16 +863,16 @@
             case LEFT:
             case PLANE:
                 decode_bgr_bitstream(s, width-1);
-                add_left_prediction_bgr32(s->picture[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
+                add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
 
                 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
                     decode_bgr_bitstream(s, width);
                     
-                    add_left_prediction_bgr32(s->picture[0] + s->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
+                    add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
                     if(s->predictor == PLANE){
                         if((y&s->interlaced)==0){
-                            s->dsp.add_bytes(s->picture[0] + s->linesize[0]*y, 
-                                             s->picture[0] + s->linesize[0]*y + fake_ystride, fake_ystride);
+                            s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, 
+                                             p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
                         }
                     }
                 }
@@ -917,12 +889,11 @@
     }
     emms_c();
     
-    for(i=0;i<3;i++) {
-        picture->data[i] = s->picture[i];
-        picture->linesize[i]= s->linesize[i];
-    }
+    *picture= *p;
+    
+    avctx->release_buffer(avctx, p);
 
-    *data_size = sizeof(AVPicture);
+    *data_size = sizeof(AVVideoFrame);
     
     return (get_bits_count(&s->gb)+7)>>3;
 }
@@ -933,10 +904,15 @@
     int i;
     
     for(i=0; i<3; i++){
-        if(!(avctx->flags&CODEC_FLAG_DR1))
-            av_freep(&s->picture[i]);
+        free_vlc(&s->vlc[i]);
+    }
 
-        free_vlc(&s->vlc[i]);
+    if(avctx->get_buffer == avcodec_default_get_buffer){
+        for(i=0; i<4; i++){
+            av_freep(&s->picture.base[i]);
+            s->picture.data[i]= NULL;
+        }
+        av_freep(&s->picture.opaque);
     }
 
     return 0;
@@ -944,33 +920,31 @@
 
 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
     HYuvContext *s = avctx->priv_data;
-    AVPicture *pict = data;
+    AVVideoFrame *pict = data;
     const int width= s->width;
     const int width2= s->width>>1;
     const int height= s->height;
     const int fake_ystride= s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
     const int fake_ustride= s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
     const int fake_vstride= s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
+    AVVideoFrame * const p= &s->picture;
     int i, size;
 
     init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
     
-    for(i=0; i<3; i++){
-        s->picture[i]= pict->data[i];
-        s->linesize[i]= pict->linesize[i];
-    }
+    *p = *pict;
     
     if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
         int lefty, leftu, leftv, y, cy;
 
-        put_bits(&s->pb, 8, leftv= s->picture[2][0]);
-        put_bits(&s->pb, 8, lefty= s->picture[0][1]);
-        put_bits(&s->pb, 8, leftu= s->picture[1][0]);
-        put_bits(&s->pb, 8,        s->picture[0][0]);
+        put_bits(&s->pb, 8, leftv= p->data[2][0]);
+        put_bits(&s->pb, 8, lefty= p->data[0][1]);
+        put_bits(&s->pb, 8, leftu= p->data[1][0]);
+        put_bits(&s->pb, 8,        p->data[0][0]);
         
-        lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+2, width-2 , lefty);
-        leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+1, width2-1, leftu);
-        leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+1, width2-1, leftv);
+        lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
+        leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
+        leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
         
         encode_422_bitstream(s, width-2);
         
@@ -978,26 +952,26 @@
             int lefttopy, lefttopu, lefttopv;
             cy=y=1;
             if(s->interlaced){
-                lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+s->linesize[0], width , lefty);
-                leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+s->linesize[1], width2, leftu);
-                leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+s->linesize[2], width2, leftv);
+                lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
+                leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
+                leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
         
                 encode_422_bitstream(s, width);
                 y++; cy++;
             }
             
-            lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+fake_ystride, 4, lefty);
-            leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+fake_ystride, 2, leftu);
-            leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+fake_ystride, 2, leftv);
+            lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
+            leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
+            leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
         
             encode_422_bitstream(s, 4);
 
-            lefttopy= s->picture[0][3];
-            lefttopu= s->picture[1][1];
-            lefttopv= s->picture[2][1];
-            sub_median_prediction(s->temp[0], s->picture[0]+4, s->picture[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
-            sub_median_prediction(s->temp[1], s->picture[1]+2, s->picture[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
-            sub_median_prediction(s->temp[2], s->picture[2]+2, s->picture[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
+            lefttopy= p->data[0][3];
+            lefttopu= p->data[1][1];
+            lefttopv= p->data[2][1];
+            sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
+            sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
+            sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
             encode_422_bitstream(s, width-4);
             y++; cy++;
 
@@ -1006,16 +980,16 @@
                     
                 if(s->bitstream_bpp==12){
                     while(2*cy > y){
-                        ydst= s->picture[0] + s->linesize[0]*y;
+                        ydst= p->data[0] + p->linesize[0]*y;
                         sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
                         encode_gray_bitstream(s, width);
                         y++;
                     }
                     if(y>=height) break;
                 }
-                ydst= s->picture[0] + s->linesize[0]*y;
-                udst= s->picture[1] + s->linesize[1]*cy;
-                vdst= s->picture[2] + s->linesize[2]*cy;
+                ydst= p->data[0] + p->linesize[0]*y;
+                udst= p->data[1] + p->linesize[1]*cy;
+                vdst= p->data[2] + p->linesize[2]*cy;
 
                 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
                 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
@@ -1029,7 +1003,7 @@
                 
                 /* encode a luma only line & y++ */
                 if(s->bitstream_bpp==12){
-                    ydst= s->picture[0] + s->linesize[0]*y;
+                    ydst= p->data[0] + p->linesize[0]*y;
 
                     if(s->predictor == PLANE && s->interlaced < y){
                         s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
@@ -1043,9 +1017,9 @@
                     if(y>=height) break;
                 }
                 
-                ydst= s->picture[0] + s->linesize[0]*y;
-                udst= s->picture[1] + s->linesize[1]*cy;
-                vdst= s->picture[2] + s->linesize[2]*cy;
+                ydst= p->data[0] + p->linesize[0]*y;
+                udst= p->data[1] + p->linesize[1]*cy;
+                vdst= p->data[2] + p->linesize[2]*cy;
 
                 if(s->predictor == PLANE && s->interlaced < cy){
                     s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
@@ -1088,11 +1062,8 @@
         bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
     }
     
-    avctx->key_frame= 1;
-    avctx->pict_type= I_TYPE;
-    
     s->picture_number++;
-    
+
     return size*4;
 }
 
--- a/mjpeg.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/mjpeg.c	Wed Dec 04 10:04:03 2002 +0000
@@ -1180,9 +1180,11 @@
 	    get_bits(&s->gb, 8), get_bits(&s->gb, 8));
 	if (get_bits(&s->gb, 8) == 0)
 	{
-	    s->avctx->aspect_ratio_info = FF_ASPECT_EXTENDED;
-	    s->avctx->aspected_width = get_bits(&s->gb, 16);
-	    s->avctx->aspected_height = get_bits(&s->gb, 16);
+	    int x_density = get_bits(&s->gb, 16);
+	    int y_density = get_bits(&s->gb, 16);
+
+            //MN: needs to be checked
+            s->avctx->aspect_ratio= s->width*y_density/((float)s->height*x_density);
 	}
 	else
 	{
@@ -1468,7 +1470,7 @@
                         }
                         /* dummy quality */
                         /* XXX: infer it with matrix */
-                    	avctx->quality = 3; 
+//                    	avctx->quality = 3; 
                         goto the_end;
                     }
 		    break;
@@ -1635,7 +1637,7 @@
     }
     /* dummy quality */
     /* XXX: infer it with matrix */
-    avctx->quality = 3; 
+//    avctx->quality = 3; 
 
     return buf_ptr - buf;
 }
--- a/motion_est.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/motion_est.c	Wed Dec 04 10:04:03 2002 +0000
@@ -92,7 +92,7 @@
     y2 = yy + range - 1;
     if (y2 > ymax)
 	y2 = ymax;
-    pix = s->new_picture[0] + (yy * s->linesize) + xx;
+    pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
     dmin = 0x7fffffff;
     mx = 0;
     my = 0;
@@ -155,7 +155,7 @@
     if (y2 > ymax)
 	y2 = ymax;
 
-    pix = s->new_picture[0] + (yy * s->linesize) + xx;
+    pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
     dmin = 0x7fffffff;
     mx = 0;
     my = 0;
@@ -231,7 +231,7 @@
     if (y2 > ymax)
 	y2 = ymax;
 
-    pix = s->new_picture[0] + (yy * s->linesize) + xx;
+    pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
     mx = 0;
     my = 0;
 
@@ -560,7 +560,7 @@
     uint16_t *score_map= s->me_score_map;
     int map_generation;
 
-    new_pic = s->new_picture[0] + pic_xy;
+    new_pic = s->new_picture.data[0] + pic_xy;
     old_pic = ref_picture + pic_xy;
     
     map_generation= update_map_generation(s);
@@ -649,7 +649,7 @@
     uint16_t *score_map= s->me_score_map;
     int map_generation;
 
-    new_pic = s->new_picture[0] + pic_xy;
+    new_pic = s->new_picture.data[0] + pic_xy;
     old_pic = ref_picture + pic_xy;
 
     map_generation= update_map_generation(s);
@@ -723,7 +723,7 @@
 
     xx = 16 * s->mb_x + 8*(n&1);
     yy = 16 * s->mb_y + 8*(n>>1);
-    pix =  s->new_picture[0] + (yy * s->linesize) + xx;
+    pix =  s->new_picture.data[0] + (yy * s->linesize) + xx;
 
     mx = *mx_ptr;
     my = *my_ptr;
@@ -789,7 +789,7 @@
         
     xx = 16 * s->mb_x + 8*(n&1);
     yy = 16 * s->mb_y + 8*(n>>1);
-    pix =  s->new_picture[0] + (yy * s->linesize) + xx;
+    pix =  s->new_picture.data[0] + (yy * s->linesize) + xx;
 
     mx = *mx_ptr;
     my = *my_ptr;
@@ -931,7 +931,7 @@
 {
     int block;
     int P[10][2];
-    uint8_t *ref_picture= s->last_picture[0];
+    uint8_t *ref_picture= s->last_picture.data[0];
     int dmin_sum=0;
 
     for(block=0; block<4; block++){
@@ -1019,7 +1019,8 @@
     int P[10][2];
     const int shift= 1+s->quarter_sample;
     int mb_type=0;
-    uint8_t *ref_picture= s->last_picture[0];
+    uint8_t *ref_picture= s->last_picture.data[0];
+    Picture * const pic= &s->current_picture;
 
     get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
     rel_xmin= xmin - mb_x*16;
@@ -1104,7 +1105,7 @@
     xx = mb_x * 16;
     yy = mb_y * 16;
 
-    pix = s->new_picture[0] + (yy * s->linesize) + xx;
+    pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
     /* At this point (mx,my) are full-pell and the relative displacement */
     ppix = ref_picture + ((yy+my) * s->linesize) + (xx+mx);
     
@@ -1115,11 +1116,11 @@
     vard = (s->dsp.pix_norm(pix, ppix, s->linesize)+128)>>8;
 
 //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
-    s->mb_var   [s->mb_width * mb_y + mb_x] = varc;
-    s->mc_mb_var[s->mb_width * mb_y + mb_x] = vard;
-    s->mb_mean  [s->mb_width * mb_y + mb_x] = (sum+128)>>8;
-    s->mb_var_sum    += varc;
-    s->mc_mb_var_sum += vard;
+    pic->mb_var   [s->mb_width * mb_y + mb_x] = varc;
+    pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard;
+    pic->mb_mean  [s->mb_width * mb_y + mb_x] = (sum+128)>>8;
+    pic->mb_var_sum    += varc;
+    pic->mc_mb_var_sum += vard;
 //printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
     
 #if 0
@@ -1318,7 +1319,7 @@
     if (src_y == s->height)
         dxy&= 1;
 
-    ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;
+    ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;
     s->dsp.put_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);
 
     fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale;
@@ -1333,10 +1334,10 @@
     if (src_y == s->height)
         dxy&= 1;
 
-    ptr = s->next_picture[0] + (src_y * s->linesize) + src_x;
+    ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x;
     s->dsp.avg_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);
 
-    fbmin += s->dsp.pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);
+    fbmin += s->dsp.pix_abs16x16(s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);
     return fbmin;
 }
 
@@ -1418,7 +1419,7 @@
             src_y = clip(src_y, -16, height);
             if (src_y == height) dxy &= ~2;
 
-            ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;
+            ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;
             s->dsp.put_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);
 
             dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
@@ -1511,8 +1512,8 @@
     
     dmin= direct_search(s, mb_x, mb_y);
 
-    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code);
-    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant;
+    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture.data[0], s->f_code);
+    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture.data[0], s->b_code) - quant;
 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
 
     fbmin= bidir_refine(s, mb_x, mb_y);
@@ -1534,8 +1535,8 @@
             type= MB_TYPE_BIDIR;
         }
         score= ((unsigned)(score*score + 128*256))>>16;
-        s->mc_mb_var_sum += score;
-        s->mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD
+        s->current_picture.mc_mb_var_sum += score;
+        s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD
     }
 
     if(s->flags&CODEC_FLAG_HQ){
@@ -1581,7 +1582,7 @@
                     int j;
                     
                     for(j=0; j<fcode && j<8; j++){
-                        if(s->pict_type==B_TYPE || s->mc_mb_var[i] < s->mb_var[i])
+                        if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[i] < s->current_picture.mb_var[i])
                             score[j]-= 170;
                     }
                 }
--- a/mpeg12.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/mpeg12.c	Wed Dec 04 10:04:03 2002 +0000
@@ -134,7 +134,7 @@
         int n;
         UINT64 time_code;
         
-        if (s->picture_in_gop_number == 0) {
+        if (s->current_picture.key_frame) {
             /* mpeg1 header repeated every gop */
             put_header(s, SEQ_START_CODE);
             
@@ -1359,7 +1359,6 @@
     s->mpeg_enc_ctx.picture_number = 0;
     s->repeat_field = 0;
     s->mpeg_enc_ctx.codec_id= avctx->codec->id;
-    avctx->mbskip_table= s->mpeg_enc_ctx.mbskip_table;
     return 0;
 }
 
@@ -1403,9 +1402,6 @@
     s->pict_type = get_bits(&s->gb, 3);
     dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number);
 
-    avctx->pict_type= s->pict_type;
-    avctx->key_frame= s->pict_type == I_TYPE;
-
     skip_bits(&s->gb, 16);
     if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
         s->full_pel[0] = get_bits1(&s->gb);
@@ -1423,6 +1419,8 @@
         s->mpeg_f_code[1][0] = f_code;
         s->mpeg_f_code[1][1] = f_code;
     }
+    s->current_picture.pict_type= s->pict_type;
+    s->current_picture.key_frame= s->pict_type == I_TYPE;
     s->y_dc_scale = 8;
     s->c_dc_scale = 8;
     s->first_slice = 1;
@@ -1576,7 +1574,7 @@
  *         DECODE_SLICE_EOP if the end of the picture is reached
  */
 static int mpeg_decode_slice(AVCodecContext *avctx, 
-                              AVPicture *pict,
+                              AVVideoFrame *pict,
                               int start_code,
                               UINT8 *buf, int buf_size)
 {
@@ -1677,38 +1675,25 @@
     if (/*s->mb_x == 0 &&*/
         s->mb_y == s->mb_height) {
         /* end of image */
-        UINT8 **picture;
+
+        if(s->mpeg2)
+            s->qscale >>=1;
 
         MPV_frame_end(s);
 
         if (s->pict_type == B_TYPE) {
-            picture = s->current_picture;
-            avctx->quality = s->qscale;
+            *pict= *(AVVideoFrame*)&s->current_picture;
         } else {
+            s->picture_number++;
             /* latency of 1 frame for I and P frames */
             /* XXX: use another variable than picture_number */
-            if (s->picture_number == 0) {
-                picture = NULL;
+            if (s->picture_number == 1) {
+                return DECODE_SLICE_OK;
             } else {
-                picture = s->last_picture;
-                avctx->quality = s->last_qscale;
+                *pict= *(AVVideoFrame*)&s->last_picture;
             }
-            s->last_qscale = s->qscale;
-            s->picture_number++;
         }
-        if(s->mpeg2)
-            avctx->quality>>=1;
-        if (picture) {
-            pict->data[0] = picture[0];
-            pict->data[1] = picture[1];
-            pict->data[2] = picture[2];
-            pict->linesize[0] = s->linesize;
-            pict->linesize[1] = s->uvlinesize;
-            pict->linesize[2] = s->uvlinesize;
-            return DECODE_SLICE_EOP;
-        } else {
-            return DECODE_SLICE_OK;
-        }
+        return DECODE_SLICE_EOP;
     } else {
         return DECODE_SLICE_OK;
     }
@@ -1827,7 +1812,7 @@
     Mpeg1Context *s = avctx->priv_data;
     UINT8 *buf_end, *buf_ptr, *buf_start;
     int len, start_code_found, ret, code, start_code, input_size;
-    AVPicture *picture = data;
+    AVVideoFrame *picture = data;
     MpegEncContext *s2 = &s->mpeg_enc_ctx;
             
     dprintf("fill_buffer\n");
@@ -1837,13 +1822,9 @@
     /* special case for last picture */
     if (buf_size == 0) {
         if (s2->picture_number > 0) {
-            picture->data[0] = s2->next_picture[0];
-            picture->data[1] = s2->next_picture[1];
-            picture->data[2] = s2->next_picture[2];
-            picture->linesize[0] = s2->linesize;
-            picture->linesize[1] = s2->uvlinesize;
-            picture->linesize[2] = s2->uvlinesize;
-            *data_size = sizeof(AVPicture);
+            *picture= *(AVVideoFrame*)&s2->next_picture;
+
+            *data_size = sizeof(AVVideoFrame);
         }
         return 0;
     }
--- a/mpegvideo.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/mpegvideo.c	Wed Dec 04 10:04:03 2002 +0000
@@ -46,7 +46,6 @@
 static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, 
                                     int src_x, int src_y, int w, int h);
 
-#define EDGE_WIDTH 16
 
 /* enable all paranoid tests for rounding, overflows, etc... */
 //#define PARANOID
@@ -268,10 +267,47 @@
     return 0;
 }
 
+/**
+ * allocates various arrays for a Picture structure, except the pixels themself.
+ * The pixels are allocated/set in te get_buffer()
+ */
+static int alloc_picture(MpegEncContext *s, Picture *pic){
+    if (s->encoding) {        
+        CHECKED_ALLOCZ(pic->mb_var   , s->mb_num * sizeof(INT16))
+        CHECKED_ALLOCZ(pic->mc_mb_var, s->mb_num * sizeof(INT16))
+        CHECKED_ALLOCZ(pic->mb_mean  , s->mb_num * sizeof(INT8))
+    }
+
+    CHECKED_ALLOCZ(pic->mbskip_table , s->mb_num * sizeof(UINT8)+1) //the +1 is for the slice end check
+    CHECKED_ALLOCZ(pic->qscale_table , s->mb_num * sizeof(UINT8))
+    pic->qstride= s->mb_width;
+    
+    return 0;
+fail: //for the CHECKED_ALLOCZ macro
+    return -1;
+}
+
+static void free_picture(MpegEncContext *s, Picture *pic){
+    int i;
+    
+    av_freep(&pic->mb_var);
+    av_freep(&pic->mc_mb_var);
+    av_freep(&pic->mb_mean);
+    av_freep(&pic->mbskip_table);
+    av_freep(&pic->qscale_table);
+    
+    if(s->avctx->get_buffer == avcodec_default_get_buffer){
+        for(i=0; i<4; i++){
+            av_freep(&pic->base[i]);
+            pic->data[i]= NULL;
+        }
+        av_freep(&pic->opaque);
+    }
+}
+
 /* init common structure for both encoder and decoder */
 int MPV_common_init(MpegEncContext *s)
 {
-    UINT8 *pict;
     int y_size, c_size, yc_size, i;
 
     dsputil_init(&s->dsp, s->avctx->dsp_mask);
@@ -279,7 +315,7 @@
 
     s->flags= s->avctx->flags;
 
-    s->mb_width = (s->width + 15) / 16;
+    s->mb_width  = (s->width  + 15) / 16;
     s->mb_height = (s->height + 15) / 16;
 
     /* set default edge pos, will be overriden in decode_header if needed */
@@ -298,51 +334,12 @@
                      + (toupper((s->avctx->fourcc>>16)&0xFF)<<16) 
                      + (toupper((s->avctx->fourcc>>24)&0xFF)<<24);
 
-    if(!(s->flags&CODEC_FLAG_DR1)){
-      s->linesize   = s->mb_width * 16 + 2 * EDGE_WIDTH;
-      s->uvlinesize = s->mb_width * 8  +     EDGE_WIDTH;
-
-      for(i=0;i<3;i++) {
-	int w, h, shift, pict_start;
-	unsigned size;
-
-        w = s->linesize;
-        h = s->mb_height * 16 + 2 * EDGE_WIDTH;
-        shift = (i == 0) ? 0 : 1;
-        size = (s->linesize>>shift) * (h >> shift);
-        pict_start = (s->linesize>>shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift);
-
-        CHECKED_ALLOCZ(pict, size)
-        s->last_picture_base[i] = pict;
-        s->last_picture[i] = pict + pict_start;
-        if(i>0) memset(s->last_picture_base[i], 128, size);
-    
-        CHECKED_ALLOCZ(pict, size)
-        s->next_picture_base[i] = pict;
-        s->next_picture[i] = pict + pict_start;
-        if(i>0) memset(s->next_picture_base[i], 128, size);
-        
-        if (s->has_b_frames || s->codec_id==CODEC_ID_MPEG4) {
-        /* Note the MPEG4 stuff is here cuz of buggy encoders which dont set the low_delay flag but 
-           do low-delay encoding, so we cant allways distinguish b-frame containing streams from low_delay streams */
-            CHECKED_ALLOCZ(pict, size)
-            s->aux_picture_base[i] = pict;
-            s->aux_picture[i] = pict + pict_start;
-            if(i>0) memset(s->aux_picture_base[i], 128, size);
-        }
-      }
-      s->ip_buffer_count= 2;
-    }
-    
     CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance
-    
+
+    s->avctx->coded_picture= (AVVideoFrame*)&s->current_picture;
+
     if (s->encoding) {
-        int j;
         int mv_table_size= (s->mb_width+2)*(s->mb_height+2);
-        
-        CHECKED_ALLOCZ(s->mb_var   , s->mb_num * sizeof(INT16))
-        CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16))
-        CHECKED_ALLOCZ(s->mb_mean  , s->mb_num * sizeof(INT8))
 
         /* Allocate MV tables */
         CHECKED_ALLOCZ(s->p_mv_table            , mv_table_size * 2 * sizeof(INT16))
@@ -354,28 +351,12 @@
         CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16))
         CHECKED_ALLOCZ(s->b_direct_mv_table     , mv_table_size * 2 * sizeof(INT16))
 
-        CHECKED_ALLOCZ(s->me_scratchpad,  s->linesize*16*3*sizeof(uint8_t))
+        //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer()
+        CHECKED_ALLOCZ(s->me_scratchpad,  s->width*2*16*3*sizeof(uint8_t)) 
         
         CHECKED_ALLOCZ(s->me_map      , ME_MAP_SIZE*sizeof(uint32_t))
         CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t))
 
-        if(s->max_b_frames){
-            for(j=0; j<REORDER_BUFFER_SIZE; j++){
-                int i;
-                for(i=0;i<3;i++) {
-                    int w, h, shift, size;
-
-                    w = s->linesize;
-                    h = s->mb_height * 16;
-                    shift = (i == 0) ? 0 : 1;
-                    size = (w >> shift) * (h >> shift);
-
-                    CHECKED_ALLOCZ(pict, size);
-                    s->picture_buffer[j][i] = pict;
-                }
-            }
-        }
-
         if(s->codec_id==CODEC_ID_MPEG4){
             CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE);
             CHECKED_ALLOCZ(   s->pb2_buffer, PB_BUFFER_SIZE);
@@ -434,12 +415,6 @@
             s->dc_val[0][i] = 1024;
     }
 
-    CHECKED_ALLOCZ(s->next_qscale_table  , s->mb_num * sizeof(UINT8))
-    CHECKED_ALLOCZ(s->last_qscale_table  , s->mb_num * sizeof(UINT8))
-    CHECKED_ALLOCZ(s->aux_qscale_table   , s->mb_num * sizeof(UINT8))
-    s->qscale_table= s->next_qscale_table;
-    s->avctx->qstride= s->mb_width;
-    
     /* which mb is a intra block */
     CHECKED_ALLOCZ(s->mbintra_table, s->mb_num);
     memset(s->mbintra_table, 1, s->mb_num);
@@ -470,10 +445,13 @@
 {
     int i;
 
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        if(s->picture[i].data[0]){
+            s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]);
+        }
+    }
+    
     av_freep(&s->mb_type);
-    av_freep(&s->mb_var);
-    av_freep(&s->mc_mb_var);
-    av_freep(&s->mb_mean);
     av_freep(&s->p_mv_table);
     av_freep(&s->b_forw_mv_table);
     av_freep(&s->b_back_mv_table);
@@ -489,9 +467,6 @@
     av_freep(&s->mbintra_table);
     av_freep(&s->cbp_table);
     av_freep(&s->pred_dir_table);
-    av_freep(&s->next_qscale_table);
-    av_freep(&s->last_qscale_table);
-    av_freep(&s->aux_qscale_table);
     av_freep(&s->me_scratchpad);
     av_freep(&s->me_map);
     av_freep(&s->me_score_map);
@@ -507,24 +482,9 @@
     av_freep(&s->avctx->stats_out);
     av_freep(&s->ac_stats);
     av_freep(&s->error_status_table);
-    
-    for(i=0;i<3;i++) {
-        int j;
-        if(!(s->flags&CODEC_FLAG_DR1)){
-            av_freep(&s->last_picture_base[i]);
-            av_freep(&s->next_picture_base[i]);
-            av_freep(&s->aux_picture_base[i]);
-        }
-        s->last_picture_base[i]=
-        s->next_picture_base[i]=
-        s->aux_picture_base [i] = NULL;
-        s->last_picture[i]=
-        s->next_picture[i]=
-        s->aux_picture [i] = NULL;
-
-        for(j=0; j<REORDER_BUFFER_SIZE; j++){
-            av_freep(&s->picture_buffer[j][i]);
-        }
+
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        free_picture(s, &s->picture[i]);
     }
     s->context_initialized = 0;
 }
@@ -813,70 +773,70 @@
 /* generic function for encode/decode called before a frame is coded/decoded */
 int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
 {
-    int i;
-    UINT8 *tmp;
+    int i, r;
+    AVVideoFrame *pic;
 
     s->mb_skiped = 0;
-    avctx->mbskip_table= s->mbskip_table;
+    
+    /* mark&release old frames */
+    if (s->pict_type != B_TYPE && s->last_picture.data[0]) {
+        Picture *pic= NULL;
+        for(i=0; i<MAX_PICTURE_COUNT; i++){
+            if(s->picture[i].data[0] == s->last_picture.data[0]){
+//                s->picture[i].reference=0;
+                avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]);
+                break;
+            }    
+        }
+        assert(i<MAX_PICTURE_COUNT);
+
+        /* release forgotten pictures */
+        /* if(mpeg124/h263) */
+        if(!s->encoding){
+            for(i=0; i<MAX_PICTURE_COUNT; i++){
+                if(s->picture[i].data[0] && s->picture[i].data[0] != s->next_picture.data[0] && s->picture[i].reference){
+                    fprintf(stderr, "releasing zombie picture\n");
+                    avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]);                
+                }
+            }
+        }
+    }
+
+    if(!s->encoding){        
+        /* find unused Picture */
+        for(i=0; i<MAX_PICTURE_COUNT; i++){
+            if(s->picture[i].data[0]==NULL) break;
+        }
+        assert(i<MAX_PICTURE_COUNT);
+    
+        pic= (AVVideoFrame*)&s->picture[i];
+        pic->reference= s->pict_type != B_TYPE;
+        pic->coded_picture_number= s->current_picture.coded_picture_number+1;
+        
+        r= avctx->get_buffer(avctx, pic);
+    
+        if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){
+            fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n");
+            return -1;
+        }
+
+        s->linesize  = pic->linesize[0];
+        s->uvlinesize= pic->linesize[1];
+    
+        if(pic->qscale_table==NULL)
+            alloc_picture(s, (Picture*)pic);
+
+        s->current_picture= s->picture[i];
+    }
 
     s->hurry_up= s->avctx->hurry_up;
     s->error_resilience= avctx->error_resilience;
 
-    if(avctx->flags&CODEC_FLAG_DR1){
-        if(avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type) < 0){
-            fprintf(stderr, "get_buffer() failed\n");
-            return -1;
-        }
-
-        s->linesize  = avctx->dr_stride;
-        s->uvlinesize= avctx->dr_uvstride;
-        s->ip_buffer_count= avctx->dr_ip_buffer_count;
+    if (s->pict_type != B_TYPE) {
+        s->last_picture= s->next_picture;
+        s->next_picture= s->current_picture;
     }
-    avctx->dr_ip_buffer_count= s->ip_buffer_count;
-    
-    if (s->pict_type == B_TYPE) {
-        for(i=0;i<3;i++) {
-            if(avctx->flags&CODEC_FLAG_DR1)
-                s->aux_picture[i]= avctx->dr_buffer[i];
-            
-            //FIXME the following should never be needed, the decoder should drop b frames if no reference is available
-            if(s->next_picture[i]==NULL)
-                s->next_picture[i]= s->aux_picture[i];
-            if(s->last_picture[i]==NULL)
-                s->last_picture[i]= s->next_picture[i];
-
-            s->current_picture[i] = s->aux_picture[i];
-        }
-        s->avctx->display_qscale_table=
-        s->avctx->current_qscale_table= 
-        s->qscale_table= s->aux_qscale_table;
-    } else {
-        for(i=0;i<3;i++) {
-            /* swap next and last */
-            if(avctx->flags&CODEC_FLAG_DR1)
-                tmp= avctx->dr_buffer[i];
-            else
-                tmp = s->last_picture[i];
-
-            s->last_picture[i] = s->next_picture[i];
-            s->next_picture[i] = tmp;
-            s->current_picture[i] = tmp;
-
-            if(s->last_picture[i]==NULL)
-                s->last_picture[i]= s->next_picture[i];
-
-            s->last_dr_opaque= s->next_dr_opaque;
-            s->next_dr_opaque= avctx->dr_opaque_frame;
-
-            if(s->has_b_frames && s->last_dr_opaque && s->codec_id!=CODEC_ID_SVQ1)
-                avctx->dr_opaque_frame= s->last_dr_opaque;
-            else
-                avctx->dr_opaque_frame= s->next_dr_opaque;
-        }
-        s->avctx->current_qscale_table= s->qscale_table      = s->last_qscale_table;
-        s->avctx->display_qscale_table= s->last_qscale_table = s->next_qscale_table;
-        s->next_qscale_table= s->qscale_table;
-    }
+   
     /* set dequantizer, we cant do it during init as it might change for mpeg4
        and we cant do it in the header decode as init isnt called for mpeg4 there yet */
     if(s->out_format == FMT_H263){
@@ -893,14 +853,15 @@
 /* generic function for encode/decode called after a frame has been coded/decoded */
 void MPV_frame_end(MpegEncContext *s)
 {
-    s->avctx->key_frame   = (s->pict_type == I_TYPE);
-    s->avctx->pict_type   = s->pict_type;
+    int i;
 
     /* draw edge for correct motion prediction if outside */
-    if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
-        draw_edges(s->current_picture[0], s->linesize  , s->h_edge_pos   , s->v_edge_pos   , EDGE_WIDTH  );
-        draw_edges(s->current_picture[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
-        draw_edges(s->current_picture[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
+    if(s->codec_id!=CODEC_ID_SVQ1){
+        if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
+            draw_edges(s->current_picture.data[0], s->linesize  , s->h_edge_pos   , s->v_edge_pos   , EDGE_WIDTH  );
+            draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
+            draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
+        }
     }
     emms_c();
     
@@ -910,84 +871,154 @@
         s->num_available_buffers++;
         if(s->num_available_buffers>2) s->num_available_buffers= 2;
     }
-}
-
-/* reorder input for encoding */
-void reorder_input(MpegEncContext *s, AVPicture *pict)
-{
-    int i, j, index;
-            
-    if(s->max_b_frames > FF_MAX_B_FRAMES) s->max_b_frames= FF_MAX_B_FRAMES;
-
-//        delay= s->max_b_frames+1; (or 0 if no b frames cuz decoder diff)
-
-    for(j=0; j<REORDER_BUFFER_SIZE-1; j++){
-        s->coded_order[j]= s->coded_order[j+1];
+    
+    s->current_picture.quality= s->qscale; //FIXME get average of qscale_table
+    s->current_picture.pict_type= s->pict_type;
+    s->current_picture.key_frame= s->pict_type == I_TYPE;
+    
+    /* copy back current_picture variables */
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        if(s->picture[i].data[0] == s->current_picture.data[0]){
+            s->picture[i]= s->current_picture;
+            break;
+        }    
+    }
+    assert(i<MAX_PICTURE_COUNT);
+
+    /* release non refernce frames */
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        if(s->picture[i].data[0] && !s->picture[i].reference)
+            s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]);
     }
-    s->coded_order[j].picture[0]= s->coded_order[j].picture[1]= s->coded_order[j].picture[2]= NULL; //catch uninitalized buffers
-    s->coded_order[j].pict_type=0;
-
-    switch(s->input_pict_type){
-    default: 
-    case I_TYPE:
-    case S_TYPE:
-    case P_TYPE:
-        index= s->max_b_frames - s->b_frames_since_non_b;
-        s->b_frames_since_non_b=0;
-        break;            
-    case B_TYPE:
-        index= s->max_b_frames + 1;
-        s->b_frames_since_non_b++;
-        break;          
+}
+
+static int load_input_picture(MpegEncContext *s, AVVideoFrame *pic_arg){
+    AVVideoFrame *pic;
+    int i,r;
+    const int encoding_delay= s->max_b_frames;
+
+    /* find unused Picture */
+    for(i=0; i<MAX_PICTURE_COUNT; i++){
+        if(s->picture[i].data[0]==NULL) break;
+    }
+    assert(i<MAX_PICTURE_COUNT);
+        
+    pic= (AVVideoFrame*)&s->picture[i];
+    pic->reference= 1;
+    
+//    assert(avctx->get_buffer == default_get_buffer || avctx->get_buffer==NULL);
+    r= s->avctx->get_buffer(s->avctx, pic);
+
+    if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){
+        fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n");
+        return -1;
     }
-//printf("index:%d type:%d strides: %d %d\n", index, s->input_pict_type, pict->linesize[0], s->linesize);
-    if(   (index==0 || (s->flags&CODEC_FLAG_INPUT_PRESERVED))
-       && pict->linesize[0] == s->linesize
-       && pict->linesize[1] == s->uvlinesize
-       && pict->linesize[2] == s->uvlinesize){
-//printf("ptr\n");
-        for(i=0; i<3; i++){
-            s->coded_order[index].picture[i]= pict->data[i];
-        }
+    
+    assert(s->linesize==0   || s->linesize  ==pic->linesize[0]);
+    assert(s->uvlinesize==0 || s->uvlinesize==pic->linesize[1]);
+    assert(pic->linesize[1] == pic->linesize[2]);
+    s->linesize  = pic->linesize[0];
+    s->uvlinesize= pic->linesize[1];
+    
+    if(pic->qscale_table==NULL)
+        alloc_picture(s, (Picture*)pic);
+
+//    assert(s->input_picture[0]==NULL || s->input_picture[0]->data[0]==NULL);
+    
+    if(s->input_picture[encoding_delay])
+        pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1;
+//printf("dpn2:%d\n", pic->display_picture_number);
+
+    /* shift buffer entries */
+    for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
+        s->input_picture[i-1]= s->input_picture[i];
+        
+    s->input_picture[encoding_delay]= (Picture*)pic;
+    pic->pict_type= pic_arg->pict_type;
+    pic->quality= pic_arg->quality;
+    
+    if(   pic->data[0] == pic_arg->data[0] 
+       && pic->data[1] == pic_arg->data[1]
+       && pic->data[2] == pic_arg->data[2]){
+       // empty
     }else{
-//printf("copy\n");
+        int h_chroma_shift, v_chroma_shift;
+        
+        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+        
         for(i=0; i<3; i++){
-            uint8_t *src = pict->data[i];
-            uint8_t *dest;
-            int src_wrap = pict->linesize[i];
-            int dest_wrap = s->linesize;
-            int w = s->width;
-            int h = s->height;
-
-            if(index==0) dest= s->last_picture[i]+16; //is current_picture indeed but the switch hapens after reordering
-            else         dest= s->picture_buffer[s->picture_buffer_index][i];
-
-            if (i >= 1) {
-                dest_wrap >>= 1;
-                w >>= 1;
-                h >>= 1;
-            }
-
-            s->coded_order[index].picture[i]= dest;
-            for(j=0;j<h;j++) {
-                memcpy(dest, src, w);
-                dest += dest_wrap;
-                src += src_wrap;
+            int src_stride= pic_arg->linesize[i];
+            int dst_stride= i ? s->uvlinesize : s->linesize;
+            int h_shift= i ? h_chroma_shift : 0;
+            int v_shift= i ? v_chroma_shift : 0;
+            int w= s->width >>h_shift;
+            int h= s->height>>v_shift;
+            uint8_t *src= pic_arg->data[i];
+            uint8_t *dst= pic->data[i] + 16;
+            
+            if(src_stride==dst_stride)
+                memcpy(dst, src, src_stride*h);
+            else{
+                while(h--){
+                    memcpy(dst, src, w);
+                    dst += dst_stride;
+                    src += src_stride;
+                }
             }
         }
-        if(index!=0){
-            s->picture_buffer_index++;
-            if(s->picture_buffer_index >= REORDER_BUFFER_SIZE) s->picture_buffer_index=0;
+    }
+
+    return 0;
+}
+
+static void select_input_picture(MpegEncContext *s){
+    int i;
+    const int encoding_delay= s->max_b_frames;
+    int coded_pic_num=0;    
+
+    if(s->reordered_input_picture[0])
+        coded_pic_num= s->reordered_input_picture[0]->coded_picture_number + 1;
+//printf("cpn:%d\n", coded_pic_num);
+    for(i=1; i<MAX_PICTURE_COUNT; i++)
+        s->reordered_input_picture[i-1]= s->reordered_input_picture[i];
+    s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL;
+
+    /* set next picture types & ordering */
+    if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){
+        if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture.data[0]==NULL || s->intra_only){
+            s->reordered_input_picture[0]= s->input_picture[0];
+            s->reordered_input_picture[0]->pict_type= I_TYPE;
+            s->reordered_input_picture[0]->coded_picture_number= coded_pic_num;
+        }else{
+            s->reordered_input_picture[0]= s->input_picture[s->max_b_frames];
+            if(s->picture_in_gop_number + s->max_b_frames >= s->gop_size)
+                s->reordered_input_picture[0]->pict_type= I_TYPE;
+            else
+                s->reordered_input_picture[0]->pict_type= P_TYPE;
+            s->reordered_input_picture[0]->coded_picture_number= coded_pic_num;
+            for(i=0; i<s->max_b_frames; i++){
+                coded_pic_num++;
+                s->reordered_input_picture[i+1]= s->input_picture[i];
+                s->reordered_input_picture[i+1]->pict_type= B_TYPE;
+                s->reordered_input_picture[i+1]->coded_picture_number= coded_pic_num;
+            }
         }
     }
-    s->coded_order[index].pict_type = s->input_pict_type;
-    s->coded_order[index].qscale    = s->input_qscale;
-    s->coded_order[index].force_type= s->force_input_type;
-    s->coded_order[index].picture_in_gop_number= s->input_picture_in_gop_number;
-    s->coded_order[index].picture_number= s->input_picture_number;
-
-    for(i=0; i<3; i++){
-        s->new_picture[i]= s->coded_order[0].picture[i];
+    
+    if(s->reordered_input_picture[0]){
+        if(s->reordered_input_picture[0]->pict_type==B_TYPE){
+            s->reordered_input_picture[0]->reference=0;
+        }
+        s->current_picture= *s->reordered_input_picture[0];
+        s->new_picture= s->current_picture;
+        s->new_picture.data[0]+=16;
+        s->new_picture.data[1]+=16;
+        s->new_picture.data[2]+=16;
+    
+        s->picture_number= s->new_picture.display_picture_number;
+//printf("dpn:%d\n", s->picture_number);
+    }else{
+       memset(&s->new_picture, 0, sizeof(Picture));
     }
 }
 
@@ -995,52 +1026,26 @@
                        unsigned char *buf, int buf_size, void *data)
 {
     MpegEncContext *s = avctx->priv_data;
-    AVPicture *pict = data;
-
-    s->input_qscale = avctx->quality;
+    AVVideoFrame *pic_arg = data;
 
     init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
 
-    if(avctx->force_type){
-        s->input_pict_type=
-        s->force_input_type= avctx->force_type;
-    }else if(s->flags&CODEC_FLAG_PASS2){
-        s->input_pict_type=
-        s->force_input_type= s->rc_context.entry[s->input_picture_number].new_pict_type;
-    }else{
-        s->force_input_type=0;
-        if (!s->intra_only) {
-            /* first picture of GOP is intra */
-            if (s->input_picture_in_gop_number % s->gop_size==0){
-                s->input_pict_type = I_TYPE;
-            }else if(s->max_b_frames==0){
-                s->input_pict_type = P_TYPE;
-            }else{
-                if(s->b_frames_since_non_b < s->max_b_frames) //FIXME more IQ
-                    s->input_pict_type = B_TYPE;
-                else
-                    s->input_pict_type = P_TYPE;
-            }
-        } else {
-            s->input_pict_type = I_TYPE;
-        }
-    }
-
-    if(s->input_pict_type==I_TYPE)
-        s->input_picture_in_gop_number=0;
+    s->picture_in_gop_number++;
+
+    load_input_picture(s, pic_arg);
     
-    reorder_input(s, pict);
+    select_input_picture(s);
     
     /* output? */
-    if(s->coded_order[0].picture[0]){
-
-        s->pict_type= s->coded_order[0].pict_type;
-        if (s->fixed_qscale) /* the ratecontrol needs the last qscale so we dont touch it for CBR */
-            s->qscale= s->coded_order[0].qscale;
-        s->force_type= s->coded_order[0].force_type;
-        s->picture_in_gop_number= s->coded_order[0].picture_in_gop_number;
-        s->picture_number= s->coded_order[0].picture_number;
-
+    if(s->new_picture.data[0]){
+
+        s->pict_type= s->new_picture.pict_type;
+        if (s->fixed_qscale){ /* the ratecontrol needs the last qscale so we dont touch it for CBR */
+            s->qscale= (int)(s->new_picture.quality+0.5);
+            assert(s->qscale);
+        }
+//emms_c();
+//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale);
         MPV_frame_start(s, avctx);
 
         encode_picture(s, s->picture_number);
@@ -1059,17 +1064,12 @@
 
         if (s->out_format == FMT_MJPEG)
             mjpeg_picture_trailer(s);
-
-        if(!s->fixed_qscale)
-            avctx->quality = s->qscale;
         
         if(s->flags&CODEC_FLAG_PASS1)
             ff_write_pass1_stats(s);
-    
     }
 
     s->input_picture_number++;
-    s->input_picture_in_gop_number++;
 
     flush_put_bits(&s->pb);
     s->frame_bits  = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
@@ -1088,14 +1088,16 @@
     fprintf(f, "%7d, %7d, %2.4f\n", pbBufPtr(&s->pb) - s->pb.buf, s->qscale, avctx->psnr_y);
 }
 #endif
-
+#if 0
     if (avctx->get_psnr) {
         /* At this point pict->data should have the original frame   */
         /* an s->current_picture should have the coded/decoded frame */
-        get_psnr(pict->data, s->current_picture,
+        get_psnr(pict->data, s->current_picture.data,
                  pict->linesize, s->linesize, avctx);
 //        printf("%f\n", avctx->psnr_y);
     }
+#endif
+
     return pbBufPtr(&s->pb) - s->pb.buf;
 }
 
@@ -1757,7 +1759,7 @@
     mb_x = s->mb_x;
     mb_y = s->mb_y;
 
-    s->qscale_table[mb_xy]= s->qscale;
+    s->current_picture.qscale_table[mb_xy]= s->qscale;
 
     /* update DC predictors for P macroblocks */
     if (!s->mb_intra) {
@@ -1823,33 +1825,47 @@
         op_pixels_func (*op_pix)[4];
         qpel_mc_func (*op_qpix)[16];
 
-        /* avoid copy if macroblock skipped in last frame too 
-           dont touch it for B-frames as they need the skip info from the next p-frame */
+        /* avoid copy if macroblock skipped in last frame too */
         if (s->pict_type != B_TYPE) {
+            s->current_picture.mbskip_table[mb_xy]= s->mb_skiped;
+        }
+
+        /* skip only during decoding as we might trash the buffers during encoding a bit */
+        if(!s->encoding){
             UINT8 *mbskip_ptr = &s->mbskip_table[mb_xy];
+            const int age= s->current_picture.age;
+
+            assert(age);
+
             if (s->mb_skiped) {
-                s->mb_skiped = 0;
-
+                s->mb_skiped= 0;
+                assert(s->pict_type!=I_TYPE);
+ 
                 (*mbskip_ptr) ++; /* indicate that this time we skiped it */
                 if(*mbskip_ptr >99) *mbskip_ptr= 99;
 
-                /* if previous was skipped too, then nothing to do ! 
-                   skip only during decoding as we might trash the buffers during encoding a bit */
-                if (*mbskip_ptr >= s->ip_buffer_count  && !s->encoding) 
-                    return;
+                /* if previous was skipped too, then nothing to do !  */
+                if (*mbskip_ptr >= age){
+//if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n");
+//if(s->pict_type!=B_TYPE) printf("%d%d ", *mbskip_ptr, age);
+                    if(s->pict_type!=B_TYPE) return;
+                    if(s->avctx->draw_horiz_band==NULL && *mbskip_ptr > age) return; 
+                    /* we dont draw complete frames here so we cant skip */
+                }
             } else {
                 *mbskip_ptr = 0; /* not skipped */
             }
-        }
+        }else
+            s->mb_skiped= 0;
 
         if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band){
-            dest_y = s->current_picture [0] + mb_x * 16;
-            dest_cb = s->current_picture[1] + mb_x * 8;
-            dest_cr = s->current_picture[2] + mb_x * 8;
+            dest_y  = s->current_picture.data[0] + mb_x * 16;
+            dest_cb = s->current_picture.data[1] + mb_x * 8;
+            dest_cr = s->current_picture.data[2] + mb_x * 8;
         }else{
-            dest_y = s->current_picture [0] + (mb_y * 16* s->linesize  ) + mb_x * 16;
-            dest_cb = s->current_picture[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
-            dest_cr = s->current_picture[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
+            dest_y  = s->current_picture.data[0] + (mb_y * 16* s->linesize  ) + mb_x * 16;
+            dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
+            dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
         }
 
         if (s->interlaced_dct) {
@@ -1873,12 +1889,12 @@
                 }
 
                 if (s->mv_dir & MV_DIR_FORWARD) {
-                    MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
+                    MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
 		    op_pix = s->dsp.avg_pixels_tab;
                     op_qpix= s->dsp.avg_qpel_pixels_tab;
                 }
                 if (s->mv_dir & MV_DIR_BACKWARD) {
-                    MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix);
+                    MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
                 }
             }
 
@@ -2154,13 +2170,13 @@
             offset = y * s->linesize;
 
         if(s->pict_type==B_TYPE || (!s->has_b_frames)){
-            src_ptr[0] = s->current_picture[0] + offset;
-            src_ptr[1] = s->current_picture[1] + (offset >> 2);
-            src_ptr[2] = s->current_picture[2] + (offset >> 2);
+            src_ptr[0] = s->current_picture.data[0] + offset;
+            src_ptr[1] = s->current_picture.data[1] + (offset >> 2);
+            src_ptr[2] = s->current_picture.data[2] + (offset >> 2);
         } else {
-            src_ptr[0] = s->last_picture[0] + offset;
-            src_ptr[1] = s->last_picture[1] + (offset >> 2);
-            src_ptr[2] = s->last_picture[2] + (offset >> 2);
+            src_ptr[0] = s->last_picture.data[0] + offset;
+            src_ptr[1] = s->last_picture.data[1] + (offset >> 2);
+            src_ptr[2] = s->last_picture.data[2] + (offset >> 2);
         }
         emms_c();
 
@@ -2180,7 +2196,7 @@
     for(i=0; i<6; i++) skip_dct[i]=0;
     
     if(s->adaptive_quant){
-        s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale;
+        s->dquant= s->current_picture.qscale_table[mb_x + mb_y*s->mb_width] - s->qscale;
 
         if(s->out_format==FMT_H263){
             if     (s->dquant> 2) s->dquant= 2;
@@ -2206,7 +2222,7 @@
         int emu=0;
 
         wrap_y = s->linesize;
-        ptr = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
+        ptr = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
 
         if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
             emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
@@ -2239,14 +2255,14 @@
             skip_dct[5]= 1;
         }else{
             int wrap_c = s->uvlinesize;
-            ptr = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
+            ptr = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
             if(emu){
                 emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr= s->edge_emu_buffer;
             }
 	    s->dsp.get_pixels(s->block[4], ptr, wrap_c);
 
-            ptr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
+            ptr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
             if(emu){
                 emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr= s->edge_emu_buffer;
@@ -2261,14 +2277,14 @@
         int wrap_y, wrap_c;
         int emu=0;
 
-        dest_y  = s->current_picture[0] + (mb_y * 16 * s->linesize       ) + mb_x * 16;
-        dest_cb = s->current_picture[1] + (mb_y * 8  * (s->uvlinesize)) + mb_x * 8;
-        dest_cr = s->current_picture[2] + (mb_y * 8  * (s->uvlinesize)) + mb_x * 8;
+        dest_y  = s->current_picture.data[0] + (mb_y * 16 * s->linesize    ) + mb_x * 16;
+        dest_cb = s->current_picture.data[1] + (mb_y * 8  * (s->uvlinesize)) + mb_x * 8;
+        dest_cr = s->current_picture.data[2] + (mb_y * 8  * (s->uvlinesize)) + mb_x * 8;
         wrap_y = s->linesize;
         wrap_c = s->uvlinesize;
-        ptr_y  = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
-        ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
-        ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
+        ptr_y  = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
+        ptr_cb = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
+        ptr_cr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
 
         if ((!s->no_rounding) || s->pict_type==B_TYPE){
 	    op_pix = s->dsp.put_pixels_tab;
@@ -2279,12 +2295,12 @@
         }
 
         if (s->mv_dir & MV_DIR_FORWARD) {
-            MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
+            MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
             op_pix = s->dsp.avg_pixels_tab;
             op_qpix= s->dsp.avg_qpel_pixels_tab;
         }
         if (s->mv_dir & MV_DIR_BACKWARD) {
-            MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix);
+            MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
         }
 
         if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
@@ -2330,9 +2346,8 @@
             }
             s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
         }
-
         /* pre quantization */         
-        if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){
+        if(s->current_picture.mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){
             //FIXME optimize
 	    if(s->dsp.pix_abs8x8(ptr_y               , dest_y               , wrap_y) < 20*s->qscale) skip_dct[0]= 1;
             if(s->dsp.pix_abs8x8(ptr_y            + 8, dest_y            + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1;
@@ -2557,8 +2572,8 @@
     s->block_wrap[5]= s->mb_width + 2;
     
     /* Reset the average MB variance */
-    s->mb_var_sum = 0;
-    s->mc_mb_var_sum = 0;
+    s->current_picture.mb_var_sum = 0;
+    s->current_picture.mc_mb_var_sum = 0;
 
     /* we need to initialize some time vars before we can encode b-frames */
     if (s->h263_pred && !s->h263_msmpeg4)
@@ -2604,15 +2619,15 @@
                 for(mb_x=0; mb_x < s->mb_width; mb_x++) {
                     int xx = mb_x * 16;
                     int yy = mb_y * 16;
-                    uint8_t *pix = s->new_picture[0] + (yy * s->linesize) + xx;
+                    uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
                     int varc;
 		    int sum = s->dsp.pix_sum(pix, s->linesize);
     
 		    varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
 
-                    s->mb_var [s->mb_width * mb_y + mb_x] = varc;
-                    s->mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8;
-                    s->mb_var_sum    += varc;
+                    s->current_picture.mb_var [s->mb_width * mb_y + mb_x] = varc;
+                    s->current_picture.mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8;
+                    s->current_picture.mb_var_sum    += varc;
                 }
             }
         }
@@ -2622,13 +2637,9 @@
     if(s->scene_change_score > 0 && s->pict_type == P_TYPE){
         s->pict_type= I_TYPE;
         memset(s->mb_type   , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height);
-        if(s->max_b_frames==0){
-            s->input_pict_type= I_TYPE;
-            s->input_picture_in_gop_number=0;
-        }
-//printf("Scene change detected, encoding as I Frame %d %d\n", s->mb_var_sum, s->mc_mb_var_sum);
+//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
     }
-    
+
     if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) 
         s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER);
         ff_fix_long_p_mvs(s);
@@ -2643,7 +2654,7 @@
     }
     
     if (s->fixed_qscale) 
-        s->frame_qscale = s->avctx->quality;
+        s->frame_qscale = s->current_picture.quality;
     else
         s->frame_qscale = ff_rate_estimate_qscale(s);
 
@@ -2658,7 +2669,7 @@
             break;
         }
 
-        s->qscale= s->qscale_table[0];
+        s->qscale= s->current_picture.qscale_table[0];
     }else
         s->qscale= (int)(s->frame_qscale + 0.5);
         
@@ -2673,6 +2684,13 @@
         convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16, 
                        s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias, 8, 8);
     }
+    
+    //FIXME var duplication
+    s->current_picture.key_frame= s->pict_type == I_TYPE;
+    s->current_picture.pict_type= s->pict_type;
+
+    if(s->current_picture.key_frame)
+        s->picture_in_gop_number=0;
 
     s->last_bits= get_bit_count(&s->pb);
     switch(s->out_format) {
--- a/mpegvideo.h	Tue Dec 03 19:40:35 2002 +0000
+++ b/mpegvideo.h	Wed Dec 04 10:04:03 2002 +0000
@@ -28,6 +28,8 @@
     FMT_MJPEG, 
 };
 
+#define EDGE_WIDTH 16
+
 #define MPEG_BUF_SIZE (16 * 1024)
 
 #define QMAT_SHIFT_MMX 16
@@ -35,7 +37,8 @@
 
 #define MAX_FCODE 7
 #define MAX_MV 2048
-#define REORDER_BUFFER_SIZE (FF_MAX_B_FRAMES+2)
+
+#define MAX_PICTURE_COUNT 7
 
 #define ME_MAP_SIZE 64
 #define ME_MAP_SHIFT 3
@@ -90,14 +93,6 @@
     int last_non_b_pict_type;
 }RateControlContext;
 
-typedef struct ReorderBuffer{
-    UINT8 *picture[3];
-    int pict_type;
-    int qscale;
-    int force_type;
-    int picture_number;
-    int picture_in_gop_number;
-} ReorderBuffer;
 
 typedef struct ScanTable{
     const UINT8 *scantable;
@@ -109,6 +104,16 @@
 #endif
 } ScanTable;
 
+typedef struct Picture{
+    FF_COMMON_PICTURE    
+
+    int mb_var_sum;             /* sum of MB variance for current frame */
+    int mc_mb_var_sum;          /* motion compensated MB variance for current frame */
+    uint16_t *mb_var;           /* Table for MB variances */
+    uint16_t *mc_mb_var;        /* Table for motion compensated MB variances */
+    uint8_t *mb_mean;           /* Table for MB luminance */
+} Picture;
+
 typedef struct ParseContext{
     UINT8 *buffer;
     int index;
@@ -145,7 +150,6 @@
     int max_qdiff;    /* max qscale difference between frames */
     int encoding;     /* true if we are encoding (vs decoding) */
     int flags;        /* AVCodecContext.flags (HQ, MV4, ...) */
-    int force_input_type;/* 0= no force, otherwise I_TYPE, P_TYPE, ... */
     int max_b_frames; /* max number of b-frames for encoding */
     int b_frame_strategy;
     int luma_elim_threshold;
@@ -160,10 +164,7 @@
     /* sequence parameters */
     int context_initialized;
     int input_picture_number;
-    int input_picture_in_gop_number; /* 0-> first pic in gop, ... */
     int picture_number;
-    int fake_picture_number; /* picture number at the bitstream frame rate */
-    int gop_picture_number;  /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */
     int picture_in_gop_number; /* 0-> first pic in gop, ... */
     int b_frames_since_non_b;  /* used for encoding, relative to not yet reordered input */
     int mb_width, mb_height;   /* number of MBs horizontally & vertically */
@@ -171,20 +172,13 @@
     int mb_num;                /* number of MBs of a picture */
     int linesize;              /* line size, in bytes, may be different from width */
     int uvlinesize;            /* line size, for chroma in bytes, may be different from width */
-    UINT8 *new_picture[3];     /* picture to be compressed */
-    UINT8 *picture_buffer[REORDER_BUFFER_SIZE][3]; /* internal buffers used for reordering of input pictures */
-    int picture_buffer_index;
-    ReorderBuffer coded_order[REORDER_BUFFER_SIZE];
-    UINT8 *last_picture[3];      /* previous picture */
-    UINT8 *last_picture_base[3]; /* real start of the picture */
-    UINT8 *next_picture[3];      /* previous picture (for bidir pred) */
-    UINT8 *next_picture_base[3]; /* real start of the picture */
-    UINT8 *aux_picture[3];       /* aux picture (for B frames only) */
-    UINT8 *aux_picture_base[3];  /* real start of the picture */
-    UINT8 *current_picture[3];   /* buffer to store the decompressed current picture */
-    void *last_dr_opaque;
-    void *next_dr_opaque;
-    int ip_buffer_count;         /* number of buffers, currently only >2 if dr1 is used */
+    Picture picture[MAX_PICTURE_COUNT]; /* main picture buffer */
+    Picture *input_picture[MAX_PICTURE_COUNT]; /* next pictures on display order for encoding*/
+    Picture *reordered_input_picture[MAX_PICTURE_COUNT]; /* pointer to the next pictures in codedorder for encoding*/
+    Picture last_picture;       /* previous picture */
+    Picture next_picture;       /* previous picture (for bidir pred) */
+    Picture new_picture;        /* source picture for encoding */
+    Picture current_picture;    /* buffer to store the decompressed current picture */
     int num_available_buffers;   /* is 0 at the start & after seeking, after the first I frame its 1 after next I/P 2 */
     int last_dc[3];              /* last DC values for MPEG1 */
     INT16 *dc_val[3];            /* used for mpeg4 DC prediction, all 3 arrays must be continuous */
@@ -200,17 +194,10 @@
     UINT8 *mbintra_table;       /* used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding */
     UINT8 *cbp_table;           /* used to store cbp, ac_pred for partitioned decoding */
     UINT8 *pred_dir_table;      /* used to store pred_dir for partitioned decoding */
-    INT8 *qscale_table;         /* used to store qscale */
-    INT8 *aux_qscale_table;
-    INT8 *next_qscale_table;
-    INT8 *last_qscale_table;     //FIXME move these into some picture struct (MpegEncContext.aux.qscale_table[])
     UINT8 *edge_emu_buffer;
 
-    int input_qscale;           /* qscale prior to reordering of frames */
-    int input_pict_type;        /* pict_type prior to reordering of frames */
-    int force_type;             /* 0= no force, otherwise I_TYPE, P_TYPE, ... */
     int qscale;                 /* QP */
-    float frame_qscale;         /* qscale from the frame level rc */
+    float frame_qscale;         /* qscale from the frame level rc FIXME remove*/
     int adaptive_quant;         /* use adaptive quantization */
     int dquant;                 /* qscale difference to prev qscale */ 
     int pict_type;              /* I_TYPE, P_TYPE, B_TYPE, ... */
@@ -272,9 +259,6 @@
     int mb_x, mb_y;
     int mb_incr;
     int mb_intra;
-    UINT16 *mb_var;       /* Table for MB variances */
-    UINT16 *mc_mb_var;    /* Table for motion compensated MB variances */
-    UINT8 *mb_mean;       /* Table for MB luminance */
     UINT8 *mb_type;       /* Table for MB type */
 #define MB_TYPE_INTRA    0x01
 #define MB_TYPE_INTER    0x02
@@ -325,8 +309,6 @@
 
     /* bit rate control */
     int I_frame_bits; //FIXME used in mpeg12 ...
-    int mb_var_sum;          /* sum of MB variance for current frame */
-    int mc_mb_var_sum;       /* motion compensated MB variance for current frame */
     INT64 wanted_bits;
     INT64 total_bits;
     int frame_bits;        /* bits used for the current frame */
@@ -476,6 +458,10 @@
     /* decompression specific */
     GetBitContext gb;
 
+    /* Mpeg1 specific */
+    int fake_picture_number; /* picture number at the bitstream frame rate */
+    int gop_picture_number;  /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */
+    
     /* MPEG2 specific - I wish I had not to support this mess. */
     int progressive_sequence;
     int mpeg_f_code[2][2];
@@ -498,7 +484,6 @@
     int mpeg2;
     int full_pel[2];
     int interlaced_dct;
-    int last_qscale;
     int first_slice;
     
     /* RTP specific */
--- a/msmpeg4.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/msmpeg4.c	Wed Dec 04 10:04:03 2002 +0000
@@ -759,10 +759,10 @@
             }else{
                 if(n<4){
                     wrap= s->linesize;
-                    dest= s->current_picture[0] + (((n>>1) + 2*s->mb_y) * 8*  wrap ) + ((n&1) + 2*s->mb_x) * 8;
+                    dest= s->current_picture.data[0] + (((n>>1) + 2*s->mb_y) * 8*  wrap ) + ((n&1) + 2*s->mb_x) * 8;
                 }else{
                     wrap= s->uvlinesize;
-                    dest= s->current_picture[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
+                    dest= s->current_picture.data[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
                 }
                 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
                 else           a= get_dc(dest-8, wrap, scale*8);
--- a/ratecontrol.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/ratecontrol.c	Wed Dec 04 10:04:03 2002 +0000
@@ -41,7 +41,7 @@
     sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n",
             s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type, 
             s->frame_qscale, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, 
-            s->f_code, s->b_code, s->mc_mb_var_sum, s->mb_var_sum, s->i_count);
+            s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count);
 }
 
 int ff_rate_control_init(MpegEncContext *s)
@@ -475,11 +475,12 @@
     float bits_tab[s->mb_num];
     const int qmin= 2; //s->avctx->mb_qmin;
     const int qmax= 31; //s->avctx->mb_qmax;
+    Picture * const pic= &s->current_picture;
     
     for(i=0; i<s->mb_num; i++){
-        float temp_cplx= sqrt(s->mc_mb_var[i]);
-        float spat_cplx= sqrt(s->mb_var[i]);
-        const int lumi= s->mb_mean[i];
+        float temp_cplx= sqrt(pic->mc_mb_var[i]);
+        float spat_cplx= sqrt(pic->mb_var[i]);
+        const int lumi= pic->mb_mean[i];
         float bits, cplx, factor;
         
         if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
@@ -533,8 +534,8 @@
             newq*= bits_sum/cplx_sum;
         }
 
-        if(i && ABS(s->qscale_table[i-1] - newq)<0.75)
-            intq= s->qscale_table[i-1];
+        if(i && ABS(pic->qscale_table[i-1] - newq)<0.75)
+            intq= pic->qscale_table[i-1];
         else
             intq= (int)(newq + 0.5);
 
@@ -542,7 +543,7 @@
         else if(intq < qmin) intq= qmin;
 //if(i%s->mb_width==0) printf("\n");
 //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i]));
-        s->qscale_table[i]= intq;
+        pic->qscale_table[i]= intq;
     }
 }
 
@@ -562,6 +563,7 @@
     double rate_factor;
     int var;
     const int pict_type= s->pict_type;
+    Picture * const pic= &s->current_picture;
     emms_c();
 
     get_qminmax(&qmin, &qmax, s, pict_type);
@@ -588,7 +590,7 @@
     br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance;
     if(br_compensation<=0.0) br_compensation=0.001;
 
-    var= pict_type == I_TYPE ? s->mb_var_sum : s->mc_mb_var_sum;
+    var= pict_type == I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum;
     
     if(s->flags&CODEC_FLAG_PASS2){
         if(pict_type!=I_TYPE)
@@ -599,8 +601,8 @@
     }else{
         rce->pict_type= 
         rce->new_pict_type= pict_type;
-        rce->mc_mb_var_sum= s->mc_mb_var_sum;
-        rce->mb_var_sum   = s->   mb_var_sum;
+        rce->mc_mb_var_sum= pic->mc_mb_var_sum;
+        rce->mb_var_sum   = pic->   mb_var_sum;
         rce->qscale   = 2;
         rce->f_code   = s->f_code;
         rce->b_code   = s->b_code;
@@ -663,10 +665,8 @@
     else if(q>qmax) q=qmax;
         
 //    printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits);
-    
-//printf("%f %f %f\n", q, br_compensation, short_term_q);
-   
-//printf("q:%d diff:%d comp:%f st_q:%f last_size:%d type:%d\n", qscale, (int)diff, br_compensation, 
+       
+//printf("diff:%d comp:%f st_q:%f last_size:%d type:%d\n", (int)diff, br_compensation, 
 //       short_term_q, s->frame_bits, pict_type);
 //printf("%d %d\n", s->bit_rate, (int)fps);
 
@@ -676,8 +676,16 @@
         q= (int)(q + 0.5);
     
     rcc->last_qscale= q;
-    rcc->last_mc_mb_var_sum= s->mc_mb_var_sum;
-    rcc->last_mb_var_sum= s->mb_var_sum;
+    rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
+    rcc->last_mb_var_sum= pic->mb_var_sum;
+#if 0
+{
+    static int mvsum=0, texsum=0;
+    mvsum += s->mv_bits;
+    texsum += s->i_tex_bits + s->p_tex_bits;
+    printf("%d %d//\n\n", mvsum, texsum);
+}
+#endif
     return q;
 }
 
--- a/rv10.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/rv10.c	Wed Dec 04 10:04:03 2002 +0000
@@ -472,7 +472,7 @@
 {
     MpegEncContext *s = avctx->priv_data;
     int i;
-    AVPicture *pict = data; 
+    AVVideoFrame *pict = data; 
 
 #ifdef DEBUG
     printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
@@ -505,15 +505,9 @@
     if(s->mb_y>=s->mb_height){
         MPV_frame_end(s);
         
-        pict->data[0] = s->current_picture[0];
-        pict->data[1] = s->current_picture[1];
-        pict->data[2] = s->current_picture[2];
-        pict->linesize[0] = s->linesize;
-        pict->linesize[1] = s->uvlinesize;
-        pict->linesize[2] = s->uvlinesize;
+        *pict= *(AVVideoFrame*)&s->current_picture;
     
-        avctx->quality = s->qscale;
-        *data_size = sizeof(AVPicture);
+        *data_size = sizeof(AVVideoFrame);
     }else{
         *data_size = 0;
     }
--- a/svq1.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/svq1.c	Wed Dec 04 10:04:03 2002 +0000
@@ -1063,7 +1063,7 @@
   MpegEncContext *s=avctx->priv_data;
   uint8_t      *current, *previous;
   int		result, i, x, y, width, height;
-  AVPicture *pict = data; 
+  AVVideoFrame *pict = data; 
 
   /* initialize bit buffer */
   init_get_bits(&s->gb,buf,buf_size);
@@ -1084,9 +1084,6 @@
   }
 
   result = svq1_decode_frame_header (&s->gb, s);
-  
-  if(MPV_frame_start(s, avctx) < 0)
-      return -1;
 
   if (result != 0)
   {
@@ -1098,6 +1095,9 @@
   
   if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size;
 
+  if(MPV_frame_start(s, avctx) < 0)
+      return -1;
+
   /* decode y, u and v components */
   for (i=0; i < 3; i++) {
     int linesize;
@@ -1112,12 +1112,12 @@
       linesize= s->uvlinesize;
     }
 
-    current  = s->current_picture[i];
+    current  = s->current_picture.data[i];
 
     if(s->pict_type==B_TYPE){
-        previous = s->next_picture[i];
+        previous = s->next_picture.data[i];
     }else{
-        previous = s->last_picture[i];
+        previous = s->last_picture.data[i];
     }
 
     if (s->pict_type == I_TYPE) {
@@ -1159,12 +1159,14 @@
 	current += 16*linesize;
       }
     }
+  }
+  
+  *pict = *(AVVideoFrame*)&s->current_picture;
 
-    pict->data[i] = s->current_picture[i];
-    pict->linesize[i] = linesize;
-  }
 
-  *data_size=sizeof(AVPicture);
+  MPV_frame_end(s);
+  
+  *data_size=sizeof(AVVideoFrame);
   return buf_size;
 }
 
@@ -1176,7 +1178,6 @@
     s->width = (avctx->width+3)&~3;
     s->height = (avctx->height+3)&~3;
     s->codec_id= avctx->codec->id;
-    avctx->mbskip_table= s->mbskip_table;
     avctx->pix_fmt = PIX_FMT_YUV410P;
     avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames
     s->flags= avctx->flags;
--- a/utils.c	Tue Dec 03 19:40:35 2002 +0000
+++ b/utils.c	Wed Dec 04 10:04:03 2002 +0000
@@ -86,6 +86,123 @@
     format->next = NULL;
 }
 
+void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift){
+    switch(fmt){
+    case PIX_FMT_YUV410P:
+        *h_shift=2;
+        *v_shift=2;
+        break;
+    case PIX_FMT_YUV420P:
+        *h_shift=1;
+        *v_shift=1;
+        break;
+    case PIX_FMT_YUV411P:
+        *h_shift=2;
+        *v_shift=0;
+        break;
+    case PIX_FMT_YUV422P:
+    case PIX_FMT_YUV422:
+        *h_shift=1;
+        *v_shift=0;
+        break;
+    default: //RGB/...
+        *h_shift=0;
+        *v_shift=0;
+        break;
+    }
+}
+
+typedef struct DefaultPicOpaque{
+    int last_pic_num;
+    uint8_t *data[4];
+}DefaultPicOpaque;
+
+int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic){
+    int i;
+    const int width = s->width;
+    const int height= s->height;
+    DefaultPicOpaque *opaque;
+
+    if(pic->opaque){
+        opaque= (DefaultPicOpaque *)pic->opaque;
+        for(i=0; i<3; i++)
+            pic->data[i]= opaque->data[i];
+
+//    printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num);    
+        pic->age= pic->coded_picture_number - opaque->last_pic_num;
+        opaque->last_pic_num= pic->coded_picture_number;
+//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number);
+    }else{
+        int align, h_chroma_shift, v_chroma_shift;
+        int w, h, pixel_size;
+        
+        avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+        
+        switch(s->pix_fmt){
+        case PIX_FMT_YUV422:
+            pixel_size=2;
+            break;
+        case PIX_FMT_RGB24:
+        case PIX_FMT_BGR24:
+            pixel_size=3;
+            break;
+        case PIX_FMT_BGRA32:
+        case PIX_FMT_RGBA32:
+            pixel_size=4;
+            break;
+        default:
+            pixel_size=1;
+        }
+        
+        if(s->codec_id==CODEC_ID_SVQ1) align=63;
+        else                           align=15;
+    
+        w= (width +align)&~align;
+        h= (height+align)&~align;
+    
+        if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
+            w+= EDGE_WIDTH*2;
+            h+= EDGE_WIDTH*2;
+        }
+        
+        opaque= av_mallocz(sizeof(DefaultPicOpaque));
+        if(opaque==NULL) return -1;
+
+        pic->opaque= opaque;
+        opaque->last_pic_num= -256*256*256*64;
+
+        for(i=0; i<3; i++){
+            int h_shift= i==0 ? 0 : h_chroma_shift;
+            int v_shift= i==0 ? 0 : v_chroma_shift;
+
+            pic->linesize[i]= pixel_size*w>>h_shift;
+
+            pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
+            if(pic->base[i]==NULL) return -1;
+
+            memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift);
+        
+            if(s->flags&CODEC_FLAG_EMU_EDGE)
+                pic->data[i] = pic->base[i];
+            else
+                pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
+            
+            opaque->data[i]= pic->data[i];
+        }
+        pic->age= 256*256*256*64;
+    }
+
+    return 0;
+}
+
+void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic){
+    int i;
+    
+    for(i=0; i<3; i++)
+        pic->data[i]=NULL;
+//printf("R%X\n", pic->opaque);
+}
+
 void avcodec_get_context_defaults(AVCodecContext *s){
     s->bit_rate= 800*1000;
     s->bit_rate_tolerance= s->bit_rate*10;
@@ -104,6 +221,8 @@
     s->frame_rate = 25 * FRAME_RATE_BASE;
     s->gop_size= 50;
     s->me_method= ME_EPZS;
+    s->get_buffer= avcodec_default_get_buffer;
+    s->release_buffer= avcodec_default_release_buffer;
 }
 
 /**
@@ -120,6 +239,16 @@
     return avctx;
 }
 
+/**
+ * allocates a AVPicture and set it to defaults.
+ * this can be deallocated by simply calling free() 
+ */
+AVVideoFrame *avcodec_alloc_picture(void){
+    AVVideoFrame *pic= av_mallocz(sizeof(AVVideoFrame));
+    
+    return pic;
+}
+
 int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
 {
     int ret;
@@ -152,7 +281,7 @@
 }
 
 int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, 
-                         const AVPicture *pict)
+                         const AVVideoFrame *pict)
 {
     int ret;
 
@@ -167,17 +296,17 @@
 /* decode a frame. return -1 if error, otherwise return the number of
    bytes used. If no frame could be decompressed, *got_picture_ptr is
    zero. Otherwise, it is non zero */
-int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, 
+int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture, 
                          int *got_picture_ptr,
                          UINT8 *buf, int buf_size)
 {
     int ret;
-
+    
     ret = avctx->codec->decode(avctx, picture, got_picture_ptr, 
                                buf, buf_size);
 
     emms_c(); //needed to avoid a emms_c() call before every return;
-
+    
     if (*got_picture_ptr)                           
         avctx->frame_number++;
     return ret;