]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpegvideo.c
avutil: add alias names for gray 8/16 colour spaces
[ffmpeg] / libavcodec / mpegvideo.c
index 46754ddc2bced001903f7b9392e3491d5b0b22d8..da425414b610906e61836b8299530e5fe25a40b1 100644 (file)
 #include "libavutil/internal.h"
 #include "libavutil/timer.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "blockdsp.h"
+#include "idctdsp.h"
 #include "internal.h"
 #include "mathops.h"
+#include "mpegutils.h"
 #include "mpegvideo.h"
 #include "mjpegenc.h"
 #include "msmpeg4.h"
+#include "qpeldsp.h"
 #include "xvmc_internal.h"
 #include "thread.h"
 #include <limits.h>
@@ -104,9 +107,26 @@ const uint8_t *const ff_mpeg2_dc_scale_table[4] = {
     mpeg2_dc_scale_table3,
 };
 
-const enum AVPixelFormat ff_pixfmt_list_420[] = {
-    AV_PIX_FMT_YUV420P,
-    AV_PIX_FMT_NONE
+const uint8_t ff_alternate_horizontal_scan[64] = {
+     0,  1,  2,  3,  8,  9, 16, 17,
+    10, 11,  4,  5,  6,  7, 15, 14,
+    13, 12, 19, 18, 24, 25, 32, 33,
+    26, 27, 20, 21, 22, 23, 28, 29,
+    30, 31, 34, 35, 40, 41, 48, 49,
+    42, 43, 36, 37, 38, 39, 44, 45,
+    46, 47, 50, 51, 56, 57, 58, 59,
+    52, 53, 54, 55, 60, 61, 62, 63,
+};
+
+const uint8_t ff_alternate_vertical_scan[64] = {
+     0,  8, 16, 24,  1,  9,  2, 10,
+    17, 25, 32, 40, 48, 56, 57, 49,
+    41, 33, 26, 18,  3, 11,  4, 12,
+    19, 27, 34, 42, 50, 58, 35, 43,
+    51, 59, 20, 28,  5, 13,  6, 14,
+    21, 29, 36, 44, 52, 60, 37, 45,
+    53, 61, 22, 30,  7, 15, 23, 31,
+    38, 46, 54, 62, 39, 47, 55, 63,
 };
 
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
@@ -344,11 +364,11 @@ static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
     ff_init_block_index(s);
     ff_update_block_index(s);
 
-    s->dsp.clear_blocks(s->block[0]);
+    s->bdsp.clear_blocks(s->block[0]);
 
-    s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
-    s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
-    s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
+    s->dest[0] = s->current_picture.f->data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
+    s->dest[1] = s->current_picture.f->data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
+    s->dest[2] = s->current_picture.f->data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
 
     assert(ref == 0);
     ff_MPV_decode_mb(s, s->block);
@@ -357,8 +377,11 @@ static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
 /* 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_blockdsp_init(&s->bdsp, s->avctx);
     ff_hpeldsp_init(&s->hdsp, s->avctx->flags);
+    ff_idctdsp_init(&s->idsp, s->avctx);
+    ff_me_cmp_init(&s->mecc, s->avctx);
+    ff_mpegvideodsp_init(&s->mdsp);
     ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
 
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
@@ -370,6 +393,9 @@ 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 (HAVE_INTRINSICS_NEON)
+        ff_MPV_common_init_neon(s);
+
     if (ARCH_ARM)
         ff_MPV_common_init_arm(s);
     if (ARCH_PPC)
@@ -381,14 +407,14 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
      * note: only wmv uses different ones
      */
     if (s->alternate_scan) {
-        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_alternate_vertical_scan);
-        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_alternate_vertical_scan);
+        ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
+        ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
     } else {
-        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_zigzag_direct);
-        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_zigzag_direct);
+        ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+        ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
     }
-    ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
-    ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+    ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+    ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
 
     return 0;
 }
@@ -426,46 +452,46 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
     int edges_needed = av_codec_is_encoder(s->avctx->codec);
     int r, ret;
 
