]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpegvideo.c
mpegvideo: Initialize chroma_*_shift and codec_tag even if the size is 0
[ffmpeg] / libavcodec / mpegvideo.c
index b48640f8fc281d05b86a936b2ddc3a2b197816b0..192e27f21540c24af8043a6bb462096f6c27cde8 100644 (file)
@@ -27,6 +27,7 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
@@ -40,9 +41,6 @@
 #include "thread.h"
 #include <limits.h>
 
-//#undef NDEBUG
-//#include <assert.h>
-
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
                                    int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
@@ -58,13 +56,6 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s,
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
                                   int16_t *block, int n, int qscale);
 
-
-/* enable all paranoid tests for rounding, overflows, etc... */
-//#define PARANOID
-
-//#define DEBUG
-
-
 static const uint8_t ff_default_chroma_qscale_table[32] = {
 //   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
@@ -158,43 +149,11 @@ static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
     ff_MPV_decode_mb(s, s->block);
 }
 
-const uint8_t *avpriv_mpv_find_start_code(const uint8_t *restrict p,
-                                          const uint8_t *end,
-                                          uint32_t * restrict state)
-{
-    int i;
-
-    assert(p <= end);
-    if (p >= end)
-        return end;
-
-    for (i = 0; i < 3; i++) {
-        uint32_t tmp = *state << 8;
-        *state = tmp + *(p++);
-        if (tmp == 0x100 || p == end)
-            return p;
-    }
-
-    while (p < end) {
-        if      (p[-1] > 1      ) p += 3;
-        else if (p[-2]          ) p += 2;
-        else if (p[-3]|(p[-1]-1)) p++;
-        else {
-            p++;
-            break;
-        }
-    }
-
-    p = FFMIN(p, end) - 4;
-    *state = AV_RB32(p);
-
-    return p + 4;
-}
-
 /* init common dct for both encoder and decoder */
 av_cold int ff_dct_common_init(MpegEncContext *s)
 {
     ff_dsputil_init(&s->dsp, s->avctx);
+    ff_hpeldsp_init(&s->hdsp, s->avctx->flags);
     ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
 
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
@@ -206,17 +165,16 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
         s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
     s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
 
-#if ARCH_X86
-    ff_MPV_common_init_x86(s);
-#elif ARCH_ALPHA
-    ff_MPV_common_init_axp(s);
-#elif ARCH_ARM
-    ff_MPV_common_init_arm(s);
-#elif HAVE_ALTIVEC
-    ff_MPV_common_init_altivec(s);
-#elif ARCH_BFIN
-    ff_MPV_common_init_bfin(s);
-#endif
+    if (ARCH_ALPHA)
+        ff_MPV_common_init_axp(s);
+    if (ARCH_ARM)
+        ff_MPV_common_init_arm(s);
+    if (ARCH_BFIN)
+        ff_MPV_common_init_bfin(s);
+    if (ARCH_PPC)
+        ff_MPV_common_init_ppc(s);
+    if (ARCH_X86)
+        ff_MPV_common_init_x86(s);
 
     /* load & permutate scantables
      * note: only wmv uses different ones
@@ -246,7 +204,7 @@ int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize)
     FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer, alloc_size * 2 * 24,
                       fail);
 
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, alloc_size * 2 * 16 * 2,
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, alloc_size * 2 * 16 * 3,
                       fail)
     s->me.temp         = s->me.scratchpad;
     s->rd_scratchpad   = s->me.scratchpad;
@@ -266,17 +224,6 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
 {
     int r, ret;
 
-    if (s->avctx->hwaccel) {
-        assert(!pic->hwaccel_picture_private);
-        if (s->avctx->hwaccel->priv_data_size) {
-            pic->hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size);
-            if (!pic->hwaccel_picture_private) {
-                av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");
-                return -1;
-            }
-        }
-    }
-
     pic->tf.f = &pic->f;
     if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
         s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
@@ -293,10 +240,21 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
     if (r < 0 || !pic->f.data[0]) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",
                r, pic->f.data[0]);
-        av_freep(&pic->hwaccel_picture_private);
         return -1;
     }
 
+    if (s->avctx->hwaccel) {
+        assert(!pic->hwaccel_picture_private);
+        if (s->avctx->hwaccel->priv_data_size) {
+            pic->hwaccel_priv_buf = av_buffer_allocz(s->avctx->hwaccel->priv_data_size);
+            if (!pic->hwaccel_priv_buf) {
+                av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");
+                return -1;
+            }
+            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
+        }
+    }
+
     if (s->linesize && (s->linesize   != pic->f.linesize[0] ||
                         s->uvlinesize != pic->f.linesize[1])) {
         av_log(s->avctx, AV_LOG_ERROR,
@@ -476,6 +434,9 @@ void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic)
 
     av_buffer_unref(&pic->hwaccel_priv_buf);
 
+    if (pic->needs_realloc)
+        free_picture_tables(pic);
+
     memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
 }
 
@@ -1008,16 +969,6 @@ static int init_context_frame(MpegEncContext *s)
     FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail);
     // Note the + 1 is for  a quicker mpeg4 slice_end detection
 
-    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
-        s->avctx->debug_mv) {
-        s->visualization_buffer[0] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-        s->visualization_buffer[1] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-        s->visualization_buffer[2] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-    }
-
     return init_er(s);
 fail:
     return AVERROR(ENOMEM);
@@ -1039,7 +990,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
 
     if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
         s->mb_height = (s->height + 31) / 32 * 2;
-    else if (s->codec_id != AV_CODEC_ID_H264)
+    else
         s->mb_height = (s->height + 15) / 16;
 
     if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {
@@ -1068,17 +1019,17 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
     s->flags  = s->avctx->flags;
     s->flags2 = s->avctx->flags2;
 
-    if (s->width && s->height) {
-        /* set chroma shifts */
-        av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
-                                         &s->chroma_x_shift,
-                                         &s->chroma_y_shift);
+    /* set chroma shifts */
+    av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                     &s->chroma_x_shift,
+                                     &s->chroma_y_shift);
 
