diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 82fd85a88ec8d63c54c8fa861bc35aed52905191..f2e5a1c13fc1a64a99161afc4fcedb2c5d86ed32 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -15,8 +15,8 @@ extern "C" {
 
 #define LIBAVCODEC_VERSION_INT 0x000406
 #define LIBAVCODEC_VERSION     "0.4.6"
-#define LIBAVCODEC_BUILD       4670
-#define LIBAVCODEC_BUILD_STR   "4670"
+#define LIBAVCODEC_BUILD       4671
+#define LIBAVCODEC_BUILD_STR   "4671"
 
 #define LIBAVCODEC_IDENT	"FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR
 
@@ -183,7 +183,7 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
                                             of only at frame boundaries */
 #define CODEC_FLAG_NORMALIZE_AQP  0x00020000 ///< normalize adaptive quantization 
 #define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< use interlaced dct 
-#define CODEC_FLAG_LOW_DELAY      0x00080000 ///< force low delay / will fail on b frames 
+#define CODEC_FLAG_LOW_DELAY      0x00080000 ///< force low delay
 #define CODEC_FLAG_ALT_SCAN       0x00100000 ///< use alternate scan 
 #define CODEC_FLAG_TRELLIS_QUANT  0x00200000 ///< use trellis quantization 
 #define CODEC_FLAG_GLOBAL_HEADER  0x00400000 ///< place global headers in extradata instead of every keyframe 
@@ -471,10 +471,14 @@ typedef struct AVCodecContext {
      * before
      * - encoding: unused
      * - decoding: set by user.
+     * @param height the height of the slice
+     * @param y the y position of the slice
+     * @param type 1->top field, 2->bottom field, 3->frame
+     * @param offset offset into the AVFrame.data from which the slice should be read
      */
     void (*draw_horiz_band)(struct AVCodecContext *s,
                             AVFrame *src, int offset[4],
-                            int y, int width, int height);
+                            int y, int type, int height);
 
     /* audio only */
     int sample_rate; ///< samples per sec 
@@ -669,6 +673,7 @@ typedef struct AVCodecContext {
     /**
      * 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
+     * width and height should be rounded up to the next multiple of 16
      * - encoding: unused
      * - decoding: set by lavc, user can override
      */
@@ -1146,6 +1151,17 @@ typedef struct AVCodecContext {
      * - decoding: unused
      */
     int context_model;
+    
+    /**
+     * slice flags
+     * - encoding: unused
+     * - decoding: set by user.
+     */
+    int slice_flags;
+#define SLICE_FLAG_CODED_ORDER    0x0001 ///< draw_horiz_band() is called in coded order instead of display
+#define SLICE_FLAG_ALLOW_FIELD    0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
+#define SLICE_FLAG_ALLOW_PLANE    0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+
 } AVCodecContext;
 
 
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index 4c8229a3c39822bcecc2c0f14d6222af66f670cb..7970cd34c5e89e38b345647a6f953ac03515a435 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -693,7 +693,7 @@ static void draw_slice(HYuvContext *s, int y){
     offset[3] = 0;
     emms_c();
 
-    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, s->width, h);
+    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
     
     s->last_slice_end= y + h;
 }
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index e5491f3fa7c29fc181f02be2119e3b35894eaa3c..e84fa55133e9a97833315274437c2880cb667aca 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -1943,13 +1943,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
         MPV_decode_mb(s, s->block);
 
         if (++s->mb_x >= s->mb_width) {
-            if(s->picture_structure==PICT_FRAME){
-                ff_draw_horiz_band(s, 16*s->mb_y, 16);
-            }else{
-                if(!s->first_field){
-                    ff_draw_horiz_band(s, 32*s->mb_y, 32);
-                }
-            }
+            ff_draw_horiz_band(s, 16*s->mb_y, 16);
 
             s->mb_x = 0;
             s->mb_y++;
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index d25cc4895f73a7c105aca35ef43c3ff4287ba437..500d076824b464e16f3d1a5ecc1dfeb3c1cb8d7f 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -2726,10 +2726,25 @@ static int pix_diff_vcmp16x8(uint8_t *s1, uint8_t*s2, int stride){ //FIXME move
  */
 void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
     if (s->avctx->draw_horiz_band) {
+        AVFrame *src;
         uint8_t *src_ptr[3];
         int offset[4];
+        
+        if(s->picture_structure != PICT_FRAME){
+            h <<= 1;
+            y <<= 1;
+            if(s->first_field  && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
+        }
+
         h= FFMIN(h, s->height - y);
 
+        if(s->pict_type==B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER)) 
+            src= (AVFrame*)s->current_picture_ptr;
+        else if(s->last_picture_ptr)
+            src= (AVFrame*)s->last_picture_ptr;
+        else
+            return;
+            
         if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
             offset[0]=
             offset[1]=
@@ -2744,8 +2759,8 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
 
         emms_c();
 
-        s->avctx->draw_horiz_band(s->avctx, (AVFrame*)s->current_picture_ptr, offset,
-                               y, s->width, h);
+        s->avctx->draw_horiz_band(s->avctx, src, offset,
+                                  y, s->picture_structure, h);
     }
 }