-    pic->tf.f = &pic->f;
+    pic->tf.f = pic->f;
     if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
         s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
         s->codec_id != AV_CODEC_ID_MSS2) {
         if (edges_needed) {
-            pic->f.width  = s->avctx->width  + 2 * EDGE_WIDTH;
-            pic->f.height = s->avctx->height + 2 * EDGE_WIDTH;
+            pic->f->width  = s->avctx->width  + 2 * EDGE_WIDTH;
+            pic->f->height = s->avctx->height + 2 * EDGE_WIDTH;
         }
 
         r = ff_thread_get_buffer(s->avctx, &pic->tf,
                                  pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
     } else {
-        pic->f.width  = s->avctx->width;
-        pic->f.height = s->avctx->height;
-        pic->f.format = s->avctx->pix_fmt;
-        r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0);
+        pic->f->width  = s->avctx->width;
+        pic->f->height = s->avctx->height;
+        pic->f->format = s->avctx->pix_fmt;
+        r = avcodec_default_get_buffer2(s->avctx, pic->f, 0);
     }
 
-    if (r < 0 || !pic->f.buf[0]) {
+    if (r < 0 || !pic->f->buf[0]) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",
-               r, pic->f.data[0]);
+               r, pic->f->data[0]);
         return -1;
     }
 
     if (edges_needed) {
         int i;
-        for (i = 0; pic->f.data[i]; i++) {
+        for (i = 0; pic->f->data[i]; i++) {
             int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) *
-                         pic->f.linesize[i] +
+                         pic->f->linesize[i] +
                          (EDGE_WIDTH >> (i ? s->chroma_x_shift : 0));
-            pic->f.data[i] += offset;
+            pic->f->data[i] += offset;
         }
-        pic->f.width  = s->avctx->width;
-        pic->f.height = s->avctx->height;
+        pic->f->width  = s->avctx->width;
+        pic->f->height = s->avctx->height;
     }
 
     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 (s->avctx->hwaccel->frame_priv_data_size) {
+            pic->hwaccel_priv_buf = av_buffer_allocz(s->avctx->hwaccel->frame_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;
@@ -474,15 +500,15 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
         }
     }
 
-    if (s->linesize && (s->linesize   != pic->f.linesize[0] ||
-                        s->uvlinesize != pic->f.linesize[1])) {
+    if (s->linesize && (s->linesize   != pic->f->linesize[0] ||
+                        s->uvlinesize != pic->f->linesize[1])) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (stride changed)\n");
         ff_mpeg_unref_picture(s, pic);
         return -1;
     }
 
-    if (pic->f.linesize[1] != pic->f.linesize[2]) {
+    if (pic->f->linesize[1] != pic->f->linesize[2]) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (uv stride mismatch)\n");
         ff_mpeg_unref_picture(s, pic);
@@ -490,7 +516,7 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
     }
 
     if (!s->edge_emu_buffer &&
-        (ret = frame_size_alloc(s, pic->f.linesize[0])) < 0) {
+        (ret = frame_size_alloc(s, pic->f->linesize[0])) < 0) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed to allocate context scratch buffers.\n");
         ff_mpeg_unref_picture(s, pic);
@@ -589,16 +615,16 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
     int i, ret;
 
     if (shared) {
-        assert(pic->f.data[0]);
+        assert(pic->f->data[0]);
         pic->shared = 1;
     } else {
-        assert(!pic->f.buf[0]);
+        assert(!pic->f->buf[0]);
 
         if (alloc_frame_buffer(s, pic) < 0)
             return -1;
 
-        s->linesize   = pic->f.linesize[0];
-        s->uvlinesize = pic->f.linesize[1];
+        s->linesize   = pic->f->linesize[0];
+        s->uvlinesize = pic->f->linesize[1];
     }
 
     if (!pic->qscale_table_buf)
@@ -640,15 +666,15 @@ void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic)
 {
     int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean);
 
-    pic->tf.f = &pic->f;
+    pic->tf.f = pic->f;
     /* WM Image / Screen codecs allocate internal buffers with different
      * dimensions / colorspaces; ignore user-defined callbacks for these. */
     if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
         s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
         s->codec_id != AV_CODEC_ID_MSS2)
         ff_thread_release_buffer(s->avctx, &pic->tf);