-        /* convert fourcc to upper case */
-        s->codec_tag          = avpriv_toupper4(s->avctx->codec_tag);
+    /* convert fourcc to upper case */
+    s->codec_tag          = avpriv_toupper4(s->avctx->codec_tag);
 
-        s->stream_codec_tag   = avpriv_toupper4(s->avctx->stream_codec_tag);
+    s->stream_codec_tag   = avpriv_toupper4(s->avctx->stream_codec_tag);
 
+    if (s->width && s->height) {
         s->avctx->coded_frame = &s->current_picture.f;
 
         if (s->encoding) {
@@ -1213,9 +1164,6 @@ static int free_context_frame(MpegEncContext *s)
 
     s->linesize = s->uvlinesize = 0;
 
-    for (i = 0; i < 3; i++)
-        av_freep(&s->visualization_buffer[i]);
-
     return 0;
 }
 
@@ -1248,7 +1196,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
     // init
     if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
         s->mb_height = (s->height + 31) / 32 * 2;
-    else if (s->codec_id != AV_CODEC_ID_H264)
+    else
         s->mb_height = (s->height + 15) / 16;
 
     if ((s->width || s->height) &&
@@ -1348,8 +1296,8 @@ void ff_MPV_common_end(MpegEncContext *s)
     s->linesize = s->uvlinesize = 0;
 }
 
-void ff_init_rl(RLTable *rl,
-                uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
+av_cold void ff_init_rl(RLTable *rl,
+                        uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
 {
     int8_t  max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1];
     uint8_t index_run[MAX_RUN + 1];
@@ -1400,7 +1348,7 @@ void ff_init_rl(RLTable *rl,
     }
 }
 
-void ff_init_vlc_rl(RLTable *rl)
+av_cold void ff_init_vlc_rl(RLTable *rl)
 {
     int i, q;
 
@@ -1528,29 +1476,29 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     s->mb_skipped = 0;
 
     /* mark & release old frames */
-    if (s->out_format != FMT_H264 || s->codec_id == AV_CODEC_ID_SVQ3) {
-        if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
-            s->last_picture_ptr != s->next_picture_ptr &&
-            s->last_picture_ptr->f.data[0]) {
-            ff_mpeg_unref_picture(s, s->last_picture_ptr);
-        }
+    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
+        s->last_picture_ptr != s->next_picture_ptr &&
+        s->last_picture_ptr->f.data[0]) {
+        ff_mpeg_unref_picture(s, s->last_picture_ptr);
+    }
 
-        /* release forgotten pictures */
-        /* if (mpeg124/h263) */
-        if (!s->encoding) {
-            for (i = 0; i < MAX_PICTURE_COUNT; i++) {
-                if (&s->picture[i] != s->last_picture_ptr &&
-                    &s->picture[i] != s->next_picture_ptr &&
-                    s->picture[i].reference && !s->picture[i].needs_realloc) {
-                    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
-                        av_log(avctx, AV_LOG_ERROR,
-                               "releasing zombie picture\n");
-                    ff_mpeg_unref_picture(s, &s->picture[i]);
-                }
+    /* release forgotten pictures */
+    /* if (mpeg124/h263) */
+    if (!s->encoding) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (&s->picture[i] != s->last_picture_ptr &&
+                &s->picture[i] != s->next_picture_ptr &&
+                s->picture[i].reference && !s->picture[i].needs_realloc) {
+                if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+                    av_log(avctx, AV_LOG_ERROR,
+                           "releasing zombie picture\n");
+                ff_mpeg_unref_picture(s, &s->picture[i]);
             }
         }
     }
 
+    ff_mpeg_unref_picture(s, &s->current_picture);
+
     if (!s->encoding) {
         ff_release_unused_pictures(s, 1);
 
@@ -1570,9 +1518,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
 
         pic->reference = 0;
         if (!s->droppable) {
-            if (s->codec_id == AV_CODEC_ID_H264)
-                pic->reference = s->picture_structure;
-            else if (s->pict_type != AV_PICTURE_TYPE_B)
+            if (s->pict_type != AV_PICTURE_TYPE_B)
                 pic->reference = 3;
         }
 
@@ -1600,12 +1546,11 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;
     s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
-    ff_mpeg_unref_picture(s, &s->current_picture);
     if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
                                    s->current_picture_ptr)) < 0)
         return ret;
 
-    if (s->codec_id != AV_CODEC_ID_H264 && s->pict_type != AV_PICTURE_TYPE_B) {
+    if (s->pict_type != AV_PICTURE_TYPE_B) {
         s->last_picture_ptr = s->next_picture_ptr;
         if (!s->droppable)
             s->next_picture_ptr = s->current_picture_ptr;
@@ -1617,85 +1562,81 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
             s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,
             s->pict_type, s->droppable);
 
-    if (s->codec_id != AV_CODEC_ID_H264) {
-        if ((s->last_picture_ptr == NULL ||
-             s->last_picture_ptr->f.data[0] == NULL) &&
-            (s->pict_type != AV_PICTURE_TYPE_I ||
-             s->picture_structure != PICT_FRAME)) {
-            int h_chroma_shift, v_chroma_shift;
-            av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
-                                             &h_chroma_shift, &v_chroma_shift);
-            if (s->pict_type != AV_PICTURE_TYPE_I)
-                av_log(avctx, AV_LOG_ERROR,
-                       "warning: first frame is no keyframe\n");
-            else if (s->picture_structure != PICT_FRAME)
-                av_log(avctx, AV_LOG_INFO,
-                       "allocate dummy last picture for field based first keyframe\n");
-
-            /* Allocate a dummy frame */
-            i = ff_find_unused_picture(s, 0);
-            if (i < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
-                return i;
-            }
-            s->last_picture_ptr = &s->picture[i];
-            if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
-                s->last_picture_ptr = NULL;
-                return -1;
-            }
-
-            memset(s->last_picture_ptr->f.data[0], 0,
-                   avctx->height * s->last_picture_ptr->f.linesize[0]);
-            memset(s->last_picture_ptr->f.data[1], 0x80,
-                   (avctx->height >> v_chroma_shift) *
-                   s->last_picture_ptr->f.linesize[1]);
-            memset(s->last_picture_ptr->f.data[2], 0x80,
-                   (avctx->height >> v_chroma_shift) *
-                   s->last_picture_ptr->f.linesize[2]);
-
-            ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);
-            ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
+    if ((s->last_picture_ptr == NULL ||
+         s->last_picture_ptr->f.data[0] == NULL) &&
+        (s->pict_type != AV_PICTURE_TYPE_I ||
+         s->picture_structure != PICT_FRAME)) {
+        int h_chroma_shift, v_chroma_shift;
+        av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                         &h_chroma_shift, &v_chroma_shift);
+        if (s->pict_type != AV_PICTURE_TYPE_I)
+            av_log(avctx, AV_LOG_ERROR,
+                   "warning: first frame is no keyframe\n");
+        else if (s->picture_structure != PICT_FRAME)
+            av_log(avctx, AV_LOG_INFO,
+                   "allocate dummy last picture for field based first keyframe\n");
+
+        /* Allocate a dummy frame */
+        i = ff_find_unused_picture(s, 0);
+        if (i < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+            return i;
         }