-    else
-        av_frame_unref(&pic->f);
+    else if (pic->f)
+        av_frame_unref(pic->f);
 
     av_buffer_unref(&pic->hwaccel_priv_buf);
 
@@ -704,11 +730,11 @@ int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src)
 {
     int ret;
 
-    av_assert0(!dst->f.buf[0]);
-    av_assert0(src->f.buf[0]);
+    av_assert0(!dst->f->buf[0]);
+    av_assert0(src->f->buf[0]);
 
-    src->tf.f = &src->f;
-    dst->tf.f = &dst->f;
+    src->tf.f = src->f;
+    dst->tf.f = dst->f;
     ret = ff_thread_ref_frame(&dst->tf, &src->tf);
     if (ret < 0)
         goto fail;
@@ -906,7 +932,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 
     for (i = 0; i < MAX_PICTURE_COUNT; i++) {
         ff_mpeg_unref_picture(s, &s->picture[i]);
-        if (s1->picture[i].f.buf[0] &&
+        if (s1->picture[i].f->buf[0] &&
             (ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0)
             return ret;
     }
@@ -914,7 +940,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 #define UPDATE_PICTURE(pic)\
 do {\
     ff_mpeg_unref_picture(s, &s->pic);\
-    if (s1->pic.f.buf[0])\
+    if (s1->pic.f->buf[0])\
         ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\
     else\
         ret = update_picture_tables(&s->pic, &s1->pic);\
@@ -981,7 +1007,7 @@ do {\
     if (!s1->first_field) {
         s->last_pict_type = s1->pict_type;
         if (s1->current_picture_ptr)
-            s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality;
+            s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f->quality;
     }
 
     return 0;
@@ -1028,7 +1054,7 @@ static int init_er(MpegEncContext *s)
     int i;
 
     er->avctx       = s->avctx;
-    er->dsp         = &s->dsp;
+    er->mecc        = &s->mecc;
 
     er->mb_index2xy = s->mb_index2xy;
     er->mb_num      = s->mb_num;
@@ -1068,7 +1094,6 @@ static int init_context_frame(MpegEncContext *s)
     s->mb_width   = (s->width + 15) / 16;
     s->mb_stride  = s->mb_width + 1;
     s->b8_stride  = s->mb_width * 2 + 1;
-    s->b4_stride  = s->mb_width * 4 + 1;
     mb_array_size = s->mb_height * s->mb_stride;
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
 
@@ -1256,14 +1281,26 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
     FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
                       MAX_PICTURE_COUNT * sizeof(Picture), fail);
     for (i = 0; i < MAX_PICTURE_COUNT; i++) {
-        av_frame_unref(&s->picture[i].f);
+        s->picture[i].f = av_frame_alloc();
+        if (!s->picture[i].f)
+            goto fail;
     }
     memset(&s->next_picture, 0, sizeof(s->next_picture));
     memset(&s->last_picture, 0, sizeof(s->last_picture));
     memset(&s->current_picture, 0, sizeof(s->current_picture));
-    av_frame_unref(&s->next_picture.f);
-    av_frame_unref(&s->last_picture.f);
-    av_frame_unref(&s->current_picture.f);
+    memset(&s->new_picture, 0, sizeof(s->new_picture));
+    s->next_picture.f = av_frame_alloc();
+    if (!s->next_picture.f)
+        goto fail;
+    s->last_picture.f = av_frame_alloc();
+    if (!s->last_picture.f)
+        goto fail;
+    s->current_picture.f = av_frame_alloc();
+    if (!s->current_picture.f)
+        goto fail;
+    s->new_picture.f = av_frame_alloc();
+    if (!s->new_picture.f)
+        goto fail;
 
     if (s->width && s->height) {
         if (init_context_frame(s))
@@ -1457,15 +1494,22 @@ void ff_MPV_common_end(MpegEncContext *s)
         for (i = 0; i < MAX_PICTURE_COUNT; i++) {
             ff_free_picture_tables(&s->picture[i]);
             ff_mpeg_unref_picture(s, &s->picture[i]);
+            av_frame_free(&s->picture[i].f);
         }
     }
     av_freep(&s->picture);
     ff_free_picture_tables(&s->last_picture);
     ff_mpeg_unref_picture(s, &s->last_picture);
+    av_frame_free(&s->last_picture.f);
     ff_free_picture_tables(&s->current_picture);
     ff_mpeg_unref_picture(s, &s->current_picture);
+    av_frame_free(&s->current_picture.f);
     ff_free_picture_tables(&s->next_picture);
     ff_mpeg_unref_picture(s, &s->next_picture);
+    av_frame_free(&s->next_picture.f);
+    ff_free_picture_tables(&s->new_picture);
+    ff_mpeg_unref_picture(s, &s->new_picture);
+    av_frame_free(&s->new_picture.f);
 
     free_context_frame(s);
 
@@ -1581,7 +1625,7 @@ static void release_unused_pictures(MpegEncContext *s)
 
 static inline int pic_is_unused(MpegEncContext *s, Picture *pic)
 {
-    if (pic->f.buf[0] == NULL)
+    if (pic->f->buf[0] == NULL)
         return 1;
     if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
         return 1;
@@ -1594,7 +1638,7 @@ static int find_unused_picture(MpegEncContext *s, int shared)
 
     if (shared) {
         for (i = 0; i < MAX_PICTURE_COUNT; i++) {
-            if (s->picture[i].f.buf[0] == NULL)
+            if (s->picture[i].f->buf[0] == NULL)
                 return i;
         }
     } else {
@@ -1634,7 +1678,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     /* mark & release old frames */
     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.buf[0]) {
+        s->last_picture_ptr->f->buf[0]) {
         ff_mpeg_unref_picture(s, s->last_picture_ptr);
     }
 
@@ -1656,7 +1700,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     release_unused_pictures(s);
 
     if (s->current_picture_ptr &&
-        s->current_picture_ptr->f.buf[0] == NULL) {
+        s->current_picture_ptr->f->buf[0] == NULL) {
         // we already have a unused image
         // (maybe it was set before reading the header)
         pic = s->current_picture_ptr;
@@ -1675,28 +1719,28 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
             pic->reference = 3;
     }
 
-    pic->f.coded_picture_number = s->coded_picture_number++;
+    pic->f->coded_picture_number = s->coded_picture_number++;
 
     if (ff_alloc_picture(s, pic, 0) < 0)
         return -1;
 
     s->current_picture_ptr = pic;
     // FIXME use only the vars from current_pic
-    s->current_picture_ptr->f.top_field_first = s->top_field_first;
+    s->current_picture_ptr->f->top_field_first = s->top_field_first;
     if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
         s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
         if (s->picture_structure != PICT_FRAME)
-            s->current_picture_ptr->f.top_field_first =
+            s->current_picture_ptr->f->top_field_first =
                 (s->picture_structure == PICT_TOP_FIELD) == s->first_field;
     }
-    s->current_picture_ptr->f.interlaced_frame = !s->progressive_frame &&
+    s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame &&
                                                  !s->progressive_sequence;
     s->current_picture_ptr->field_picture      =  s->picture_structure != PICT_FRAME;
 
-    s->current_picture_ptr->f.pict_type = s->pict_type;
+    s->current_picture_ptr->f->pict_type = s->pict_type;
     // if (s->flags && CODEC_FLAG_QSCALE)
     //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;
-    s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+    s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
     if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
                                    s->current_picture_ptr)) < 0)
@@ -1709,13 +1753,13 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     }
     av_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",
             s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,