-        if ((s->next_picture_ptr == NULL ||
-             s->next_picture_ptr->f.data[0] == NULL) &&
-            s->pict_type == AV_PICTURE_TYPE_B) {
-            /* Allocate a dummy frame */
-            i = ff_find_unused_picture(s, 0);
-            if (i < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
-                return i;
-            }
-            s->next_picture_ptr = &s->picture[i];
-            if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
-                s->next_picture_ptr = NULL;
-                return -1;
-            }
-            ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);
-            ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);
+        s->last_picture_ptr = &s->picture[i];
+        if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
+            s->last_picture_ptr = NULL;
+            return -1;
         }
-    }
 
-    if (s->codec_id != AV_CODEC_ID_H264) {
-        if (s->last_picture_ptr) {
-            ff_mpeg_unref_picture(s, &s->last_picture);
-            if (s->last_picture_ptr->f.data[0] &&
-                (ret = ff_mpeg_ref_picture(s, &s->last_picture,
-                                           s->last_picture_ptr)) < 0)
-                return ret;
+        memset(s->last_picture_ptr->f.data[0], 0,
+               avctx->height * s->last_picture_ptr->f.linesize[0]);
+        memset(s->last_picture_ptr->f.data[1], 0x80,
+               (avctx->height >> v_chroma_shift) *
+               s->last_picture_ptr->f.linesize[1]);
+        memset(s->last_picture_ptr->f.data[2], 0x80,
+               (avctx->height >> v_chroma_shift) *
+               s->last_picture_ptr->f.linesize[2]);
+
+        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
+    }
+    if ((s->next_picture_ptr == NULL ||
+         s->next_picture_ptr->f.data[0] == NULL) &&
+        s->pict_type == AV_PICTURE_TYPE_B) {
+        /* Allocate a dummy frame */
+        i = ff_find_unused_picture(s, 0);
+        if (i < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+            return i;
         }
-        if (s->next_picture_ptr) {
-            ff_mpeg_unref_picture(s, &s->next_picture);
-            if (s->next_picture_ptr->f.data[0] &&
-                (ret = ff_mpeg_ref_picture(s, &s->next_picture,
-                                           s->next_picture_ptr)) < 0)
-                return ret;
+        s->next_picture_ptr = &s->picture[i];
+        if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
+            s->next_picture_ptr = NULL;
+            return -1;
         }
+        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);
+    }
 
-        assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
-                                                     s->last_picture_ptr->f.data[0]));
+    if (s->last_picture_ptr) {
+        ff_mpeg_unref_picture(s, &s->last_picture);
+        if (s->last_picture_ptr->f.data[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->last_picture,
+                                       s->last_picture_ptr)) < 0)
+            return ret;
+    }
+    if (s->next_picture_ptr) {
+        ff_mpeg_unref_picture(s, &s->next_picture);
+        if (s->next_picture_ptr->f.data[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->next_picture,
+                                       s->next_picture_ptr)) < 0)
+            return ret;
     }
 
-    if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) {
+    assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
+                                                 s->last_picture_ptr->f.data[0]));
+
+    if (s->picture_structure!= PICT_FRAME) {
         int i;
         for (i = 0; i < 4; i++) {
             if (s->picture_structure == PICT_BOTTOM_FIELD) {
@@ -1746,7 +1687,6 @@ void ff_MPV_frame_end(MpegEncContext *s)
         ff_xvmc_field_end(s);
    } else if ((s->er.error_count || s->encoding) &&
               !s->avctx->hwaccel &&
-              !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
               s->unrestricted_mv &&
               s->current_picture.reference &&
               !s->intra_only &&
@@ -1801,98 +1741,10 @@ void ff_MPV_frame_end(MpegEncContext *s)
 #endif
     s->avctx->coded_frame = &s->current_picture_ptr->f;
 
-    if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.reference)
+    if (s->current_picture.reference)
         ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
 }
 
-/**
- * Draw a line from (ex, ey) -> (sx, sy).
- * @param w width of the image
- * @param h height of the image
- * @param stride stride/linesize of the image
- * @param color color of the arrow
- */
-static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
-                      int w, int h, int stride, int color)
-{
-    int x, y, fr, f;
-
-    sx = av_clip(sx, 0, w - 1);
-    sy = av_clip(sy, 0, h - 1);
-    ex = av_clip(ex, 0, w - 1);
-    ey = av_clip(ey, 0, h - 1);
-
-    buf[sy * stride + sx] += color;
-
-    if (FFABS(ex - sx) > FFABS(ey - sy)) {
-        if (sx > ex) {
-            FFSWAP(int, sx, ex);
-            FFSWAP(int, sy, ey);
-        }
-        buf += sx + sy * stride;
-        ex  -= sx;
-        f    = ((ey - sy) << 16) / ex;
-        for (x = 0; x <= ex; x++) {
-            y  = (x * f) >> 16;
-            fr = (x * f) & 0xFFFF;
-            buf[y * stride + x]       += (color * (0x10000 - fr)) >> 16;
-            buf[(y + 1) * stride + x] += (color *            fr ) >> 16;
-        }
-    } else {
-        if (sy > ey) {
-            FFSWAP(int, sx, ex);
-            FFSWAP(int, sy, ey);
-        }
-        buf += sx + sy * stride;
-        ey  -= sy;
-        if (ey)
-            f  = ((ex - sx) << 16) / ey;
-        else
-            f = 0;
-        for (y = 0; y = ey; y++) {
-            x  = (y * f) >> 16;
-            fr = (y * f) & 0xFFFF;
-            buf[y * stride + x]     += (color * (0x10000 - fr)) >> 16;
-            buf[y * stride + x + 1] += (color *            fr ) >> 16;
-        }
-    }
-}
-
-/**
- * Draw an arrow from (ex, ey) -> (sx, sy).
- * @param w width of the image
- * @param h height of the image
- * @param stride stride/linesize of the image
- * @param color color of the arrow
- */
-static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
-                       int ey, int w, int h, int stride, int color)
-{
-    int dx,dy;
-
-    sx = av_clip(sx, -100, w + 100);
-    sy = av_clip(sy, -100, h + 100);
-    ex = av_clip(ex, -100, w + 100);
-    ey = av_clip(ey, -100, h + 100);
-
-    dx = ex - sx;
-    dy = ey - sy;
-
-    if (dx * dx + dy * dy > 3 * 3) {
-        int rx =  dx + dy;
-        int ry = -dx + dy;
-        int length = ff_sqrt((rx * rx + ry * ry) << 8);
-
-        // FIXME subpixel accuracy
-        rx = ROUNDED_DIV(rx * 3 << 4, length);
-        ry = ROUNDED_DIV(ry * 3 << 4, length);
-
-        draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color);
-        draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color);
-    }
-    draw_line(buf, sx, sy, ex, ey, w, h, stride, color);
-}
-
 /**
  * Print debugging info for the given picture.
  */
@@ -1991,214 +1843,6 @@ void ff_print_debug_info(MpegEncContext *s, Picture *p)
             av_log(s->avctx, AV_LOG_DEBUG, "\n");
         }
     }