-            s->last_picture_ptr    ? s->last_picture_ptr->f.data[0]    : NULL,
-            s->next_picture_ptr    ? s->next_picture_ptr->f.data[0]    : NULL,
-            s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,
+            s->last_picture_ptr    ? s->last_picture_ptr->f->data[0]    : NULL,
+            s->next_picture_ptr    ? s->next_picture_ptr->f->data[0]    : NULL,
+            s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL,
             s->pict_type, s->droppable);
 
     if ((s->last_picture_ptr == NULL ||
-         s->last_picture_ptr->f.buf[0] == NULL) &&
+         s->last_picture_ptr->f->buf[0] == NULL) &&
         (s->pict_type != AV_PICTURE_TYPE_I ||
          s->picture_structure != PICT_FRAME)) {
         int h_chroma_shift, v_chroma_shift;
@@ -1737,27 +1781,27 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         s->last_picture_ptr = &s->picture[i];
 
         s->last_picture_ptr->reference   = 3;
-        s->last_picture_ptr->f.pict_type = AV_PICTURE_TYPE_I;
+        s->last_picture_ptr->f->pict_type = AV_PICTURE_TYPE_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,
+        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,
+               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]);
+               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.buf[0] == NULL) &&
+         s->next_picture_ptr->f->buf[0] == NULL) &&
         s->pict_type == AV_PICTURE_TYPE_B) {
         /* Allocate a dummy frame */
         i = ff_find_unused_picture(s, 0);
@@ -1768,7 +1812,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         s->next_picture_ptr = &s->picture[i];
 
         s->next_picture_ptr->reference   = 3;
-        s->next_picture_ptr->f.pict_type = AV_PICTURE_TYPE_I;
+        s->next_picture_ptr->f->pict_type = AV_PICTURE_TYPE_I;
 
         if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
             s->next_picture_ptr = NULL;
@@ -1780,21 +1824,21 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
 
     if (s->last_picture_ptr) {
         ff_mpeg_unref_picture(s, &s->last_picture);
-        if (s->last_picture_ptr->f.buf[0] &&
+        if (s->last_picture_ptr->f->buf[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.buf[0] &&
+        if (s->next_picture_ptr->f->buf[0] &&
             (ret = ff_mpeg_ref_picture(s, &s->next_picture,
                                        s->next_picture_ptr)) < 0)
             return ret;
     }
 
     if (s->pict_type != AV_PICTURE_TYPE_I &&
-        !(s->last_picture_ptr && s->last_picture_ptr->f.buf[0])) {
+        !(s->last_picture_ptr && s->last_picture_ptr->f->buf[0])) {
         av_log(s, AV_LOG_ERROR,
                "Non-reference picture received and no reference available\n");
         return AVERROR_INVALIDDATA;
@@ -1804,12 +1848,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         int i;
         for (i = 0; i < 4; i++) {
             if (s->picture_structure == PICT_BOTTOM_FIELD) {
-                s->current_picture.f.data[i] +=
-                    s->current_picture.f.linesize[i];
+                s->current_picture.f->data[i] +=
+                    s->current_picture.f->linesize[i];
             }
-            s->current_picture.f.linesize[i] *= 2;
-            s->last_picture.f.linesize[i]    *= 2;
-            s->next_picture.f.linesize[i]    *= 2;
+            s->current_picture.f->linesize[i] *= 2;
+            s->last_picture.f->linesize[i]    *= 2;
+            s->next_picture.f->linesize[i]    *= 2;
         }
     }
 
@@ -1866,7 +1910,7 @@ void ff_print_debug_info(MpegEncContext *s, Picture *p)
     AVFrame *pict;
     if (s->avctx->hwaccel || !p || !p->mb_type)
         return;
-    pict = &p->f;
+    pict = p->f;
 
     if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
         int x,y;
@@ -2001,7 +2045,7 @@ static inline void put_dct(MpegEncContext *s,
                            int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
     s->dct_unquantize_intra(s, block, i, qscale);
-    s->dsp.idct_put (dest, line_size, block);
+    s->idsp.idct_put(dest, line_size, block);
 }
 
 /* add block[] to dest[] */
@@ -2009,7 +2053,7 @@ static inline void add_dct(MpegEncContext *s,
                            int16_t *block, int i, uint8_t *dest, int line_size)
 {
     if (s->block_last_index[i] >= 0) {
-        s->dsp.idct_add (dest, line_size, block);
+        s->idsp.idct_add(dest, line_size, block);
     }
 }
 
@@ -2019,7 +2063,7 @@ static inline void add_dequant_dct(MpegEncContext *s,
     if (s->block_last_index[i] >= 0) {
         s->dct_unquantize_inter(s, block, i, qscale);
 
-        s->dsp.idct_add (dest, line_size, block);
+        s->idsp.idct_add(dest, line_size, block);
     }
 }
 
@@ -2087,7 +2131,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
        av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
        for(i=0; i<6; i++){
            for(j=0; j<64; j++){
-               av_log(s->avctx, AV_LOG_DEBUG, "%5d", block[i][s->dsp.idct_permutation[j]]);
+               av_log(s->avctx, AV_LOG_DEBUG, "%5d",
+                      block[i][s->idsp.idct_permutation[j]]);
            }
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
        }
@@ -2114,8 +2159,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
         int dct_linesize, dct_offset;
         op_pixels_func (*op_pix)[4];
         qpel_mc_func (*op_qpix)[16];
-        const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
-        const int uvlinesize = s->current_picture.f.linesize[1];
+        const int linesize   = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics
+        const int uvlinesize = s->current_picture.f->linesize[1];
         const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band;
         const int block_size = 8;
 
@@ -2173,12 +2218,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
                     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);
+                    ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f->data, op_pix, op_qpix);
                     op_pix = s->hdsp.avg_pixels_tab;
                     op_qpix= s->me.qpel_avg;
                 }
                 if (s->mv_dir & MV_DIR_BACKWARD) {
-                    ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
+                    ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f->data, op_pix, op_qpix);
                 }
             }
 
@@ -2264,29 +2309,29 @@ FF_ENABLE_DEPRECATION_WARNINGS
                     }
                 }
             }else{
-                s->dsp.idct_put(dest_y                          , dct_linesize, block[0]);
-                s->dsp.idct_put(dest_y              + block_size, dct_linesize, block[1]);
-                s->dsp.idct_put(dest_y + dct_offset             , dct_linesize, block[2]);
-                s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]);
+                s->idsp.idct_put(dest_y,                           dct_linesize, block[0]);
+                s->idsp.idct_put(dest_y              + block_size, dct_linesize, block[1]);
+                s->idsp.idct_put(dest_y + dct_offset,              dct_linesize, block[2]);
+                s->idsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]);
 
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
                     if(s->chroma_y_shift){
-                        s->dsp.idct_put(dest_cb, uvlinesize, block[4]);
-                        s->dsp.idct_put(dest_cr, uvlinesize, block[5]);
+                        s->idsp.idct_put(dest_cb, uvlinesize, block[4]);
+                        s->idsp.idct_put(dest_cr, uvlinesize, block[5]);
                     }else{
 
                         dct_linesize = uvlinesize << s->interlaced_dct;
                         dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize * 8;
 
-                        s->dsp.idct_put(dest_cb,              dct_linesize, block[4]);
-                        s->dsp.idct_put(dest_cr,              dct_linesize, block[5]);
-                        s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
-                        s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
+                        s->idsp.idct_put(dest_cb,              dct_linesize, block[4]);
+                        s->idsp.idct_put(dest_cr,              dct_linesize, block[5]);
+                        s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
+                        s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
                         if(!s->chroma_x_shift){//Chroma444
-                            s->dsp.idct_put(dest_cb + 8,              dct_linesize, block[8]);
-                            s->dsp.idct_put(dest_cr + 8,              dct_linesize, block[9]);
-                            s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]);
-                            s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]);
+                            s->idsp.idct_put(dest_cb + 8,              dct_linesize, block[8]);
+                            s->idsp.idct_put(dest_cr + 8,              dct_linesize, block[9]);
+                            s->idsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]);
+                            s->idsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]);
                         }
                     }
                 }//gray