-
-    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
-        (s->avctx->debug_mv)) {
-        const int shift = 1 + s->quarter_sample;
-        int mb_y;
-        uint8_t *ptr;
-        int i;
-        int h_chroma_shift, v_chroma_shift, block_height;
-        const int width          = s->avctx->width;
-        const int height         = s->avctx->height;
-        const int mv_sample_log2 = 4 - pict->motion_subsample_log2;
-        const int mv_stride      = (s->mb_width << mv_sample_log2) +
-                                   (s->codec_id == AV_CODEC_ID_H264 ? 0 : 1);
-        s->low_delay = 0; // needed to see the vectors without trashing the buffers
-
-        av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
-                                         &h_chroma_shift, &v_chroma_shift);
-        for (i = 0; i < 3; i++) {
-            memcpy(s->visualization_buffer[i], pict->data[i],
-                   (i == 0) ? pict->linesize[i] * height:
-                              pict->linesize[i] * height >> v_chroma_shift);
-            pict->data[i] = s->visualization_buffer[i];
-        }
-        ptr          = pict->data[0];
-        block_height = 16 >> v_chroma_shift;
-
-        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-            int mb_x;
-            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                const int mb_index = mb_x + mb_y * s->mb_stride;
-                if ((s->avctx->debug_mv) && p->motion_val) {
-                    int type;
-                    for (type = 0; type < 3; type++) {
-                        int direction = 0;
-                        switch (type) {
-                        case 0:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_P))
-                                continue;
-                            direction = 0;
-                            break;
-                        case 1:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_B))
-                                continue;
-                            direction = 0;
-                            break;
-                        case 2:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_B))
-                                continue;
-                            direction = 1;
-                            break;
-                        }
-                        if (!USES_LIST(p->mb_type[mb_index], direction))
-                            continue;
-
-                        if (IS_8X8(p->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 4; i++) {
-                                int sx = mb_x * 16 + 4 + 8 * (i & 1);
-                                int sy = mb_y * 16 + 4 + 8 * (i >> 1);
-                                int xy = (mb_x * 2 + (i & 1) +
-                                          (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = (p->motion_val[direction][xy][0] >> shift) + sx;
-                                int my = (p->motion_val[direction][xy][1] >> shift) + sy;
-                                draw_arrow(ptr, sx, sy, mx, my, width,
-                                           height, s->linesize, 100);
-                            }
-                        } else if (IS_16X8(p->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 2; i++) {
-                                int sx = mb_x * 16 + 8;
-                                int sy = mb_y * 16 + 4 + 8 * i;
-                                int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = (p->motion_val[direction][xy][0] >> shift);
-                                int my = (p->motion_val[direction][xy][1] >> shift);
-
-                                if (IS_INTERLACED(p->mb_type[mb_index]))
-                                    my *= 2;
-
-                            draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                       height, s->linesize, 100);
-                            }
-                        } else if (IS_8X16(p->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 2; i++) {
-                                int sx = mb_x * 16 + 4 + 8 * i;
-                                int sy = mb_y * 16 + 8;
-                                int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = p->motion_val[direction][xy][0] >> shift;
-                                int my = p->motion_val[direction][xy][1] >> shift;
-
-                                if (IS_INTERLACED(p->mb_type[mb_index]))
-                                    my *= 2;
-
-                                draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                           height, s->linesize, 100);
-                            }
-                        } else {
-                              int sx = mb_x * 16 + 8;
-                              int sy = mb_y * 16 + 8;
-                              int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2;
-                              int mx = p->motion_val[direction][xy][0] >> shift + sx;
-                              int my = p->motion_val[direction][xy][1] >> shift + sy;
-                              draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
-                        }
-                    }
-                }
-                if ((s->avctx->debug & FF_DEBUG_VIS_QP) && p->motion_val) {
-                    uint64_t c = (p->qscale_table[mb_index] * 128 / 31) *
-                                 0x0101010101010101ULL;
-                    int y;
-                    for (y = 0; y < block_height; y++) {
-                        *(uint64_t *)(pict->data[1] + 8 * mb_x +
-                                      (block_height * mb_y + y) *
-                                      pict->linesize[1]) = c;
-                        *(uint64_t *)(pict->data[2] + 8 * mb_x +
-                                      (block_height * mb_y + y) *
-                                      pict->linesize[2]) = c;
-                    }
-                }
-                if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
-                    p->motion_val) {
-                    int mb_type = p->mb_type[mb_index];
-                    uint64_t u,v;
-                    int y;
-#define COLOR(theta, r) \
-    u = (int)(128 + r * cos(theta * 3.141592 / 180)); \
-    v = (int)(128 + r * sin(theta * 3.141592 / 180));
-
-
-                    u = v = 128;
-                    if (IS_PCM(mb_type)) {
-                        COLOR(120, 48)
-                    } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) ||
-                               IS_INTRA16x16(mb_type)) {
-                        COLOR(30, 48)
-                    } else if (IS_INTRA4x4(mb_type)) {
-                        COLOR(90, 48)
-                    } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) {
-                        // COLOR(120, 48)
-                    } else if (IS_DIRECT(mb_type)) {
-                        COLOR(150, 48)
-                    } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) {
-                        COLOR(170, 48)
-                    } else if (IS_GMC(mb_type)) {
-                        COLOR(190, 48)
-                    } else if (IS_SKIP(mb_type)) {
-                        // COLOR(180, 48)
-                    } else if (!USES_LIST(mb_type, 1)) {
-                        COLOR(240, 48)
-                    } else if (!USES_LIST(mb_type, 0)) {
-                        COLOR(0, 48)
-                    } else {
-                        assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
-                        COLOR(300,48)
-                    }
-
-                    u *= 0x0101010101010101ULL;
-                    v *= 0x0101010101010101ULL;
-                    for (y = 0; y < block_height; y++) {
-                        *(uint64_t *)(pict->data[1] + 8 * mb_x +
-                                      (block_height * mb_y + y) * pict->linesize[1]) = u;
-                        *(uint64_t *)(pict->data[2] + 8 * mb_x +
-                                      (block_height * mb_y + y) * pict->linesize[2]) = v;
-                    }
-
-                    // segmentation
-                    if (IS_8X8(mb_type) || IS_16X8(mb_type)) {
-                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 +
-                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
-                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 +
-                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
-                    }
-                    if (IS_8X8(mb_type) || IS_8X16(mb_type)) {
-                        for (y = 0; y < 16; y++)
-                            pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) *
-                                          pict->linesize[0]] ^= 0x80;
-                    }
-                    if (IS_8X8(mb_type) && mv_sample_log2 >= 2) {
-                        int dm = 1 << (mv_sample_log2 - 2);
-                        for (i = 0; i < 4; i++) {
-                            int sx = mb_x * 16 + 8 * (i & 1);
-                            int sy = mb_y * 16 + 8 * (i >> 1);
-                            int xy = (mb_x * 2 + (i & 1) +
-                                     (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
-                            // FIXME bidir
-                            int32_t *mv = (int32_t *) &p->motion_val[0][xy];
-                            if (mv[0] != mv[dm] ||
-                                mv[dm * mv_stride] != mv[dm * (mv_stride + 1)])
-                                for (y = 0; y < 8; y++)
-                                    pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80;
-                            if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)])
-                                *(uint64_t *)(pict->data[0] + sx + (sy + 4) *
-                                              pict->linesize[0]) ^= 0x8080808080808080ULL;
-                        }
-                    }
-
-                    if (IS_INTERLACED(mb_type) &&
-                        s->codec_id == AV_CODEC_ID_H264) {
-                        // hmm
-                    }
-                }
-                s->mbskip_table[mb_index] = 0;
-            }
-        }
-    }
 }
 
 /**
@@ -2406,13 +2050,13 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
 
                 op_qpix= s->me.qpel_put;
                 if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
-                    op_pix = s->dsp.put_pixels_tab;
+                    op_pix = s->hdsp.put_pixels_tab;
                 }else{
-                    op_pix = s->dsp.put_no_rnd_pixels_tab;
+                    op_pix = s->hdsp.put_no_rnd_pixels_tab;
                 }
                 if (s->mv_dir & MV_DIR_FORWARD) {
                     ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
-                    op_pix = s->dsp.avg_pixels_tab;
+                    op_pix = s->hdsp.avg_pixels_tab;
                     op_qpix= s->me.qpel_avg;
                 }
                 if (s->mv_dir & MV_DIR_BACKWARD) {
@@ -2532,9 +2176,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
         }
 skip_idct:
         if(!readable){
-            s->dsp.put_pixels_tab[0][0](s->dest[0], dest_y ,   linesize,16);
-            s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
-            s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
+            s->hdsp.put_pixels_tab[0][0](s->dest[0], dest_y ,   linesize,16);
+            s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
+            s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
         }
     }
 }
@@ -2566,7 +2210,6 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
     }
 
     if (!avctx->hwaccel &&
-        !(avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
         draw_edges &&
         cur->reference &&
         !(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
@@ -2607,8 +2250,7 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
             return;
 
         if (cur->f.pict_type == AV_PICTURE_TYPE_B &&
-            picture_structure == PICT_FRAME    &&
-            avctx->codec_id != AV_CODEC_ID_H264  &&
+            picture_structure == PICT_FRAME &&
             avctx->codec_id != AV_CODEC_ID_SVQ3) {
             for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
                 offset[i] = 0;
@@ -2708,6 +2350,10 @@ void ff_mpeg_flush(AVCodecContext *avctx){
         ff_mpeg_unref_picture(s, &s->picture[i]);
     s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
 
+    ff_mpeg_unref_picture(s, &s->current_picture);
+    ff_mpeg_unref_picture(s, &s->last_picture);
+    ff_mpeg_unref_picture(s, &s->next_picture);
+
     s->mb_x= s->mb_y= 0;
 
     s->parse_context.state= -1;