@@ -2310,69 +2355,16 @@ void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]){
         MPV_decode_mb_internal(s, block, 0);
 }
 
-/**
- * @param h is the normal height, this will be reduced automatically if needed for the last row
- */
-void ff_draw_horiz_band(AVCodecContext *avctx,
-                        AVFrame *cur, AVFrame *last,
-                        int y, int h, int picture_structure,
-                        int first_field, int low_delay)
-{
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
-    int vshift = desc->log2_chroma_h;
-    const int field_pic = picture_structure != PICT_FRAME;
-    if(field_pic){
-        h <<= 1;
-        y <<= 1;
-    }
-
-    h = FFMIN(h, avctx->height - y);
-
-    if(field_pic && first_field && !(avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
-
-    if (avctx->draw_horiz_band) {
-        AVFrame *src;
-        int offset[AV_NUM_DATA_POINTERS];
-        int i;
-
-        if (cur->pict_type == AV_PICTURE_TYPE_B || low_delay ||
-           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
-            src = cur;
-        else if (last)
-            src = last;
-        else
-            return;
-
-        if (cur->pict_type == AV_PICTURE_TYPE_B &&
-            picture_structure == PICT_FRAME &&
-            avctx->codec_id != AV_CODEC_ID_SVQ3) {
-            for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-                offset[i] = 0;
-        }else{
-            offset[0]= y * src->linesize[0];
-            offset[1]=
-            offset[2]= (y >> vshift) * src->linesize[1];
-            for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
-                offset[i] = 0;
-        }
-
-        emms_c();
-
-        avctx->draw_horiz_band(avctx, src, offset,
-                               y, picture_structure, h);
-    }
-}
-
 void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
 {
-    ff_draw_horiz_band(s->avctx, &s->current_picture.f,
-                       &s->last_picture.f, y, h, s->picture_structure,
+    ff_draw_horiz_band(s->avctx, s->current_picture.f,
+                       s->last_picture.f, y, h, s->picture_structure,
                        s->first_field, s->low_delay);
 }
 
 void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
-    const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
-    const int uvlinesize = s->current_picture.f.linesize[1];
+    const int linesize   = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics
+    const int uvlinesize = s->current_picture.f->linesize[1];
     const int mb_size= 4;
 
     s->block_index[0]= s->b8_stride*(s->mb_y*2    ) - 2 + s->mb_x*2;
@@ -2383,9 +2375,9 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
     s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
     //block_index is not used by mpeg2, so it is not affected by chroma_format
 
-    s->dest[0] = s->current_picture.f.data[0] + ((s->mb_x - 1) <<  mb_size);
-    s->dest[1] = s->current_picture.f.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
-    s->dest[2] = s->current_picture.f.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
+    s->dest[0] = s->current_picture.f->data[0] + ((s->mb_x - 1) <<  mb_size);
+    s->dest[1] = s->current_picture.f->data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
+    s->dest[2] = s->current_picture.f->data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
 
     if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
     {
@@ -2480,40 +2472,3 @@ void ff_MPV_report_decode_progress(MpegEncContext *s)
     if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
         ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0);
 }
-
-#if CONFIG_ERROR_RESILIENCE
-void ff_mpeg_set_erpic(ERPicture *dst, Picture *src)
-{
-    int i;
-
-    if (!src)
-        return;
-
-    dst->f = &src->f;
-    dst->tf = &src->tf;
-
-    for (i = 0; i < 2; i++) {
-        dst->motion_val[i] = src->motion_val[i];
-        dst->ref_index[i] = src->ref_index[i];
-    }
-
-    dst->mb_type = src->mb_type;
-    dst->field_picture = src->field_picture;
-}
-
-void ff_mpeg_er_frame_start(MpegEncContext *s)
-{
-    ERContext *er = &s->er;
-
-    ff_mpeg_set_erpic(&er->cur_pic, s->current_picture_ptr);
-    ff_mpeg_set_erpic(&er->next_pic, s->next_picture_ptr);
-    ff_mpeg_set_erpic(&er->last_pic, s->last_picture_ptr);
-
-    er->pp_time           = s->pp_time;
-    er->pb_time           = s->pb_time;
-    er->quarter_sample    = s->quarter_sample;
-    er->partitioned_frame = s->partitioned_frame;
-
-    ff_er_frame_start(er);
-}
-#endif /* CONFIG_ERROR_RESILIENCE */