h264: deMpegEncContextize
authorAnton Khirnov <anton@khirnov.net>
Sun, 3 Feb 2013 10:10:05 +0000 (11:10 +0100)
committerAnton Khirnov <anton@khirnov.net>
Fri, 15 Feb 2013 15:35:16 +0000 (16:35 +0100)
Most of the changes are just trivial are just trivial replacements of
fields from MpegEncContext with equivalent fields in H264Context.
Everything in h264* other than h264.c are those trivial changes.

The nontrivial parts are:
1) extracting a simplified version of the frame management code from
   mpegvideo.c. We don't need last/next_picture anymore, since h264 uses
   its own more complex system already and those were set only to appease
   the mpegvideo parts.
2) some tables that need to be allocated/freed in appropriate places.
3) hwaccels -- mostly trivial replacements.
   for dxva, the draw_horiz_band() call is moved from
   ff_dxva2_common_end_frame() to per-codec end_frame() callbacks,
   because it's now different for h264 and MpegEncContext-based
   decoders.
4) svq3 -- it does not use h264 complex reference system, so I just
   added some very simplistic frame management instead and dropped the
   use of ff_h264_frame_start(). Because of this I also had to move some
   initialization code to svq3.

Additional fixes for chroma format and bit depth changes by
Janne Grunau <janne-libav@jannau.net>

Signed-off-by: Anton Khirnov <anton@khirnov.net>
34 files changed:
libavcodec/dxva2.c
libavcodec/dxva2_h264.c
libavcodec/dxva2_internal.h
libavcodec/dxva2_mpeg2.c
libavcodec/dxva2_vc1.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_direct.c
libavcodec/h264_loopfilter.c
libavcodec/h264_mb_template.c
libavcodec/h264_mc_template.c
libavcodec/h264_mvpred.h
libavcodec/h264_parser.c
libavcodec/h264_ps.c
libavcodec/h264_refs.c
libavcodec/h264_sei.c
libavcodec/h264pred.c
libavcodec/mpegvideo.h
libavcodec/svq3.c
libavcodec/vaapi.c
libavcodec/vaapi_h264.c
libavcodec/vaapi_internal.h
libavcodec/vaapi_mpeg2.c
libavcodec/vaapi_mpeg4.c
libavcodec/vaapi_vc1.c
libavcodec/vda_h264.c
libavcodec/vdpau.c
libavcodec/vdpau_h264.c
libavcodec/vdpau_internal.h
libavcodec/vdpau_mpeg12.c
libavcodec/vdpau_mpeg4.c
libavcodec/vdpau_vc1.c

index 63addb7..bc43cae 100644 (file)
@@ -76,7 +76,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
     return result;
 }
 
-int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
+int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
@@ -90,7 +90,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
     int      result;
 
     if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
-                                               ff_dxva2_get_surface(s->current_picture_ptr),
+                                               ff_dxva2_get_surface(pic),
                                                NULL))) {
         av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
         return -1;
@@ -146,7 +146,5 @@ end:
         result = -1;
     }
 
-    if (!result)
-        ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
     return result;
 }
index 2fd0767..7009d6c 100644 (file)
@@ -44,15 +44,14 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
 static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
                                     DXVA_PicParams_H264 *pp)
 {
-    const MpegEncContext *s = &h->s;
-    const Picture *current_picture = s->current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     int i, j;
 
     memset(pp, 0, sizeof(*pp));
     /* Configure current picture */
     fill_picture_entry(&pp->CurrPic,
                        ff_dxva2_get_surface_index(ctx, current_picture),
-                       s->picture_structure == PICT_BOTTOM_FIELD);
+                       h->picture_structure == PICT_BOTTOM_FIELD);
     /* Configure the set of references */
     pp->UsedForReferenceFlags  = 0;
     pp->NonExistingFrameFlags  = 0;
@@ -88,13 +87,13 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
         }
     }
 
-    pp->wFrameWidthInMbsMinus1        = s->mb_width  - 1;
-    pp->wFrameHeightInMbsMinus1       = s->mb_height - 1;
+    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
+    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
     pp->num_ref_frames                = h->sps.ref_frame_count;
 
-    pp->wBitFields                    = ((s->picture_structure != PICT_FRAME) <<  0) |
+    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) <<  0) |
                                         ((h->sps.mb_aff &&
-                                        (s->picture_structure == PICT_FRAME)) <<  1) |
+                                        (h->picture_structure == PICT_FRAME)) <<  1) |
                                         (h->sps.residual_color_transform_flag <<  2) |
                                         /* sp_for_switch_flag (not implemented by Libav) */
                                         (0                                    <<  3) |
@@ -120,11 +119,11 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
         pp->Reserved16Bits            = 3; /* FIXME is there a way to detect the right mode ? */
     pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
     pp->CurrFieldOrderCnt[0] = 0;
-    if ((s->picture_structure & PICT_TOP_FIELD) &&
+    if ((h->picture_structure & PICT_TOP_FIELD) &&
         current_picture->field_poc[0] != INT_MAX)
         pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
     pp->CurrFieldOrderCnt[1] = 0;
-    if ((s->picture_structure & PICT_BOTTOM_FIELD) &&
+    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&
         current_picture->field_poc[1] != INT_MAX)
         pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
     pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
@@ -200,7 +199,6 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const MpegEncContext *s = &h->s;
     unsigned list;
 
     memset(slice, 0, sizeof(*slice));
@@ -208,9 +206,9 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
     slice->SliceBytesInBuffer    = size;
     slice->wBadSliceChopping     = 0;
 
-    slice->first_mb_in_slice     = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
+    slice->first_mb_in_slice     = (h->mb_y >> FIELD_OR_MBAFF_PICTURE) * h->mb_width + h->mb_x;
     slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices */
-    slice->BitOffsetToSliceData  = get_bits_count(&s->gb);
+    slice->BitOffsetToSliceData  = get_bits_count(&h->gb);
     slice->slice_type            = ff_h264_get_slice_type(h);
     if (h->slice_type_fixed)
         slice->slice_type += 5;
@@ -260,7 +258,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
         }
     }
     slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
-    slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
+    slice->slice_qp_delta    = h->qscale - h->pps.init_qp;
     slice->redundant_pic_cnt = h->redundant_pic_count;
     if (h->slice_type == AV_PICTURE_TYPE_B)
         slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
@@ -277,10 +275,9 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
                                              DXVA2_DecodeBufferDesc *sc)
 {
     const H264Context *h = avctx->priv_data;
-    const MpegEncContext *s = &h->s;
-    const unsigned mb_count = s->mb_width * s->mb_height;
+    const unsigned mb_count = h->mb_width * h->mb_height;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
     DXVA_Slice_H264_Short *slice = NULL;
     uint8_t  *dxva_data, *current, *end;
@@ -376,7 +373,7 @@ static int start_frame(AVCodecContext *avctx,
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->f.hwaccel_picture_private;
 
     if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
         return -1;
@@ -399,7 +396,7 @@ static int decode_slice(AVCodecContext *avctx,
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
     unsigned position;
 
@@ -427,16 +424,19 @@ static int decode_slice(AVCodecContext *avctx,
 static int end_frame(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *s = &h->s;
     struct dxva2_picture_context *ctx_pic =
-        h->s.current_picture_ptr->f.hwaccel_picture_private;
+        h->cur_pic_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_h264_dxva2_hwaccel = {
index e2305b1..a81cfbe 100644 (file)
@@ -47,7 +47,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
                            unsigned mb_count);
 
 
-int ff_dxva2_common_end_frame(AVCodecContext *, MpegEncContext *,
+int ff_dxva2_common_end_frame(AVCodecContext *, Picture *,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
index fa6ae7b..e247731 100644 (file)
@@ -251,13 +251,17 @@ static int end_frame(AVCodecContext *avctx)
     struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
         s->current_picture_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(s, 0, avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
index 5aed2f3..0767055 100644 (file)
@@ -254,14 +254,18 @@ static int end_frame(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->bitstream_size <= 0)
         return -1;
 
-    return ff_dxva2_common_end_frame(avctx, &v->s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     NULL, 0,
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    NULL, 0,
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
+    return ret;
 }
 
 #if CONFIG_WMV3_DXVA2_HWACCEL
index b5efde0..79e4b0b 100644 (file)
@@ -83,11 +83,10 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
                               int mb_x, int mb_y, int mb_intra, int mb_skipped)
 {
     H264Context    *h = opaque;
-    MpegEncContext *s = &h->s;
 
-    s->mb_x  = mb_x;
-    s->mb_y  = mb_y;
-    h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+    h->mb_x  = mb_x;
+    h->mb_y  = mb_y;
+    h->mb_xy = mb_x + mb_y * h->mb_stride;
     memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
     assert(ref >= 0);
     /* FIXME: It is possible albeit uncommon that slice references
@@ -96,22 +95,179 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
      * practice then correct remapping should be added. */
     if (ref >= h->ref_count[0])
         ref = 0;
-    fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
+    fill_rectangle(&h->cur_pic.f.ref_index[0][4 * h->mb_xy],
                    2, 2, 2, ref, 1);
     fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
     fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
-                   pack16to32(s->mv[0][0][0], s->mv[0][0][1]), 4);
+                   pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
     assert(!FRAME_MBAFF);
     ff_h264_hl_decode_mb(h);
 }
 
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
+{
+    ff_draw_horiz_band(h->avctx, &h->dsp, &h->cur_pic,
+                       h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
+                       y, height, h->picture_structure, h->first_field, 1,
+                       h->low_delay, h->mb_height * 16, h->mb_width * 16);
+}
+
+static void free_frame_buffer(H264Context *h, Picture *pic)
+{
+    ff_thread_release_buffer(h->avctx, &pic->f);
+    av_freep(&pic->f.hwaccel_picture_private);
+}
+
+static void free_picture(H264Context *h, Picture *pic)
+{
+    int i;
+
+    if (pic->f.data[0])
+        free_frame_buffer(h, pic);
+
+    av_freep(&pic->qscale_table_base);
+    pic->f.qscale_table = NULL;
+    av_freep(&pic->mb_type_base);
+    pic->f.mb_type = NULL;
+    for (i = 0; i < 2; i++) {
+        av_freep(&pic->motion_val_base[i]);
+        av_freep(&pic->f.ref_index[i]);
+        pic->f.motion_val[i] = NULL;
+    }
+}
+
+static void release_unused_pictures(H264Context *h, int remove_current)
+{
+    int i;
+
+    /* release non reference frames */
+    for (i = 0; i < h->picture_count; i++) {
+        if (h->DPB[i].f.data[0] && !h->DPB[i].f.reference &&
+            (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) &&
+            (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
+            free_frame_buffer(h, &h->DPB[i]);
+        }
+    }
+}
+
+static int alloc_scratch_buffers(H264Context *h, int linesize)
+{
+    int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
+
+    if (h->bipred_scratchpad)
+        return 0;
+
+    h->bipred_scratchpad = av_malloc(16 * 6 * alloc_size);
+    // edge emu needs blocksize + filter length - 1
+    // (= 21x21 for  h264)
+    h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 21);
+    h->me.scratchpad   = av_mallocz(alloc_size * 2 * 16 * 2);
+
+    if (!h->bipred_scratchpad || !h->edge_emu_buffer || !h->me.scratchpad) {
+        av_freep(&h->bipred_scratchpad);
+        av_freep(&h->edge_emu_buffer);
+        av_freep(&h->me.scratchpad);
+        return AVERROR(ENOMEM);
+    }
+
+    h->me.temp = h->me.scratchpad;
+
+    return 0;
+}
+
+static int alloc_picture(H264Context *h, Picture *pic)
+{
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+    const int mb_array_size = h->mb_stride * h->mb_height;
+    const int b4_stride     = h->mb_width * 4 + 1;
+    const int b4_array_size = b4_stride * h->mb_height * 4;
+    int i, ret = 0;
+
+    av_assert0(!pic->f.data[0]);
+
+    if (h->avctx->hwaccel) {
+        const AVHWAccel *hwaccel = h->avctx->hwaccel;
+        av_assert0(!pic->f.hwaccel_picture_private);
+        if (hwaccel->priv_data_size) {
+            pic->f.hwaccel_picture_private = av_mallocz(hwaccel->priv_data_size);
+            if (!pic->f.hwaccel_picture_private)
+                return AVERROR(ENOMEM);
+        }
+    }
+    ret = ff_thread_get_buffer(h->avctx, &pic->f);
+    if (ret < 0)
+        goto fail;
+
+    h->linesize   = pic->f.linesize[0];
+    h->uvlinesize = pic->f.linesize[1];
+
+    if (pic->f.qscale_table == NULL) {
+        FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base,
+                          (big_mb_num + h->mb_stride) * sizeof(uint8_t),
+                          fail)
+        FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base,
+                          (big_mb_num + h->mb_stride) * sizeof(uint32_t),
+                          fail)
+        pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
+        pic->f.qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
+
+        for (i = 0; i < 2; i++) {
+            FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i],
+                              2 * (b4_array_size + 4) * sizeof(int16_t),
+                              fail)
+            pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+            FF_ALLOCZ_OR_GOTO(h->avctx, pic->f.ref_index[i],
+                              4 * mb_array_size * sizeof(uint8_t), fail)
+        }
+        pic->f.motion_subsample_log2 = 2;
+
+        pic->f.qstride = h->mb_stride;
+    }
+
+    pic->owner2 = h;
+
+    return 0;
+fail:
+    free_frame_buffer(h, pic);
+    return (ret < 0) ? ret : AVERROR(ENOMEM);
+}
+
+static inline int pic_is_unused(H264Context *h, Picture *pic)
+{
+    if (pic->f.data[0] == NULL)
+        return 1;
+    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
+        if (!pic->owner2 || pic->owner2 == h)
+            return 1;
+    return 0;
+}
+
+static int find_unused_picture(H264Context *h)
+{
+    int i;
+
+    for (i = h->picture_range_start; i < h->picture_range_end; i++) {
+        if (pic_is_unused(h, &h->DPB[i]))
+            break;
+    }
+    if (i == h->picture_range_end)
+        return AVERROR_INVALIDDATA;
+
+    if (h->DPB[i].needs_realloc) {
+        h->DPB[i].needs_realloc = 0;
+        free_picture(h, &h->DPB[i]);
+        avcodec_get_frame_defaults(&h->DPB[i].f);
+    }
+
+    return i;
+}
+
 /**
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
  */
 int ff_h264_check_intra4x4_pred_mode(H264Context *h)
 {
-    MpegEncContext *const s     = &h->s;
     static const int8_t top[12] = {
         -1, 0, LEFT_DC_PRED, -1, -1, -1, -1, -1, 0
     };
@@ -124,9 +280,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
         for (i = 0; i < 4; i++) {
             int status = top[h->intra4x4_pred_mode_cache[scan8[0] + i]];
             if (status < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "top block unavailable for requested intra4x4 mode %d at %d %d\n",
-                       status, s->mb_x, s->mb_y);
+                       status, h->mb_x, h->mb_y);
                 return -1;
             } else if (status) {
                 h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
@@ -140,9 +296,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
             if (!(h->left_samples_available & mask[i])) {
                 int status = left[h->intra4x4_pred_mode_cache[scan8[0] + 8 * i]];
                 if (status < 0) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "left block unavailable for requested intra4x4 mode %d at %d %d\n",
-                           status, s->mb_x, s->mb_y);
+                           status, h->mb_x, h->mb_y);
                     return -1;
                 } else if (status) {
                     h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
@@ -159,23 +315,22 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
  */
 int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
 {
-    MpegEncContext *const s     = &h->s;
     static const int8_t top[7]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
     static const int8_t left[7] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 };
 
     if (mode > 6U) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "out of range intra chroma pred mode at %d %d\n",
-               s->mb_x, s->mb_y);
+               h->mb_x, h->mb_y);
         return -1;
     }
 
     if (!(h->top_samples_available & 0x8000)) {
         mode = top[mode];
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "top block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
+                   h->mb_x, h->mb_y);
             return -1;
         }
     }
@@ -189,9 +344,9 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
                    2 * (mode == DC_128_PRED8x8);
         }
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "left block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
+                   h->mb_x, h->mb_y);
             return -1;
         }
     }
@@ -314,7 +469,7 @@ static int decode_rbsp_trailing(H264Context *h, const uint8_t *src)
     int v = *src;
     int r;
 
-    tprintf(h->s.avctx, "rbsp trailing %X\n", v);
+    tprintf(h->avctx, "rbsp trailing %X\n", v);
 
     for (r = 1; r < 9; r++) {
         if (v & 1)
@@ -341,10 +496,9 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
                                      int height, int y_offset, int list0,
                                      int list1, int *nrefs)
 {
-    MpegEncContext *const s = &h->s;
     int my;
 
-    y_offset += 16 * (s->mb_y >> MB_FIELD);
+    y_offset += 16 * (h->mb_y >> MB_FIELD);
 
     if (list0) {
         int ref_n    = h->ref_cache[0][scan8[n]];
@@ -353,8 +507,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         // Error resilience puts the current picture in the ref list.
         // Don't try to wait on these as it will cause a deadlock.
         // Fields can wait on each other, though.
-        if (ref->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+            (ref->f.reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
                 nrefs[0] += 1;
@@ -366,8 +520,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         int ref_n    = h->ref_cache[1][scan8[n]];
         Picture *ref = &h->ref_list[1][ref_n];
 
-        if (ref->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+            (ref->f.reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
             if (refs[1][ref_n] < 0)
                 nrefs[1] += 1;
@@ -383,9 +537,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
  */
 static void await_references(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     int refs[2][48];
     int nrefs[2] = { 0 };
     int ref, list;
@@ -459,7 +612,7 @@ static void await_references(H264Context *h)
                 Picture *ref_pic      = &h->ref_list[list][ref];
                 int ref_field         = ref_pic->f.reference - 1;
                 int ref_field_picture = ref_pic->field_picture;
-                int pic_height        = 16 * s->mb_height >> ref_field_picture;
+                int pic_height        = 16 * h->mb_height >> ref_field_picture;
 
                 row <<= MB_MBAFF;
                 nrefs[list]--;
@@ -500,7 +653,6 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
                                          h264_chroma_mc_func chroma_op,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;
     int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;
     const int luma_xy = (mx & 3) + ((my & 3) << 2);
@@ -512,8 +664,8 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     int emu = 0;
     const int full_mx    = mx >> 2;
     const int full_my    = my >> 2;
-    const int pic_width  = 16 * s->mb_width;
-    const int pic_height = 16 * s->mb_height >> MB_FIELD;
+    const int pic_width  = 16 * h->mb_width;
+    const int pic_height = 16 * h->mb_height >> MB_FIELD;
     int ysh;
 
     if (mx & 7)
@@ -525,12 +677,12 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
         full_my                <          0 - extra_height ||
         full_mx + 16 /*FIXME*/ > pic_width  + extra_width  ||
         full_my + 16 /*FIXME*/ > pic_height + extra_height) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                  src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
                                  h->mb_linesize,
                                  16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,
                                  full_my - 2, pic_width, pic_height);
-        src_y = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         emu   = 1;
     }
 
@@ -538,19 +690,19 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     if (!square)
         qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);
 
-    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)
         return;
 
     if (chroma_idc == 3 /* yuv444 */) {
         src_cb = pic->f.data[1] + offset;
         if (emu) {
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                      src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
                                      h->mb_linesize,
                                      16 + 5, 16 + 5 /*FIXME*/,
                                      full_mx - 2, full_my - 2,
                                      pic_width, pic_height);
-            src_cb = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -558,13 +710,13 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
 
         src_cr = pic->f.data[2] + offset;
         if (emu) {
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                      src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
                                      h->mb_linesize,
                                      16 + 5, 16 + 5 /*FIXME*/,
                                      full_mx - 2, full_my - 2,
                                      pic_width, pic_height);
-            src_cr = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -575,7 +727,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     ysh = 3 - (chroma_idc == 2 /* yuv422 */);
     if (chroma_idc == 1 /* yuv420 */ && MB_FIELD) {
         // chroma offset when predicting from a field of opposite parity
-        my  += 2 * ((s->mb_y & 1) - (pic->f.reference - 1));
+        my  += 2 * ((h->mb_y & 1) - (pic->f.reference - 1));
         emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);
     }
 
@@ -585,20 +737,20 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
              (my >> ysh) * h->mb_uvlinesize;
 
     if (emu) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_uvlinesize,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,
                                  9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
                                  pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cb = s->edge_emu_buffer;
+        src_cb = h->edge_emu_buffer;
     }
     chroma_op(dest_cb, src_cb, h->mb_uvlinesize,
               height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
 
     if (emu) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_uvlinesize,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,
                                  9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
                                  pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cr = s->edge_emu_buffer;
+        src_cr = h->edge_emu_buffer;
     }
     chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
@@ -616,7 +768,6 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square,
                                          int list0, int list1,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s       = &h->s;
     qpel_mc_func *qpix_op         = qpix_put;
     h264_chroma_mc_func chroma_op = chroma_put;
 
@@ -631,8 +782,8 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square,
         dest_cb += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD);
 
     if (list0) {
         Picture *ref = &h->ref_list[0][h->ref_cache[0][scan8[n]]];
@@ -666,7 +817,6 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
                                               int list0, int list1,
                                               int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     int chroma_height;
 
     dest_y += (2 * x_offset << pixel_shift) + 2 * y_offset * h->mb_linesize;
@@ -685,8 +835,8 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
         dest_cb      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD);
 
     if (list0 && list1) {
         /* don't optimize for luma-only case, since B-frames usually
@@ -707,7 +857,7 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
                     pixel_shift, chroma_idc);
 
         if (h->use_weight == 2) {
-            int weight0 = h->implicit_weight[refn0][refn1][s->mb_y & 1];
+            int weight0 = h->implicit_weight[refn0][refn1][h->mb_y & 1];
             int weight1 = 64 - weight0;
             luma_weight_avg(dest_y, tmp_y, h->mb_linesize,
                             height, 5, weight0, weight1, 0);
@@ -765,24 +915,23 @@ static av_always_inline void prefetch_motion(H264Context *h, int list,
 {
     /* fetch pixels for estimated mv 4 macroblocks ahead
      * optimized for 64byte cache lines */
-    MpegEncContext *const s = &h->s;
     const int refn = h->ref_cache[list][scan8[0]];
     if (refn >= 0) {
-        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * s->mb_x + 8;
-        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * s->mb_y;
+        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8;
+        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y;
         uint8_t **src = h->ref_list[list][refn].f.data;
         int off       = (mx << pixel_shift) +
-                        (my + (s->mb_x & 3) * 4) * h->mb_linesize +
+                        (my + (h->mb_x & 3) * 4) * h->mb_linesize +
                         (64 << pixel_shift);
-        s->vdsp.prefetch(src[0] + off, s->linesize, 4);
+        h->vdsp.prefetch(src[0] + off, h->linesize, 4);
         if (chroma_idc == 3 /* yuv444 */) {
-            s->vdsp.prefetch(src[1] + off, s->linesize, 4);
-            s->vdsp.prefetch(src[2] + off, s->linesize, 4);
+            h->vdsp.prefetch(src[1] + off, h->linesize, 4);
+            h->vdsp.prefetch(src[2] + off, h->linesize, 4);
         } else {
             off = ((mx >> 1) << pixel_shift) +
-                  ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize +
+                  ((my >> 1) + (h->mb_x & 7)) * h->uvlinesize +
                   (64 << pixel_shift);
-            s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
+            h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
         }
     }
 }
@@ -806,6 +955,18 @@ static void free_tables(H264Context *h, int free_rbsp)
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2br_xy);
 
+    if (free_rbsp) {
+        for (i = 0; i < h->picture_count && !h->avctx->internal->is_copy; i++)
+            free_picture(h, &h->DPB[i]);
+        av_freep(&h->DPB);
+        h->picture_count = 0;
+    } else if (h->DPB) {
+        for (i = 0; i < h->picture_count; i++)
+            h->DPB[i].needs_realloc = 1;
+    }
+
+    h->cur_pic_ptr = NULL;
+
     for (i = 0; i < MAX_THREADS; i++) {
         hx = h->thread_context[i];
         if (!hx)
@@ -813,6 +974,15 @@ static void free_tables(H264Context *h, int free_rbsp)
         av_freep(&hx->top_borders[1]);
         av_freep(&hx->top_borders[0]);
         av_freep(&hx->bipred_scratchpad);
+        av_freep(&hx->edge_emu_buffer);
+        av_freep(&hx->dc_val_base);
+        av_freep(&hx->me.scratchpad);
+        av_freep(&hx->er.mb_index2xy);
+        av_freep(&hx->er.error_status_table);
+        av_freep(&hx->er.er_temp_buffer);
+        av_freep(&hx->er.mbintra_table);
+        av_freep(&hx->er.mbskip_table);
+
         if (free_rbsp) {
             av_freep(&hx->rbsp_buffer[1]);
             av_freep(&hx->rbsp_buffer[0]);
@@ -896,50 +1066,59 @@ static void init_dequant_tables(H264Context *h)
 
 int ff_h264_alloc_tables(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int big_mb_num    = s->mb_stride * (s->mb_height + 1);
-    const int row_mb_num    = s->mb_stride * 2 * s->avctx->thread_count;
-    int x, y;
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1);
+    const int row_mb_num    = h->mb_stride * 2 * h->avctx->thread_count;
+    int x, y, i;
 
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
                       row_mb_num * 8 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
                       big_mb_num * 48 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base,
-                      (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
+                      (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table,
                       big_mb_num * sizeof(uint16_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table,
                       big_mb_num * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[0],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[1],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table,
                       4 * big_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts,
                       big_mb_num * sizeof(uint8_t), fail)
 
     memset(h->slice_table_base, -1,
-           (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base));
-    h->slice_table = h->slice_table_base + s->mb_stride * 2 + 1;
+           (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base));
+    h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1;
 
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2br_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    for (y = 0; y < s->mb_height; y++)
-        for (x = 0; x < s->mb_width; x++) {
-            const int mb_xy = x + y * s->mb_stride;
+    for (y = 0; y < h->mb_height; y++)
+        for (x = 0; x < h->mb_width; x++) {
+            const int mb_xy = x + y * h->mb_stride;
             const int b_xy  = 4 * x + 4 * y * h->b_stride;
 
             h->mb2b_xy[mb_xy]  = b_xy;
-            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * s->mb_stride)));
+            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * h->mb_stride)));
         }
 
     if (!h->dequant4_coeff[0])
         init_dequant_tables(h);
 
+    if (!h->DPB) {
+        h->picture_count = MAX_PICTURE_COUNT * FFMAX(1, h->avctx->thread_count);
+        h->DPB = av_mallocz_array(h->picture_count, sizeof(*h->DPB));
+        if (!h->DPB)
+            return AVERROR(ENOMEM);
+        for (i = 0; i < h->picture_count; i++)
+            avcodec_get_frame_defaults(&h->DPB[i].f);
+        avcodec_get_frame_defaults(&h->cur_pic.f);
+    }
+
     return 0;
 
 fail:
@@ -952,20 +1131,24 @@ fail:
  */
 static void clone_tables(H264Context *dst, H264Context *src, int i)
 {
-    MpegEncContext *const s     = &src->s;
-    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * s->mb_stride;
+    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * src->mb_stride;
     dst->non_zero_count         = src->non_zero_count;
     dst->slice_table            = src->slice_table;
     dst->cbp_table              = src->cbp_table;
     dst->mb2b_xy                = src->mb2b_xy;
     dst->mb2br_xy               = src->mb2br_xy;
     dst->chroma_pred_mode_table = src->chroma_pred_mode_table;
-    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * s->mb_stride;
-    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * s->mb_stride;
+    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * src->mb_stride;
+    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * src->mb_stride;
     dst->direct_table           = src->direct_table;
     dst->list_counts            = src->list_counts;
+    dst->DPB                    = src->DPB;
+    dst->cur_pic_ptr            = src->cur_pic_ptr;
+    dst->cur_pic                = src->cur_pic;
     dst->bipred_scratchpad      = NULL;
-    ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma,
+    dst->edge_emu_buffer        = NULL;
+    dst->me.scratchpad          = NULL;
+    ff_h264_pred_init(&dst->hpc, src->avctx->codec_id, src->sps.bit_depth_luma,
                       src->sps.chroma_format_idc);
 }
 
@@ -975,10 +1158,17 @@ static void clone_tables(H264Context *dst, H264Context *src, int i)
  */
 static int context_init(H264Context *h)
 {
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    ERContext *er = &h->er;
+    int mb_array_size = h->mb_height * h->mb_stride;
+    int y_size  = (2 * h->mb_width + 1) * (2 * h->mb_height + 1);
+    int c_size  = h->mb_stride * (h->mb_height + 1);
+    int yc_size = y_size + 2   * c_size;
+    int x, y, i;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[0],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
 
     h->ref_cache[0][scan8[5]  + 1] =
     h->ref_cache[0][scan8[7]  + 1] =
@@ -987,8 +1177,45 @@ static int context_init(H264Context *h)
     h->ref_cache[1][scan8[7]  + 1] =
     h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
 
-    h->s.er.decode_mb = h264_er_decode_mb;
-    h->s.er.opaque    = h;
+    /* init ER */
+    er->avctx          = h->avctx;
+    er->dsp            = &h->dsp;
+    er->decode_mb      = h264_er_decode_mb;
+    er->opaque         = h;
+    er->quarter_sample = 1;
+
+    er->mb_num      = h->mb_num;
+    er->mb_width    = h->mb_width;
+    er->mb_height   = h->mb_height;
+    er->mb_stride   = h->mb_stride;
+    er->b8_stride   = h->mb_width * 2 + 1;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, (h->mb_num + 1) * sizeof(int),
+                      fail); // error ressilience code looks cleaner with this
+    for (y = 0; y < h->mb_height; y++)
+        for (x = 0; x < h->mb_width; x++)
+            er->mb_index2xy[x + y * h->mb_width] = x + y * h->mb_stride;
+
+    er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) *
+                                                   h->mb_stride + h->mb_width;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table,
+                      mb_array_size * sizeof(uint8_t), fail);
+
+    FF_ALLOC_OR_GOTO(h->avctx, er->mbintra_table, mb_array_size, fail);
+    memset(er->mbintra_table, 1, mb_array_size);
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, er->mbskip_table, mb_array_size + 2, fail);
+
+    FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, h->mb_height * h->mb_stride,
+                     fail);
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base, yc_size * sizeof(int16_t), fail);
+    er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2;
+    er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1;
+    er->dc_val[2] = er->dc_val[1] + c_size;
+    for (i = 0; i < yc_size; i++)
+        h->dc_val_base[i] = 1024;
 
     return 0;
 
@@ -1001,23 +1228,23 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
 
 static av_cold void common_init(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
 
-    s->width    = s->avctx->width;
-    s->height   = s->avctx->height;
-    s->codec_id = s->avctx->codec->id;
+    h->width    = h->avctx->width;
+    h->height   = h->avctx->height;
+
+    h->bit_depth_luma    = 8;
+    h->chroma_format_idc = 1;
 
     ff_h264dsp_init(&h->h264dsp, 8, 1);
     ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
     ff_h264qpel_init(&h->h264qpel, 8);
-    ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
+    ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);
 
     h->dequant_coeff_pps = -1;
-    s->unrestricted_mv   = 1;
 
     /* needed so that IDCT permutation is known early */
-    ff_dsputil_init(&s->dsp, s->avctx);
-    ff_videodsp_init(&s->vdsp, 8);
+    ff_dsputil_init(&h->dsp, h->avctx);
+    ff_videodsp_init(&h->vdsp, 8);
 
     memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
     memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
@@ -1025,7 +1252,7 @@ static av_cold void common_init(H264Context *h)
 
 int ff_h264_decode_extradata(H264Context *h)
 {
-    AVCodecContext *avctx = h->s.avctx;
+    AVCodecContext *avctx = h->avctx;
 
     if (avctx->extradata[0] == 1) {
         int i, cnt, nalsize;
@@ -1080,22 +1307,22 @@ int ff_h264_decode_extradata(H264Context *h)
 av_cold int ff_h264_decode_init(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *const s = &h->s;
     int i;
 
-    ff_MPV_decode_defaults(s);
-
-    s->avctx = avctx;
+    h->avctx = avctx;
     common_init(h);
 
-    s->out_format      = FMT_H264;
-    s->workaround_bugs = avctx->workaround_bugs;
+    h->picture_structure   = PICT_FRAME;
+    h->picture_range_start = 0;
+    h->picture_range_end   = MAX_PICTURE_COUNT;
+    h->slice_context_count = 1;
+    h->workaround_bugs     = avctx->workaround_bugs;
+    h->flags               = avctx->flags;
 
     /* set defaults */
     // s->decode_mb = ff_h263_decode_mb;
-    s->quarter_sample = 1;
     if (!avctx->has_b_frames)
-        s->low_delay = 1;
+        h->low_delay = 1;
 
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
 
@@ -1113,7 +1340,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     ff_h264_reset_sei(h);
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         if (avctx->ticks_per_frame == 1)
-            s->avctx->time_base.den *= 2;
+            h->avctx->time_base.den *= 2;
         avctx->ticks_per_frame = 2;
     }
 
@@ -1122,25 +1349,30 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
         return -1;
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
     return 0;
 }
 
 #define IN_RANGE(a, b, size) (((a) >= (b)) && ((a) < ((b) + (size))))
+#undef REBASE_PICTURE
+#define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
+    ((pic && pic >= old_ctx->DPB &&                       \
+      pic < old_ctx->DPB + old_ctx->picture_count) ?      \
+        &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
 
 static void copy_picture_range(Picture **to, Picture **from, int count,
-                               MpegEncContext *new_base,
-                               MpegEncContext *old_base)
+                               H264Context *new_base,
+                               H264Context *old_base)
 {
     int i;
 
     for (i = 0; i < count; i++) {
         assert((IN_RANGE(from[i], old_base, sizeof(*old_base)) ||
-                IN_RANGE(from[i], old_base->picture,
+                IN_RANGE(from[i], old_base->DPB,
                          sizeof(Picture) * old_base->picture_count) ||
                 !from[i]));
         to[i] = REBASE_PICTURE(from[i], new_base, old_base);
@@ -1171,7 +1403,7 @@ static int decode_init_thread_copy(AVCodecContext *avctx)
     memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
     memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 
-    h->s.context_initialized = 0;
+    h->context_initialized = 0;
 
     return 0;
 }
@@ -1188,49 +1420,47 @@ static int decode_update_thread_context(AVCodecContext *dst,
                                         const AVCodecContext *src)
 {
     H264Context *h = dst->priv_data, *h1 = src->priv_data;
-    MpegEncContext *const s = &h->s, *const s1 = &h1->s;
-    int inited = s->context_initialized, err;
+    int inited = h->context_initialized, err = 0;
+    int context_reinitialized = 0;
     int i;
 
-    if (dst == src || !s1->context_initialized)
+    if (dst == src || !h1->context_initialized)
         return 0;
 
     if (inited &&
-        (s->width      != s1->width      ||
-         s->height     != s1->height     ||
-         s->mb_width   != s1->mb_width   ||
-         s->mb_height  != s1->mb_height  ||
+        (h->width      != h1->width      ||
+         h->height     != h1->height     ||
+         h->mb_width   != h1->mb_width   ||
+         h->mb_height  != h1->mb_height  ||
          h->sps.bit_depth_luma    != h1->sps.bit_depth_luma    ||
          h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||
          h->sps.colorspace        != h1->sps.colorspace)) {
 
         av_freep(&h->bipred_scratchpad);
 
-        s->width     = s1->width;
-        s->height    = s1->height;
-        s->mb_height = s1->mb_height;
+        h->width     = h1->width;
+        h->height    = h1->height;
+        h->mb_height = h1->mb_height;
+        h->mb_width  = h1->mb_width;
+        h->mb_num    = h1->mb_num;
+        h->mb_stride = h1->mb_stride;
         h->b_stride  = h1->b_stride;
 
         if ((err = h264_slice_header_init(h, 1)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
+            av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
             return err;
         }
-        h->context_reinitialized = 1;
+        context_reinitialized = 1;
 
-        /* update linesize on resize for h264. The h264 decoder doesn't
-         * necessarily call ff_MPV_frame_start in the new thread */
-        s->linesize   = s1->linesize;
-        s->uvlinesize = s1->uvlinesize;
+        /* update linesize on resize. The decoder doesn't
+         * necessarily call ff_h264_frame_start in the new thread */
+        h->linesize   = h1->linesize;
+        h->uvlinesize = h1->uvlinesize;
 
         /* copy block_offset since frame_start may not be called */
         memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
-        h264_set_parameter_from_sps(h);
     }
 
-    err = ff_mpeg_update_thread_context(dst, src);
-    if (err)
-        return err;
-
     if (!inited) {
         for (i = 0; i < MAX_SPS_COUNT; i++)
             av_freep(h->sps_buffers + i);
@@ -1238,11 +1468,20 @@ static int decode_update_thread_context(AVCodecContext *dst,
         for (i = 0; i < MAX_PPS_COUNT; i++)
             av_freep(h->pps_buffers + i);
 
-        // copy all fields after MpegEnc
-        memcpy(&h->s + 1, &h1->s + 1,
-               sizeof(H264Context) - sizeof(MpegEncContext));
+        memcpy(h, h1, sizeof(*h1));
         memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
         memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
+        memset(&h->er, 0, sizeof(h->er));
+        memset(&h->me, 0, sizeof(h->me));
+        h->context_initialized = 0;
+
+        h->picture_range_start  += MAX_PICTURE_COUNT;
+        h->picture_range_end    += MAX_PICTURE_COUNT;
+
+        h->avctx = dst;
+        h->DPB   = NULL;
+        h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
         if (ff_h264_alloc_tables(h) < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
             return AVERROR(ENOMEM);
@@ -1254,17 +1493,46 @@ static int decode_update_thread_context(AVCodecContext *dst,
             h->rbsp_buffer_size[i] = 0;
         }
         h->bipred_scratchpad = NULL;
+        h->edge_emu_buffer   = NULL;
 
         h->thread_context[0] = h;
 
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
+        h->dsp.clear_blocks(h->mb);
+        h->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
+        h->context_initialized = 1;
     }
 
+    h->avctx->coded_height  = h1->avctx->coded_height;
+    h->avctx->coded_width   = h1->avctx->coded_width;
+    h->avctx->width         = h1->avctx->width;
+    h->avctx->height        = h1->avctx->height;
+    h->coded_picture_number = h1->coded_picture_number;
+    h->first_field          = h1->first_field;
+    h->picture_structure    = h1->picture_structure;
+    h->qscale               = h1->qscale;
+    h->droppable            = h1->droppable;
+    h->data_partitioning    = h1->data_partitioning;
+    h->low_delay            = h1->low_delay;
+
+    memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB));
+
+    // reset s->picture[].f.extended_data to s->picture[].f.data
+    for (i = 0; i < h->picture_count; i++)
+        h->DPB[i].f.extended_data = h->DPB[i].f.data;
+
+    h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
+    h->cur_pic = h1->cur_pic;
+    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
+    h->workaround_bugs = h1->workaround_bugs;
+    h->low_delay       = h1->low_delay;
+    h->droppable       = h1->droppable;
+
     /* frame_start may not be called for the next thread (if it's decoding
      * a bottom field) so this has to be allocated here */
-    if (!h->bipred_scratchpad)
-        h->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
+    err = alloc_scratch_buffers(h, h1->linesize);
+    if (err < 0)
+        return err;
 
     // extradata/NAL handling
     h->is_avc = h1->is_avc;
@@ -1299,17 +1567,20 @@ static int decode_update_thread_context(AVCodecContext *dst,
     copy_fields(h, h1, ref2frm, intra_gb);
     copy_fields(h, h1, short_ref, cabac_init_idc);
 
-    copy_picture_range(h->short_ref, h1->short_ref, 32, s, s1);
-    copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1);
+    copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
+    copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
     copy_picture_range(h->delayed_pic, h1->delayed_pic,
-                       MAX_DELAYED_PIC_COUNT + 2, s, s1);
+                       MAX_DELAYED_PIC_COUNT + 2, h, h1);
 
     h->last_slice_type = h1->last_slice_type;
 
-    if (!s->current_picture_ptr)
+    if (context_reinitialized)
+        h264_set_parameter_from_sps(h);
+
+    if (!h->cur_pic_ptr)
         return 0;
 
-    if (!s->droppable) {
+    if (!h->droppable) {
         err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
         h->prev_poc_msb = h->poc_msb;
         h->prev_poc_lsb = h->poc_lsb;
@@ -1323,45 +1594,66 @@ static int decode_update_thread_context(AVCodecContext *dst,
 
 int ff_h264_frame_start(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int i;
+    Picture *pic;
+    int i, ret;
     const int pixel_shift = h->pixel_shift;
 
-    if (ff_MPV_frame_start(s, s->avctx) < 0)
-        return -1;
-    ff_mpeg_er_frame_start(s);
+    release_unused_pictures(h, 1);
+    h->cur_pic_ptr = NULL;
+
+    i = find_unused_picture(h);
+    if (i < 0) {
+        av_log(h->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+        return i;
+    }
+    pic = &h->DPB[i];
+
+    pic->f.reference            = h->droppable ? 0 : h->picture_structure;
+    pic->f.coded_picture_number = h->coded_picture_number++;
+    pic->field_picture          = h->picture_structure != PICT_FRAME;
     /*
-     * ff_MPV_frame_start uses pict_type to derive key_frame.
-     * This is incorrect for H.264; IDR markings must be used.
-     * Zero here; IDR markings per slice in frame or fields are ORed in later.
+     * Zero key_frame here; IDR markings per slice in frame or fields are ORed
+     * in later.
      * See decode_nal_units().
      */
-    s->current_picture_ptr->f.key_frame = 0;
-    s->current_picture_ptr->mmco_reset  = 0;
+    pic->f.key_frame = 0;
+    pic->mmco_reset  = 0;
+
+    if ((ret = alloc_picture(h, pic)) < 0)
+        return ret;
+
+    h->cur_pic_ptr = pic;
+    h->cur_pic     = *h->cur_pic_ptr;
+    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+
+    ff_er_frame_start(&h->er);
 
-    assert(s->linesize && s->uvlinesize);
+    assert(h->linesize && h->uvlinesize);
 
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
     }
 
     /* can't be in alloc_tables because linesize isn't known there.
      * FIXME: redo bipred weight to not require extra buffer? */
-    for (i = 0; i < s->slice_context_count; i++)
-        if (h->thread_context[i] && !h->thread_context[i]->bipred_scratchpad)
-            h->thread_context[i]->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
+    for (i = 0; i < h->slice_context_count; i++)
+        if (h->thread_context[i]) {
+            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);
+            if (ret < 0)
+                return ret;
+        }
 
     /* Some macroblocks can be accessed before they're available in case
      * of lost slices, MBAFF or threading. */
     memset(h->slice_table, -1,
-           (s->mb_height * s->mb_stride - 1) * sizeof(*h->slice_table));
+           (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
 
     // s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding ||
     //             s->current_picture.f.reference /* || h->contains_intra */ || 1;
@@ -1372,15 +1664,14 @@ int ff_h264_frame_start(H264Context *h)
      * SVQ3 as well as most other codecs have only last/next/current and thus
      * get released even with set reference, besides SVQ3 and others do not
      * mark frames as reference later "naturally". */
-    if (s->codec_id != AV_CODEC_ID_SVQ3)
-        s->current_picture_ptr->f.reference = 0;
+    if (h->avctx->codec_id != AV_CODEC_ID_SVQ3)
+        h->cur_pic_ptr->f.reference = 0;
 
-    s->current_picture_ptr->field_poc[0]     =
-        s->current_picture_ptr->field_poc[1] = INT_MAX;
+    h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX;
 
     h->next_output_pic = NULL;
 
-    assert(s->current_picture_ptr->long_ref == 0);
+    assert(h->cur_pic_ptr->long_ref == 0);
 
     return 0;
 }
@@ -1395,14 +1686,13 @@ int ff_h264_frame_start(H264Context *h)
  */
 static void decode_postinit(H264Context *h, int setup_finished)
 {
-    MpegEncContext *const s = &h->s;
-    Picture *out = s->current_picture_ptr;
-    Picture *cur = s->current_picture_ptr;
+    Picture *out = h->cur_pic_ptr;
+    Picture *cur = h->cur_pic_ptr;
     int i, pics, out_of_order, out_idx;
     int invalid = 0, cnt = 0;
 
-    s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
-    s->current_picture_ptr->f.pict_type   = s->pict_type;
+    h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
+    h->cur_pic_ptr->f.pict_type   = h->pict_type;
 
     if (h->next_output_pic)
         return;
@@ -1413,7 +1703,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
          * The check in decode_nal_units() is not good enough to find this
          * yet, so we assume the worst for now. */
         // if (setup_finished)
-        //    ff_thread_finish_setup(s->avctx);
+        //    ff_thread_finish_setup(h->avctx);
         return;
     }
 
@@ -1487,15 +1777,15 @@ static void decode_postinit(H264Context *h, int setup_finished)
     /* Sort B-frames into display order */
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
-    if (s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
+    if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
         !h->sps.bitstream_restriction_flag) {
-        s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
+        h->low_delay           = 0;
     }
 
     pics = 0;
@@ -1516,7 +1806,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
      * there is no delay, we can't detect that (since the frame was already
      * output to the user), so we also set h->mmco_reset to detect the MMCO
      * reset code.
-     * FIXME: if we detect insufficient delays (as per s->avctx->has_b_frames),
+     * FIXME: if we detect insufficient delays (as per h->avctx->has_b_frames),
      * we increase the delay between input and output. All frames affected by
      * the lag (e.g. those that should have been output before another frame
      * that we already returned to the user) will be dropped. This is a bug
@@ -1548,40 +1838,40 @@ static void decode_postinit(H264Context *h, int setup_finished)
             out     = h->delayed_pic[i];
             out_idx = i;
         }
-    if (s->avctx->has_b_frames == 0 &&
+    if (h->avctx->has_b_frames == 0 &&
         (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
         h->next_outputed_poc = INT_MIN;
     out_of_order = !out->f.key_frame && !h->mmco_reset &&
                    (out->poc < h->next_outputed_poc);
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames >= h->sps.num_reorder_frames) {
-    } else if (out_of_order && pics - 1 == s->avctx->has_b_frames &&
-               s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
+        h->avctx->has_b_frames >= h->sps.num_reorder_frames) {
+    } else if (out_of_order && pics - 1 == h->avctx->has_b_frames &&
+               h->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
         if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
-            s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
+            h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, cnt);
         }
-        s->low_delay = 0;
-    } else if (s->low_delay &&
+        h->low_delay = 0;
+    } else if (h->low_delay &&
                ((h->next_outputed_poc != INT_MIN &&
                  out->poc > h->next_outputed_poc + 2) ||
                 cur->f.pict_type == AV_PICTURE_TYPE_B)) {
-        s->low_delay = 0;
-        s->avctx->has_b_frames++;
+        h->low_delay = 0;
+        h->avctx->has_b_frames++;
     }
 
-    if (pics > s->avctx->has_b_frames) {
+    if (pics > h->avctx->has_b_frames) {
         out->f.reference &= ~DELAYED_PIC_REF;
         // for frame threading, the owner must be the second field's thread or
         // else the first thread can release the picture and reuse it unsafely
-        out->owner2       = s;
+        out->owner2       = h;
         for (i = out_idx; h->delayed_pic[i]; i++)
             h->delayed_pic[i] = h->delayed_pic[i + 1];
     }
     memmove(h->last_pocs, &h->last_pocs[1],
             sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));
     h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;
-    if (!out_of_order && pics > s->avctx->has_b_frames) {
+    if (!out_of_order && pics > h->avctx->has_b_frames) {
         h->next_output_pic = out;
         if (out->mmco_reset) {
             if (out_idx > 0) {
@@ -1599,11 +1889,11 @@ static void decode_postinit(H264Context *h, int setup_finished)
         }
         h->mmco_reset = 0;
     } else {
-        av_log(s->avctx, AV_LOG_DEBUG, "no picture\n");
+        av_log(h->avctx, AV_LOG_DEBUG, "no picture\n");
     }
 
     if (setup_finished)
-        ff_thread_finish_setup(s->avctx);
+        ff_thread_finish_setup(h->avctx);
 }
 
 static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
@@ -1611,7 +1901,6 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
                                               int linesize, int uvlinesize,
                                               int simple)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *top_border;
     int top_idx = 1;
     const int pixel_shift = h->pixel_shift;
@@ -1623,13 +1912,13 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
     src_cr -= uvlinesize;
 
     if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (!MB_MBAFF) {
-                top_border = h->top_borders[0][s->mb_x];
+                top_border = h->top_borders[0][h->mb_x];
                 AV_COPY128(top_border, src_y + 15 * linesize);
                 if (pixel_shift)
                     AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
-                if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                     if (chroma444) {
                         if (pixel_shift) {
                             AV_COPY128(top_border + 32, src_cb + 15 * uvlinesize);
@@ -1665,14 +1954,14 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
             return;
     }
 
-    top_border = h->top_borders[top_idx][s->mb_x];
+    top_border = h->top_borders[top_idx][h->mb_x];
     /* There are two lines saved, the line above the top macroblock
      * of a pair, and the line above the bottom macroblock. */
     AV_COPY128(top_border, src_y + 16 * linesize);
     if (pixel_shift)
         AV_COPY128(top_border + 16, src_y + 16 * linesize + 16);
 
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
         if (chroma444) {
             if (pixel_shift) {
                 AV_COPY128(top_border + 32, src_cb + 16 * linesize);
@@ -1709,7 +1998,6 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
                                             int xchg, int chroma444,
                                             int simple, int pixel_shift)
 {
-    MpegEncContext *const s = &h->s;
     int deblock_topleft;
     int deblock_top;
     int top_idx = 1;
@@ -1717,7 +2005,7 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
     uint8_t *top_border;
 
     if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (!MB_MBAFF)
                 return;
         } else {
@@ -1726,19 +2014,19 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
     }
 
     if (h->deblocking_filter == 2) {
-        deblock_topleft = h->slice_table[h->mb_xy - 1 - s->mb_stride] == h->slice_num;
+        deblock_topleft = h->slice_table[h->mb_xy - 1 - h->mb_stride] == h->slice_num;
         deblock_top     = h->top_type;
     } else {
-        deblock_topleft = (s->mb_x > 0);
-        deblock_top     = (s->mb_y > !!MB_FIELD);
+        deblock_topleft = (h->mb_x > 0);
+        deblock_top     = (h->mb_y > !!MB_FIELD);
     }
 
     src_y  -= linesize   + 1 + pixel_shift;
     src_cb -= uvlinesize + 1 + pixel_shift;
     src_cr -= uvlinesize + 1 + pixel_shift;
 
-    top_border_m1 = h->top_borders[top_idx][s->mb_x - 1];
-    top_border    = h->top_borders[top_idx][s->mb_x];
+    top_border_m1 = h->top_borders[top_idx][h->mb_x - 1];
+    top_border    = h->top_borders[top_idx][h->mb_x];
 
 #define XCHG(a, b, xchg)                        \
     if (pixel_shift) {                          \
@@ -1760,12 +2048,12 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
         }
         XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);
         XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);
-        if (s->mb_x + 1 < s->mb_width) {
-            XCHG(h->top_borders[top_idx][s->mb_x + 1],
+        if (h->mb_x + 1 < h->mb_width) {
+            XCHG(h->top_borders[top_idx][h->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
     }
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
         if (chroma444) {
             if (deblock_topleft) {
                 XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
@@ -1775,9 +2063,9 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
             XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);
             XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
             XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
-            if (s->mb_x + 1 < s->mb_width) {
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
+            if (h->mb_x + 1 < h->mb_width) {
+                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
+                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
             }
         } else {
             if (deblock_top) {
@@ -1819,17 +2107,16 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
                                                        int linesize,
                                                        uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     void (*idct_dc_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p - 1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p - 1];
     block_offset += 16 * p;
     if (IS_INTRA4x4(mb_type)) {
         if (IS_8x8DCT(mb_type)) {
             if (transform_bypass) {
                 idct_dc_add  =
-                idct_add     = s->dsp.add_pixels8;
+                idct_add     = h->dsp.add_pixels8;
             } else {
                 idct_dc_add = h->h264dsp.h264_idct8_dc_add;
                 idct_add    = h->h264dsp.h264_idct8_add;
@@ -1854,7 +2141,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
         } else {
             if (transform_bypass) {
                 idct_dc_add  =
-                    idct_add = s->dsp.add_pixels4;
+                    idct_add = h->dsp.add_pixels4;
             } else {
                 idct_dc_add = h->h264dsp.h264_idct_dc_add;
                 idct_add    = h->h264dsp.h264_idct_add;
@@ -1871,7 +2158,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
                     uint64_t tr_high;
                     if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
                         const int topright_avail = (h->topright_samples_available << i) & 0x8000;
-                        assert(s->mb_y || linesize <= block_offset[i]);
+                        assert(h->mb_y || linesize <= block_offset[i]);
                         if (!topright_avail) {
                             if (pixel_shift) {
                                 tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
@@ -1934,7 +2221,6 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                                                     int linesize,
                                                     uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
     block_offset += 16 * p;
@@ -1952,7 +2238,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                         for (i = 0; i < 16; i++)
                             if (h->non_zero_count_cache[scan8[i + p * 16]] ||
                                 dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                s->dsp.add_pixels4(dest_y + block_offset[i],
+                                h->dsp.add_pixels4(dest_y + block_offset[i],
                                                    h->mb + (i * 16 + p * 256 << pixel_shift),
                                                    linesize);
                     }
@@ -1965,8 +2251,8 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
             } else if (h->cbp & 15) {
                 if (transform_bypass) {
                     const int di = IS_8x8DCT(mb_type) ? 4 : 1;
-                    idct_add = IS_8x8DCT(mb_type) ? s->dsp.add_pixels8
-                                                  : s->dsp.add_pixels4;
+                    idct_add = IS_8x8DCT(mb_type) ? h->dsp.add_pixels8
+                                                  : h->dsp.add_pixels4;
                     for (i = 0; i < 16; i += di)
                         if (h->non_zero_count_cache[scan8[i + p * 16]])
                             idct_add(dest_y + block_offset[i],
@@ -1991,7 +2277,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                     // FIXME benchmark weird rule, & below
                     uint8_t *const ptr = dest_y + block_offset[i];
                     ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize,
-                                       s->qscale, IS_INTRA(mb_type) ? 1 : 0);
+                                       h->qscale, IS_INTRA(mb_type) ? 1 : 0);
                 }
         }
     }
@@ -2011,10 +2297,9 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
 
 void ff_h264_hl_decode_mb(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0;
 
     if (CHROMA444) {
         if (is_complex || h->pixel_shift)
@@ -2031,15 +2316,14 @@ void ff_h264_hl_decode_mb(H264Context *h)
 
 static int pred_weight_table(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     int list, i;
     int luma_def, chroma_def;
 
     h->use_weight             = 0;
     h->use_weight_chroma      = 0;
-    h->luma_log2_weight_denom = get_ue_golomb(&s->gb);
+    h->luma_log2_weight_denom = get_ue_golomb(&h->gb);
     if (h->sps.chroma_format_idc)
-        h->chroma_log2_weight_denom = get_ue_golomb(&s->gb);
+        h->chroma_log2_weight_denom = get_ue_golomb(&h->gb);
     luma_def   = 1 << h->luma_log2_weight_denom;
     chroma_def = 1 << h->chroma_log2_weight_denom;
 
@@ -2049,10 +2333,10 @@ static int pred_weight_table(H264Context *h)
         for (i = 0; i < h->ref_count[list]; i++) {
             int luma_weight_flag, chroma_weight_flag;
 
-            luma_weight_flag = get_bits1(&s->gb);
+            luma_weight_flag = get_bits1(&h->gb);
             if (luma_weight_flag) {
-                h->luma_weight[i][list][0] = get_se_golomb(&s->gb);
-                h->luma_weight[i][list][1] = get_se_golomb(&s->gb);
+                h->luma_weight[i][list][0] = get_se_golomb(&h->gb);
+                h->luma_weight[i][list][1] = get_se_golomb(&h->gb);
                 if (h->luma_weight[i][list][0] != luma_def ||
                     h->luma_weight[i][list][1] != 0) {
                     h->use_weight             = 1;
@@ -2064,12 +2348,12 @@ static int pred_weight_table(H264Context *h)
             }
 
             if (h->sps.chroma_format_idc) {
-                chroma_weight_flag = get_bits1(&s->gb);
+                chroma_weight_flag = get_bits1(&h->gb);
                 if (chroma_weight_flag) {
                     int j;
                     for (j = 0; j < 2; j++) {
-                        h->chroma_weight[i][list][j][0] = get_se_golomb(&s->gb);
-                        h->chroma_weight[i][list][j][1] = get_se_golomb(&s->gb);
+                        h->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);
+                        h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);
                         if (h->chroma_weight[i][list][j][0] != chroma_def ||
                             h->chroma_weight[i][list][j][1] != 0) {
                             h->use_weight_chroma = 1;
@@ -2099,7 +2383,6 @@ static int pred_weight_table(H264Context *h)
  */
 static void implicit_weight_table(H264Context *h, int field)
 {
-    MpegEncContext *const s = &h->s;
     int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1;
 
     for (i = 0; i < 2; i++) {
@@ -2108,10 +2391,10 @@ static void implicit_weight_table(H264Context *h, int field)
     }
 
     if (field < 0) {
-        if (s->picture_structure == PICT_FRAME) {
-            cur_poc = s->current_picture_ptr->poc;
+        if (h->picture_structure == PICT_FRAME) {
+            cur_poc = h->cur_pic_ptr->poc;
         } else {
-            cur_poc = s->current_picture_ptr->field_poc[s->picture_structure - 1];
+            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure - 1];
         }
         if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF &&
             h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) {
@@ -2123,7 +2406,7 @@ static void implicit_weight_table(H264Context *h, int field)
         ref_count0 = h->ref_count[0];
         ref_count1 = h->ref_count[1];
     } else {
-        cur_poc    = s->current_picture_ptr->field_poc[field];
+        cur_poc    = h->cur_pic_ptr->field_poc[field];
         ref_start  = 16;
         ref_count0 = 16 + 2 * h->ref_count[0];
         ref_count1 = 16 + 2 * h->ref_count[1];
@@ -2180,9 +2463,9 @@ static void flush_change(H264Context *h)
     h->outputed_poc = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
     idr(h);
-    if (h->s.current_picture_ptr)
-        h->s.current_picture_ptr->f.reference = 0;
-    h->s.first_field = 0;
+    if (h->cur_pic_ptr)
+        h->cur_pic_ptr->f.reference = 0;
+    h->first_field = 0;
     memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
     memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
     memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
@@ -2203,15 +2486,28 @@ static void flush_dpb(AVCodecContext *avctx)
     }
 
     flush_change(h);
-    ff_mpeg_flush(avctx);
+
+    for (i = 0; i < h->picture_count; i++) {
+        if (h->DPB[i].f.data[0])
+            free_frame_buffer(h, &h->DPB[i]);
+    }
+    h->cur_pic_ptr = NULL;
+
+    h->mb_x = h->mb_y = 0;
+
+    h->parse_context.state             = -1;
+    h->parse_context.frame_start_found = 0;
+    h->parse_context.overread          = 0;
+    h->parse_context.overread_index    = 0;
+    h->parse_context.index             = 0;
+    h->parse_context.last_index        = 0;
 }
 
 static int init_poc(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int max_frame_num = 1 << h->sps.log2_max_frame_num;
     int field_poc[2];
-    Picture *cur = s->current_picture_ptr;
+    Picture *cur = h->cur_pic_ptr;
 
     h->frame_num_offset = h->prev_frame_num_offset;
     if (h->frame_num < h->prev_frame_num)
@@ -2228,7 +2524,7 @@ static int init_poc(H264Context *h)
             h->poc_msb = h->prev_poc_msb;
         field_poc[0] =
         field_poc[1] = h->poc_msb + h->poc_lsb;
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc_bottom;
     } else if (h->sps.poc_type == 1) {
         int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
@@ -2263,7 +2559,7 @@ static int init_poc(H264Context *h)
         field_poc[0] = expectedpoc + h->delta_poc[0];
         field_poc[1] = field_poc[0] + h->sps.offset_for_top_to_bottom_field;
 
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc[1];
     } else {
         int poc = 2 * (h->frame_num_offset + h->frame_num);
@@ -2275,10 +2571,10 @@ static int init_poc(H264Context *h)
         field_poc[1] = poc;
     }
 
-    if (s->picture_structure != PICT_BOTTOM_FIELD)
-        s->current_picture_ptr->field_poc[0] = field_poc[0];
-    if (s->picture_structure != PICT_TOP_FIELD)
-        s->current_picture_ptr->field_poc[1] = field_poc[1];
+    if (h->picture_structure != PICT_BOTTOM_FIELD)
+        h->cur_pic_ptr->field_poc[0] = field_poc[0];
+    if (h->picture_structure != PICT_TOP_FIELD)
+        h->cur_pic_ptr->field_poc[1] = field_poc[1];
     cur->poc = FFMIN(cur->field_poc[0], cur->field_poc[1]);
 
     return 0;
@@ -2323,21 +2619,20 @@ static void init_scan_tables(H264Context *h)
 
 static int field_end(H264Context *h, int in_setup)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     int err = 0;
-    s->mb_y = 0;
+    h->mb_y = 0;
 
-    if (!in_setup && !s->droppable)
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
+    if (!in_setup && !h->droppable)
+        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
 
     if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_set_reference_frames(s);
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+        ff_vdpau_h264_set_reference_frames(h);
 
     if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
-        if (!s->droppable) {
+        if (!h->droppable) {
             err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
             h->prev_poc_msb = h->poc_msb;
             h->prev_poc_lsb = h->poc_lsb;
@@ -2354,8 +2649,8 @@ static int field_end(H264Context *h, int in_setup)
     }
 
     if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_picture_complete(s);
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+        ff_vdpau_h264_picture_complete(h);
 
     /*
      * FIXME: Error handling code does not seem to support interlaced
@@ -2369,10 +2664,36 @@ static int field_end(H264Context *h, int in_setup)
      * past end by one (callers fault) and resync_mb_y != 0
      * causes problems for the first MB line, too.
      */
-    if (!FIELD_PICTURE)
-        ff_er_frame_end(&s->er);
-
-    ff_MPV_frame_end(s);
+    if (!FIELD_PICTURE) {
+        h->er.cur_pic  = h->cur_pic_ptr;
+        h->er.last_pic = h->ref_count[0] ? &h->ref_list[0][0] : NULL;
+        h->er.next_pic = h->ref_count[1] ? &h->ref_list[1][0] : NULL;
+        ff_er_frame_end(&h->er);
+    }
+
+    /* redraw edges for the frame if decoding didn't complete */
+    if (h->er.error_count &&
+        !h->avctx->hwaccel &&
+        !(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
+        h->cur_pic_ptr->f.reference &&
+        !(h->flags & CODEC_FLAG_EMU_EDGE)) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(h->avctx->pix_fmt);
+        int hshift = desc->log2_chroma_w;
+        int vshift = desc->log2_chroma_h;
+        h->dsp.draw_edges(h->cur_pic.f.data[0], h->linesize,
+                          h->mb_width * 16, h->mb_height * 16,
+                          EDGE_WIDTH, EDGE_WIDTH,
+                          EDGE_TOP | EDGE_BOTTOM);
+        h->dsp.draw_edges(h->cur_pic.f.data[1], h->uvlinesize,
+                          (h->mb_width * 16) >> hshift, (h->mb_height * 16) >> vshift,
+                          EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                          EDGE_TOP | EDGE_BOTTOM);
+        h->dsp.draw_edges(h->cur_pic.f.data[2], h->uvlinesize,
+                          (h->mb_width * 16) >> hshift, (h->mb_height * 16) >> vshift,
+                          EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                          EDGE_TOP | EDGE_BOTTOM);
+    }
+    emms_c();
 
     h->current_slice = 0;
 
@@ -2384,21 +2705,12 @@ static int field_end(H264Context *h, int in_setup)
  */
 static int clone_slice(H264Context *dst, H264Context *src)
 {
-    int ret;
-
     memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));
-    dst->s.current_picture_ptr = src->s.current_picture_ptr;
-    dst->s.current_picture     = src->s.current_picture;
-    dst->s.linesize            = src->s.linesize;
-    dst->s.uvlinesize          = src->s.uvlinesize;
-    dst->s.first_field         = src->s.first_field;
-
-    if (!dst->s.edge_emu_buffer &&
-        (ret = ff_mpv_frame_size_alloc(&dst->s, dst->s.linesize))) {
-        av_log(dst->s.avctx, AV_LOG_ERROR,
-               "Failed to allocate scratch buffers\n");
-        return ret;
-    }
+    dst->cur_pic_ptr = src->cur_pic_ptr;
+    dst->cur_pic     = src->cur_pic;
+    dst->linesize    = src->linesize;
+    dst->uvlinesize  = src->uvlinesize;
+    dst->first_field = src->first_field;
 
     dst->prev_poc_msb          = src->prev_poc_msb;
     dst->prev_poc_lsb          = src->prev_poc_lsb;
@@ -2445,32 +2757,30 @@ int ff_h264_get_profile(SPS *sps)
 
 static int h264_set_parameter_from_sps(H264Context *h)
 {
-    MpegEncContext *s = &h->s;
-
-    if (s->flags & CODEC_FLAG_LOW_DELAY ||
+    if (h->flags & CODEC_FLAG_LOW_DELAY ||
         (h->sps.bitstream_restriction_flag &&
          !h->sps.num_reorder_frames)) {
-        if (s->avctx->has_b_frames > 1 || h->delayed_pic[0])
-            av_log(h->s.avctx, AV_LOG_WARNING, "Delayed frames seen. "
+        if (h->avctx->has_b_frames > 1 || h->delayed_pic[0])
+            av_log(h->avctx, AV_LOG_WARNING, "Delayed frames seen. "
                    "Reenabling low delay requires a codec flush.\n");
         else
-            s->low_delay = 1;
+            h->low_delay = 1;
     }
 
-    if (s->avctx->has_b_frames < 2)
-        s->avctx->has_b_frames = !s->low_delay;
+    if (h->avctx->has_b_frames < 2)
+        h->avctx->has_b_frames = !h->low_delay;
 
-    if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+    if (h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
         h->cur_chroma_format_idc      != h->sps.chroma_format_idc) {
-        if (s->avctx->codec &&
-            s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU &&
+        if (h->avctx->codec &&
+            h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU &&
             (h->sps.bit_depth_luma != 8 || h->sps.chroma_format_idc > 1)) {
-            av_log(s->avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "VDPAU decoding does not support video colorspace.\n");
             return AVERROR_INVALIDDATA;
         }
         if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
-            s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+            h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
             h->cur_chroma_format_idc      = h->sps.chroma_format_idc;
             h->pixel_shift                = h->sps.bit_depth_luma > 8;
 
@@ -2478,13 +2788,13 @@ static int h264_set_parameter_from_sps(H264Context *h)
                             h->sps.chroma_format_idc);
             ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
             ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma);
-            ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma,
+            ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma,
                               h->sps.chroma_format_idc);
-            s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
-            ff_dsputil_init(&s->dsp, s->avctx);
-            ff_videodsp_init(&s->vdsp, h->sps.bit_depth_luma);
+            h->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
+            ff_dsputil_init(&h->dsp, h->avctx);
+            ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
         } else {
-            av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+            av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
                    h->sps.bit_depth_luma);
             return AVERROR_INVALIDDATA;
         }
@@ -2494,11 +2804,10 @@ static int h264_set_parameter_from_sps(H264Context *h)
 
 static enum PixelFormat get_pixel_format(H264Context *h)
 {
-    MpegEncContext *const s  = &h->s;
     switch (h->sps.bit_depth_luma) {
     case 9:
         if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP9;
             } else
                 return AV_PIX_FMT_YUV444P9;
@@ -2509,7 +2818,7 @@ static enum PixelFormat get_pixel_format(H264Context *h)
         break;
     case 10:
         if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP10;
             } else
                 return AV_PIX_FMT_YUV444P10;
@@ -2520,24 +2829,24 @@ static enum PixelFormat get_pixel_format(H264Context *h)
         break;
     case 8:
         if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP;
             } else
-                return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
+                return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
                                                                  : AV_PIX_FMT_YUV444P;
         } else if (CHROMA422) {
-            return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
+            return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
                                                              : AV_PIX_FMT_YUV422P;
         } else {
-            return s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts ?
-                                        s->avctx->codec->pix_fmts :
-                                        s->avctx->color_range == AVCOL_RANGE_JPEG ?
+            return h->avctx->get_format(h->avctx, h->avctx->codec->pix_fmts ?
+                                        h->avctx->codec->pix_fmts :
+                                        h->avctx->color_range == AVCOL_RANGE_JPEG ?
                                         hwaccel_pixfmt_list_h264_jpeg_420 :
                                         ff_hwaccel_pixfmt_list_420);
         }
         break;
     default:
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
         return AVERROR_INVALIDDATA;
     }
@@ -2545,73 +2854,101 @@ static enum PixelFormat get_pixel_format(H264Context *h)
 
 static int h264_slice_header_init(H264Context *h, int reinit)
 {
-    MpegEncContext *const s  = &h->s;
-    int i, ret;
+    int nb_slices = (HAVE_THREADS &&
+                     h->avctx->active_thread_type & FF_THREAD_SLICE) ?
+                    h->avctx->thread_count : 1;
+    int i;
 
-    avcodec_set_dimensions(s->avctx, s->width, s->height);
-    s->avctx->sample_aspect_ratio = h->sps.sar;
-    av_assert0(s->avctx->sample_aspect_ratio.den);
+    avcodec_set_dimensions(h->avctx, h->width, h->height);
+    h->avctx->sample_aspect_ratio = h->sps.sar;
+    av_assert0(h->avctx->sample_aspect_ratio.den);
+    av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
+                                     &h->chroma_x_shift, &h->chroma_y_shift);
 
     if (h->sps.timing_info_present_flag) {
         int64_t den = h->sps.time_scale;
         if (h->x264_build < 44U)
             den *= 2;
-        av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
+        av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
                   h->sps.num_units_in_tick, den, 1 << 30);
     }
 
-    s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
+    h->avctx->hwaccel = ff_find_hwaccel(h->avctx->codec->id, h->avctx->pix_fmt);
 
-    if (reinit) {
+    if (reinit)
         free_tables(h, 0);
-        if ((ret = ff_MPV_common_frame_size_change(s)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_frame_size_change() failed.\n");
-            return ret;
-        }
-    } else {
-        if ((ret = ff_MPV_common_init(s)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
-            return ret;
-        }
-    }
-    s->first_field = 0;
+    h->first_field = 0;
     h->prev_interlaced_frame = 1;
 
     init_scan_tables(h);
     if (ff_h264_alloc_tables(h) < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Could not allocate memory for h264\n");
         return AVERROR(ENOMEM);
     }
 
-    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_SLICE)) {
+    if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) {
+        int max_slices;
+        if (h->mb_height)
+            max_slices = FFMIN(MAX_THREADS, h->mb_height);
+        else
+            max_slices = MAX_THREADS;
+        av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
+               " reducing to %d\n", nb_slices, max_slices);
+        nb_slices = max_slices;
+    }
+    h->slice_context_count = nb_slices;
+
+    if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
         if (context_init(h) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
+            av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
             return -1;
         }
     } else {
-        for (i = 1; i < s->slice_context_count; i++) {
+        for (i = 1; i < h->slice_context_count; i++) {
             H264Context *c;
-            c = h->thread_context[i] = av_malloc(sizeof(H264Context));
-            memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
-            memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
+            c = h->thread_context[i] = av_mallocz(sizeof(H264Context));
+            c->avctx       = h->avctx;
+            c->dsp         = h->dsp;
+            c->vdsp        = h->vdsp;
             c->h264dsp     = h->h264dsp;
             c->h264qpel    = h->h264qpel;
             c->h264chroma  = h->h264chroma;
             c->sps         = h->sps;
             c->pps         = h->pps;
             c->pixel_shift = h->pixel_shift;
+            c->width       = h->width;
+            c->height      = h->height;
+            c->linesize    = h->linesize;
+            c->uvlinesize  = h->uvlinesize;
+            c->chroma_x_shift = h->chroma_x_shift;
+            c->chroma_y_shift = h->chroma_y_shift;
+            c->qscale      = h->qscale;
+            c->droppable   = h->droppable;
+            c->data_partitioning = h->data_partitioning;
+            c->low_delay   = h->low_delay;
+            c->mb_width    = h->mb_width;
+            c->mb_height   = h->mb_height;
+            c->mb_stride   = h->mb_stride;
+            c->mb_num      = h->mb_num;
+            c->flags       = h->flags;
+            c->workaround_bugs = h->workaround_bugs;
+            c->pict_type   = h->pict_type;
+
             init_scan_tables(c);
             clone_tables(c, h, i);
+            c->context_initialized = 1;
         }
 
-        for (i = 0; i < s->slice_context_count; i++)
+        for (i = 0; i < h->slice_context_count; i++)
             if (context_init(h->thread_context[i]) < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
+                av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
                 return -1;
             }
     }
 
+    h->context_initialized = 1;
+
     return 0;
 }
 
@@ -2627,8 +2964,6 @@ static int h264_slice_header_init(H264Context *h, int reinit)
  */
 static int decode_slice_header(H264Context *h, H264Context *h0)
 {
-    MpegEncContext *const s  = &h->s;
-    MpegEncContext *const s0 = &h0->s;
     unsigned int first_mb_in_slice;
     unsigned int pps_id;
     int num_ref_idx_active_override_flag, max_refs, ret;
@@ -2637,10 +2972,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     int last_pic_structure, last_pic_droppable;
     int needs_reinit = 0;
 
-    s->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
-    s->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
+    h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
+    h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
 
-    first_mb_in_slice = get_ue_golomb(&s->gb);
+    first_mb_in_slice = get_ue_golomb(&h->gb);
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
         if (h0->current_slice && FIELD_PICTURE) {
@@ -2648,21 +2983,21 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         }
 
         h0->current_slice = 0;
-        if (!s0->first_field) {
-            if (s->current_picture_ptr && !s->droppable &&
-                s->current_picture_ptr->owner2 == s) {
-                ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                          s->picture_structure == PICT_BOTTOM_FIELD);
+        if (!h0->first_field) {
+            if (h->cur_pic_ptr && !h->droppable &&
+                h->cur_pic_ptr->owner2 == h) {
+                ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                          h->picture_structure == PICT_BOTTOM_FIELD);
             }
-            s->current_picture_ptr = NULL;
+            h->cur_pic_ptr = NULL;
         }
     }
 
-    slice_type = get_ue_golomb_31(&s->gb);
+    slice_type = get_ue_golomb_31(&h->gb);
     if (slice_type > 9) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "slice type too large (%d) at %d %d\n",
-               h->slice_type, s->mb_x, s->mb_y);
+               h->slice_type, h->mb_x, h->mb_y);
         return -1;
     }
     if (slice_type > 4) {
@@ -2680,15 +3015,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     h->slice_type_nos = slice_type & 3;
 
     // to make a few old functions happy, it's wrong though
-    s->pict_type = h->slice_type;
+    h->pict_type = h->slice_type;
 
-    pps_id = get_ue_golomb(&s->gb);
+    pps_id = get_ue_golomb(&h->gb);
     if (pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
+        av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
         return -1;
     }
     if (!h0->pps_buffers[pps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing PPS %u referenced\n",
                pps_id);
         return -1;
@@ -2696,77 +3031,77 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     h->pps = *h0->pps_buffers[pps_id];
 
     if (!h0->sps_buffers[h->pps.sps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing SPS %u referenced\n",
                h->pps.sps_id);
         return -1;
     }
 
     if (h->pps.sps_id != h->current_sps_id ||
-        h->context_reinitialized           ||
         h0->sps_buffers[h->pps.sps_id]->new) {
-        SPS *new_sps = h0->sps_buffers[h->pps.sps_id];
-
         h0->sps_buffers[h->pps.sps_id]->new = 0;
 
-        if (h->sps.chroma_format_idc != new_sps->chroma_format_idc ||
-            h->sps.bit_depth_luma    != new_sps->bit_depth_luma)
-            needs_reinit = 1;
-
         h->current_sps_id = h->pps.sps_id;
         h->sps            = *h0->sps_buffers[h->pps.sps_id];
 
+        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||
+            h->chroma_format_idc != h->sps.chroma_format_idc) {
+            h->bit_depth_luma    = h->sps.bit_depth_luma;
+            h->chroma_format_idc = h->sps.chroma_format_idc;
+            needs_reinit         = 1;
+        }
         if ((ret = h264_set_parameter_from_sps(h)) < 0)
             return ret;
     }
 
-    s->avctx->profile = ff_h264_get_profile(&h->sps);
-    s->avctx->level   = h->sps.level_idc;
-    s->avctx->refs    = h->sps.ref_frame_count;
+    h->avctx->profile = ff_h264_get_profile(&h->sps);
+    h->avctx->level   = h->sps.level_idc;
+    h->avctx->refs    = h->sps.ref_frame_count;
 
-    if (s->mb_width  != h->sps.mb_width ||
-        s->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag))
+    if (h->mb_width  != h->sps.mb_width ||
+        h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag))
         needs_reinit = 1;
 
-    s->mb_width  = h->sps.mb_width;
-    s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    h->mb_width  = h->sps.mb_width;
+    h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    h->mb_num    = h->mb_width * h->mb_height;
+    h->mb_stride = h->mb_width + 1;
 
-    h->b_stride = s->mb_width * 4;
+    h->b_stride = h->mb_width * 4;
 
-    s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
+    h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
 
-    s->width = 16 * s->mb_width - (2 >> CHROMA444) * FFMIN(h->sps.crop_right, (8 << CHROMA444) - 1);
+    h->width = 16 * h->mb_width - (2 >> CHROMA444) * FFMIN(h->sps.crop_right, (8 << CHROMA444) - 1);
     if (h->sps.frame_mbs_only_flag)
-        s->height = 16 * s->mb_height - (1 << s->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> s->chroma_y_shift) - 1);
+        h->height = 16 * h->mb_height - (1 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1);
     else
-        s->height = 16 * s->mb_height - (2 << s->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> s->chroma_y_shift) - 1);
+        h->height = 16 * h->mb_height - (2 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1);
 
-    if (FFALIGN(s->avctx->width,  16) == s->width &&
-        FFALIGN(s->avctx->height, 16) == s->height) {
-        s->width  = s->avctx->width;
-        s->height = s->avctx->height;
+    if (FFALIGN(h->avctx->width,  16) == h->width &&
+        FFALIGN(h->avctx->height, 16) == h->height) {
+        h->width  = h->avctx->width;
+        h->height = h->avctx->height;
     }
 
     if (h->sps.video_signal_type_present_flag) {
-        s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG
+        h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG
                                                   : AVCOL_RANGE_MPEG;
         if (h->sps.colour_description_present_flag) {
-            if (s->avctx->colorspace != h->sps.colorspace)
+            if (h->avctx->colorspace != h->sps.colorspace)
                 needs_reinit = 1;
-            s->avctx->color_primaries = h->sps.color_primaries;
-            s->avctx->color_trc       = h->sps.color_trc;
-            s->avctx->colorspace      = h->sps.colorspace;
+            h->avctx->color_primaries = h->sps.color_primaries;
+            h->avctx->color_trc       = h->sps.color_trc;
+            h->avctx->colorspace      = h->sps.colorspace;
         }
     }
 
-    if (s->context_initialized &&
-        (s->width  != s->avctx->width   ||
-         s->height != s->avctx->height  ||
-         needs_reinit                   ||
-         av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
+    if (h->context_initialized &&
+        (h->width  != h->avctx->width   ||
+         h->height != h->avctx->height  ||
+         needs_reinit)) {
 
         if (h != h0) {
-            av_log(s->avctx, AV_LOG_ERROR, "changing width/height on "
+            av_log(h->avctx, AV_LOG_ERROR, "changing width/height on "
                    "slice %d\n", h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
@@ -2775,31 +3110,30 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
 
         if ((ret = get_pixel_format(h)) < 0)
             return ret;
-        s->avctx->pix_fmt = ret;
+        h->avctx->pix_fmt = ret;
 
-        av_log(h->s.avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
-               "pix_fmt: %d\n", s->width, s->height, s->avctx->pix_fmt);
+        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
+               "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt);
 
         if ((ret = h264_slice_header_init(h, 1)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "h264_slice_header_init() failed\n");
             return ret;
         }
-        h->context_reinitialized = 1;
     }
-    if (!s->context_initialized) {
+    if (!h->context_initialized) {
         if (h != h0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "Cannot (re-)initialize context during parallel decoding.\n");
             return -1;
         }
 
         if ((ret = get_pixel_format(h)) < 0)
             return ret;
-        s->avctx->pix_fmt = ret;
+        h->avctx->pix_fmt = ret;
 
         if ((ret = h264_slice_header_init(h, 0)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "h264_slice_header_init() failed\n");
             return ret;
         }
@@ -2810,37 +3144,37 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         init_dequant_tables(h);
     }
 
-    h->frame_num = get_bits(&s->gb, h->sps.log2_max_frame_num);
+    h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
     h->mb_mbaff        = 0;
     h->mb_aff_frame    = 0;
-    last_pic_structure = s0->picture_structure;
-    last_pic_droppable = s0->droppable;
-    s->droppable       = h->nal_ref_idc == 0;
+    last_pic_structure = h0->picture_structure;
+    last_pic_droppable = h0->droppable;
+    h->droppable       = h->nal_ref_idc == 0;
     if (h->sps.frame_mbs_only_flag) {
-        s->picture_structure = PICT_FRAME;
+        h->picture_structure = PICT_FRAME;
     } else {
-        if (get_bits1(&s->gb)) { // field_pic_flag
-            s->picture_structure = PICT_TOP_FIELD + get_bits1(&s->gb); // bottom_field_flag
+        if (get_bits1(&h->gb)) { // field_pic_flag
+            h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
         } else {
-            s->picture_structure = PICT_FRAME;
+            h->picture_structure = PICT_FRAME;
             h->mb_aff_frame      = h->sps.mb_aff;
         }
     }
-    h->mb_field_decoding_flag = s->picture_structure != PICT_FRAME;
+    h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME;
 
     if (h0->current_slice != 0) {
-        if (last_pic_structure != s->picture_structure ||
-            last_pic_droppable != s->droppable) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+        if (last_pic_structure != h->picture_structure ||
+            last_pic_droppable != h->droppable) {
+            av_log(h->avctx, AV_LOG_ERROR,
                    "Changing field mode (%d -> %d) between slices is not allowed\n",
-                   last_pic_structure, s->picture_structure);
-            s->picture_structure = last_pic_structure;
-            s->droppable         = last_pic_droppable;
+                   last_pic_structure, h->picture_structure);
+            h->picture_structure = last_pic_structure;
+            h->droppable         = last_pic_droppable;
             return AVERROR_INVALIDDATA;
-        } else if (!s0->current_picture_ptr) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "unset current_picture_ptr on %d. slice\n",
+        } else if (!h0->cur_pic_ptr) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "unset cur_pic_ptr on %d. slice\n",
                    h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
@@ -2868,53 +3202,53 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
          * decode frames as "finished".
          * We have to do that before the "dummy" in-between frame allocation,
          * since that can modify s->current_picture_ptr. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.data[0]);
+            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
 
             /* Mark old field/frame as completed */
-            if (!last_pic_droppable && s0->current_picture_ptr->owner2 == s0) {
-                ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+            if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) {
+                ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                           last_pic_structure == PICT_BOTTOM_FIELD);
             }
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
                 if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                    ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                    ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                               last_pic_structure == PICT_TOP_FIELD);
                 }
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and previous field were reference, but had
                      * different frame_nums. Consider this field first in
                      * pair. Throw away previous field except for reference
                      * purposes. */
                     if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                        ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                        ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
                                                   last_pic_structure == PICT_TOP_FIELD);
                     }
                 } else {
                     /* Second field in complementary pair */
                     if (!((last_pic_structure   == PICT_TOP_FIELD &&
-                           s->picture_structure == PICT_BOTTOM_FIELD) ||
+                           h->picture_structure == PICT_BOTTOM_FIELD) ||
                           (last_pic_structure   == PICT_BOTTOM_FIELD &&
-                           s->picture_structure == PICT_TOP_FIELD))) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                           h->picture_structure == PICT_TOP_FIELD))) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "Invalid field mode combination %d/%d\n",
-                               last_pic_structure, s->picture_structure);
-                        s->picture_structure = last_pic_structure;
-                        s->droppable         = last_pic_droppable;
+                               last_pic_structure, h->picture_structure);
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
                         return AVERROR_INVALIDDATA;
-                    } else if (last_pic_droppable != s->droppable) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                    } else if (last_pic_droppable != h->droppable) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "Cannot combine reference and non-reference fields in the same frame\n");
-                        av_log_ask_for_sample(s->avctx, NULL);
-                        s->picture_structure = last_pic_structure;
-                        s->droppable         = last_pic_droppable;
+                        av_log_ask_for_sample(h->avctx, NULL);
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
                         return AVERROR_PATCHWELCOME;
                     }
 
@@ -2924,7 +3258,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                      * on that first field (or if that was us, we just did that above).
                      * By taking ownership, we assign responsibility to ourselves to
                      * report progress on the second field. */
-                    s0->current_picture_ptr->owner2 = s0;
+                    h0->cur_pic_ptr->owner2 = h0;
                 }
             }
         }
@@ -2932,20 +3266,20 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         while (h->frame_num != h->prev_frame_num &&
                h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
             Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
-            av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
+            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
                    h->frame_num, h->prev_frame_num);
             if (ff_h264_frame_start(h) < 0)
                 return -1;
             h->prev_frame_num++;
             h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
-            s->current_picture_ptr->frame_num = h->prev_frame_num;
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 1);
+            h->cur_pic_ptr->frame_num = h->prev_frame_num;
+            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 0);
+            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 1);
             if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
-                s->avctx->err_recognition & AV_EF_EXPLODE)
+                h->avctx->err_recognition & AV_EF_EXPLODE)
                 return ret;
             if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
-                (s->avctx->err_recognition & AV_EF_EXPLODE))
+                (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return AVERROR_INVALIDDATA;
             /* Error concealment: if a ref is missing, copy the previous ref in its place.
              * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
@@ -2957,7 +3291,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                 if (prev) {
                     av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize,
                                   (const uint8_t **)prev->f.data, prev->f.linesize,
-                                  s->avctx->pix_fmt, s->mb_width * 16, s->mb_height * 16);
+                                  h->avctx->pix_fmt, h->mb_width * 16, h->mb_height * 16);
                     h->short_ref[0]->poc = prev->poc + 2;
                 }
                 h->short_ref[0]->frame_num = h->prev_frame_num;
@@ -2967,61 +3301,61 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         /* See if we have a decoded first field looking for a pair...
          * We're using that to see whether to continue decoding in that
          * frame, or to allocate a new one. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.data[0]);
+            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
-                s0->current_picture_ptr = NULL;
-                s0->first_field         = FIELD_PICTURE;
+                h0->cur_pic_ptr = NULL;
+                h0->first_field = FIELD_PICTURE;
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and the previous field had different frame_nums.
                      * Consider this field first in pair. Throw away previous
                      * one except for reference purposes. */
-                    s0->first_field         = 1;
-                    s0->current_picture_ptr = NULL;
+                    h0->first_field = 1;
+                    h0->cur_pic_ptr = NULL;
                 } else {
                     /* Second field in complementary pair */
-                    s0->first_field = 0;
+                    h0->first_field = 0;
                 }
             }
         } else {
             /* Frame or first field in a potentially complementary pair */
-            s0->first_field = FIELD_PICTURE;
+            h0->first_field = FIELD_PICTURE;
         }
 
-        if (!FIELD_PICTURE || s0->first_field) {
+        if (!FIELD_PICTURE || h0->first_field) {
             if (ff_h264_frame_start(h) < 0) {
-                s0->first_field = 0;
+                h0->first_field = 0;
                 return -1;
             }
         } else {
-            ff_release_unused_pictures(s, 0);
+            release_unused_pictures(h, 0);
         }
     }
     if (h != h0 && (ret = clone_slice(h, h0)) < 0)
         return ret;
 
-    s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
+    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
 
-    assert(s->mb_num == s->mb_width * s->mb_height);
-    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num ||
-        first_mb_in_slice >= s->mb_num) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
+    assert(h->mb_num == h->mb_width * h->mb_height);
+    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= h->mb_num ||
+        first_mb_in_slice >= h->mb_num) {
+        av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
         return -1;
     }
-    s->resync_mb_x = s->mb_x =  first_mb_in_slice % s->mb_width;
-    s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;
-    if (s->picture_structure == PICT_BOTTOM_FIELD)
-        s->resync_mb_y = s->mb_y = s->mb_y + 1;
-    assert(s->mb_y < s->mb_height);
+    h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;
+    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE;
+    if (h->picture_structure == PICT_BOTTOM_FIELD)
+        h->resync_mb_y = h->mb_y = h->mb_y + 1;
+    assert(h->mb_y < h->mb_height);
 
-    if (s->picture_structure == PICT_FRAME) {
+    if (h->picture_structure == PICT_FRAME) {
         h->curr_pic_num = h->frame_num;
         h->max_pic_num  = 1 << h->sps.log2_max_frame_num;
     } else {
@@ -3030,26 +3364,26 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     }
 
     if (h->nal_unit_type == NAL_IDR_SLICE)
-        get_ue_golomb(&s->gb); /* idr_pic_id */
+        get_ue_golomb(&h->gb); /* idr_pic_id */
 
     if (h->sps.poc_type == 0) {
-        h->poc_lsb = get_bits(&s->gb, h->sps.log2_max_poc_lsb);
+        h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc_bottom = get_se_golomb(&s->gb);
+        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+            h->delta_poc_bottom = get_se_golomb(&h->gb);
     }
 
     if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {
-        h->delta_poc[0] = get_se_golomb(&s->gb);
+        h->delta_poc[0] = get_se_golomb(&h->gb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc[1] = get_se_golomb(&s->gb);
+        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+            h->delta_poc[1] = get_se_golomb(&h->gb);
     }
 
     init_poc(h);
 
     if (h->pps.redundant_pic_cnt_present)
-        h->redundant_pic_count = get_ue_golomb(&s->gb);
+        h->redundant_pic_count = get_ue_golomb(&h->gb);
 
     // set defaults, might be overridden a few lines later
     h->ref_count[0] = h->pps.ref_count[0];
@@ -3057,15 +3391,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
-            h->direct_spatial_mv_pred = get_bits1(&s->gb);
-        num_ref_idx_active_override_flag = get_bits1(&s->gb);
+            h->direct_spatial_mv_pred = get_bits1(&h->gb);
+        num_ref_idx_active_override_flag = get_bits1(&h->gb);
 
         if (num_ref_idx_active_override_flag) {
-            h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
+            h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
             if (h->ref_count[0] < 1)
                 return AVERROR_INVALIDDATA;
             if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-                h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
+                h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
                 if (h->ref_count[1] < 1)
                     return AVERROR_INVALIDDATA;
             }
@@ -3078,10 +3412,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     } else
         h->list_count = 0;
 
-    max_refs = s->picture_structure == PICT_FRAME ? 16 : 32;
+    max_refs = h->picture_structure == PICT_FRAME ? 16 : 32;
 
     if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
+        av_log(h->avctx, AV_LOG_ERROR, "reference overflow\n");
         h->ref_count[0] = h->ref_count[1] = 1;
         return AVERROR_INVALIDDATA;
     }
@@ -3095,19 +3429,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         return -1;
     }
 
-    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        s->last_picture_ptr = &h->ref_list[0][0];
-        s->last_picture_ptr->owner2 = s;
-        s->er.last_pic = s->last_picture_ptr;
-        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
-    }
-    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-        s->next_picture_ptr = &h->ref_list[1][0];
-        s->next_picture_ptr->owner2 = s;
-        s->er.next_pic = s->next_picture_ptr;
-        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
-    }
-
     if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
         (h->pps.weighted_bipred_idc == 1 &&
          h->slice_type_nos == AV_PICTURE_TYPE_B))
@@ -3129,10 +3450,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     // further down the line. This may break decoding if the first slice is
     // corrupt, thus we only do this if frame-mt is enabled.
     if (h->nal_ref_idc &&
-        ff_h264_decode_ref_pic_marking(h0, &s->gb,
-                            !(s->avctx->active_thread_type & FF_THREAD_FRAME) ||
+        ff_h264_decode_ref_pic_marking(h0, &h->gb,
+                            !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
                             h0->current_slice == 0) < 0 &&
-        (s->avctx->err_recognition & AV_EF_EXPLODE))
+        (h->avctx->err_recognition & AV_EF_EXPLODE))
         return AVERROR_INVALIDDATA;
 
     if (FRAME_MBAFF) {
@@ -3149,37 +3470,37 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     ff_h264_direct_ref_list_init(h);
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I && h->pps.cabac) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
+            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
             return -1;
         }
         h->cabac_init_idc = tmp;
     }
 
     h->last_qscale_diff = 0;
-    tmp = h->pps.init_qp + get_se_golomb(&s->gb);
+    tmp = h->pps.init_qp + get_se_golomb(&h->gb);
     if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {
-        av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
+        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
         return -1;
     }
-    s->qscale       = tmp;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->qscale       = tmp;
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
     // FIXME qscale / qp ... stuff
     if (h->slice_type == AV_PICTURE_TYPE_SP)
-        get_bits1(&s->gb); /* sp_for_switch_flag */
+        get_bits1(&h->gb); /* sp_for_switch_flag */
     if (h->slice_type == AV_PICTURE_TYPE_SP ||
         h->slice_type == AV_PICTURE_TYPE_SI)
-        get_se_golomb(&s->gb); /* slice_qs_delta */
+        get_se_golomb(&h->gb); /* slice_qs_delta */
 
     h->deblocking_filter     = 1;
     h->slice_alpha_c0_offset = 52;
     h->slice_beta_offset     = 52;
     if (h->pps.deblocking_filter_parameters_present) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "deblocking_filter_idc %u out of range\n", tmp);
             return -1;
         }
@@ -3188,11 +3509,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             h->deblocking_filter ^= 1;  // 1<->0
 
         if (h->deblocking_filter) {
-            h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1;
-            h->slice_beta_offset     += get_se_golomb(&s->gb) << 1;
+            h->slice_alpha_c0_offset += get_se_golomb(&h->gb) << 1;
+            h->slice_beta_offset     += get_se_golomb(&h->gb) << 1;
             if (h->slice_alpha_c0_offset > 104U ||
                 h->slice_beta_offset     > 104U) {
-                av_log(s->avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "deblocking filter parameters %d %d out of range\n",
                        h->slice_alpha_c0_offset, h->slice_beta_offset);
                 return -1;
@@ -3200,29 +3521,29 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         }
     }
 
-    if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
+    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
          h->slice_type_nos != AV_PICTURE_TYPE_I) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
          h->slice_type_nos == AV_PICTURE_TYPE_B) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
          h->nal_ref_idc == 0))
         h->deblocking_filter = 0;
 
     if (h->deblocking_filter == 1 && h0->max_contexts > 1) {
-        if (s->avctx->flags2 & CODEC_FLAG2_FAST) {
+        if (h->avctx->flags2 & CODEC_FLAG2_FAST) {
             /* Cheat slightly for speed:
              * Do not bother to deblock across slices. */
             h->deblocking_filter = 2;
         } else {
             h0->max_contexts = 1;
             if (!h0->single_decode_warning) {
-                av_log(s->avctx, AV_LOG_INFO,
+                av_log(h->avctx, AV_LOG_INFO,
                        "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");
                 h0->single_decode_warning = 1;
             }
             if (h != h0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "Deblocking switched inside frame.\n");
                 return 1;
             }
@@ -3238,7 +3559,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     h0->last_slice_type = slice_type;
     h->slice_num = ++h0->current_slice;
     if (h->slice_num >= MAX_SLICES) {
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Too many slices, increase MAX_SLICES and recompile\n");
     }
 
@@ -3276,26 +3597,26 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     }
 
     // FIXME: fix draw_edges + PAFF + frame threads
-    h->emu_edge_width  = (s->flags & CODEC_FLAG_EMU_EDGE ||
+    h->emu_edge_width  = (h->flags & CODEC_FLAG_EMU_EDGE ||
                           (!h->sps.frame_mbs_only_flag &&
-                           s->avctx->active_thread_type))
+                           h->avctx->active_thread_type))
                          ? 0 : 16;
     h->emu_edge_height = (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
 
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG,
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(h->avctx, AV_LOG_DEBUG,
                "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
                h->slice_num,
-               (s->picture_structure == PICT_FRAME ? "F" : s->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
+               (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
                first_mb_in_slice,
                av_get_picture_type_char(h->slice_type),
                h->slice_type_fixed ? " fix" : "",
                h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
                pps_id, h->frame_num,
-               s->current_picture_ptr->field_poc[0],
-               s->current_picture_ptr->field_poc[1],
+               h->cur_pic_ptr->field_poc[0],
+               h->cur_pic_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
-               s->qscale,
+               h->qscale,
                h->deblocking_filter,
                h->slice_alpha_c0_offset / 2 - 26, h->slice_beta_offset / 2 - 26,
                h->use_weight,
@@ -3325,7 +3646,6 @@ int ff_h264_get_slice_type(const H264Context *h)
 }
 
 static av_always_inline void fill_filter_caches_inter(H264Context *h,
-                                                      MpegEncContext *const s,
                                                       int mb_type, int top_xy,
                                                       int left_xy[LEFT_MBS],
                                                       int top_type,
@@ -3340,11 +3660,11 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
             const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
             const int b8_xy = 4 * top_xy + 2;
             int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
-            AV_COPY128(mv_dst - 1 * 8, s->current_picture.f.motion_val[list][b_xy + 0]);
+            AV_COPY128(mv_dst - 1 * 8, h->cur_pic.f.motion_val[list][b_xy + 0]);
             ref_cache[0 - 1 * 8] =
-            ref_cache[1 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
+            ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 0]];
             ref_cache[2 - 1 * 8] =
-            ref_cache[3 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 1]];
+            ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 1]];
         } else {
             AV_ZERO128(mv_dst - 1 * 8);
             AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u);
@@ -3355,14 +3675,14 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
                 const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                 const int b8_xy = 4 * left_xy[LTOP] + 1;
                 int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
-                AV_COPY32(mv_dst - 1 +  0, s->current_picture.f.motion_val[list][b_xy + b_stride * 0]);
-                AV_COPY32(mv_dst - 1 +  8, s->current_picture.f.motion_val[list][b_xy + b_stride * 1]);
-                AV_COPY32(mv_dst - 1 + 16, s->current_picture.f.motion_val[list][b_xy + b_stride * 2]);
-                AV_COPY32(mv_dst - 1 + 24, s->current_picture.f.motion_val[list][b_xy + b_stride * 3]);
+                AV_COPY32(mv_dst - 1 +  0, h->cur_pic.f.motion_val[list][b_xy + b_stride * 0]);
+                AV_COPY32(mv_dst - 1 +  8, h->cur_pic.f.motion_val[list][b_xy + b_stride * 1]);
+                AV_COPY32(mv_dst - 1 + 16, h->cur_pic.f.motion_val[list][b_xy + b_stride * 2]);
+                AV_COPY32(mv_dst - 1 + 24, h->cur_pic.f.motion_val[list][b_xy + b_stride * 3]);
                 ref_cache[-1 +  0] =
-                ref_cache[-1 +  8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 0]];
+                ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 0]];
                 ref_cache[-1 + 16] =
-                ref_cache[-1 + 24] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 1]];
+                ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 1]];
             } else {
                 AV_ZERO32(mv_dst - 1 +  0);
                 AV_ZERO32(mv_dst - 1 +  8);
@@ -3386,7 +3706,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        int8_t *ref = &s->current_picture.f.ref_index[list][4 * mb_xy];
+        int8_t *ref = &h->cur_pic.f.ref_index[list][4 * mb_xy];
         int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
         uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101;
         uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101;
@@ -3397,7 +3717,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        int16_t(*mv_src)[2] = &s->current_picture.f.motion_val[list][4 * s->mb_x + 4 * s->mb_y * b_stride];
+        int16_t(*mv_src)[2] = &h->cur_pic.f.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride];
         AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride);
         AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride);
         AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride);
@@ -3411,31 +3731,30 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
  */
 static int fill_filter_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int top_xy, left_xy[LEFT_MBS];
     int top_type, left_type[LEFT_MBS];
     uint8_t *nnz;
     uint8_t *nnz_cache;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD);
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
 
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LTOP] -= s->mb_stride;
+                left_xy[LTOP] -= h->mb_stride;
         } else {
             if (curr_mb_field_flag)
-                top_xy += s->mb_stride &
-                    (((s->current_picture.f.mb_type[top_xy] >> 7) & 1) - 1);
+                top_xy += h->mb_stride &
+                    (((h->cur_pic.f.mb_type[top_xy] >> 7) & 1) - 1);
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LBOT] += s->mb_stride;
+                left_xy[LBOT] += h->mb_stride;
         }
     }
 
@@ -3447,25 +3766,25 @@ static int fill_filter_caches(H264Context *h, int mb_type)
          * This is a conservative estimate: could also check beta_offset
          * and more accurate chroma_qp. */
         int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
-        int qp        = s->current_picture.f.qscale_table[mb_xy];
+        int qp        = h->cur_pic.f.qscale_table[mb_xy];
         if (qp <= qp_thresh &&
             (left_xy[LTOP] < 0 ||
-             ((qp + s->current_picture.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
+             ((qp + h->cur_pic.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
             (top_xy < 0 ||
-             ((qp + s->current_picture.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
+             ((qp + h->cur_pic.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
             if (!FRAME_MBAFF)
                 return 1;
             if ((left_xy[LTOP] < 0 ||
-                 ((qp + s->current_picture.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
-                (top_xy < s->mb_stride ||
-                 ((qp + s->current_picture.f.qscale_table[top_xy - s->mb_stride] + 1) >> 1) <= qp_thresh))
+                 ((qp + h->cur_pic.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
+                (top_xy < h->mb_stride ||
+                 ((qp + h->cur_pic.f.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))
                 return 1;
         }
     }
 
-    top_type        = s->current_picture.f.mb_type[top_xy];
-    left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    top_type        = h->cur_pic.f.mb_type[top_xy];
+    left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
+    left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
     if (h->deblocking_filter == 2) {
         if (h->slice_table[top_xy] != h->slice_num)
             top_type = 0;
@@ -3484,10 +3803,10 @@ static int fill_filter_caches(H264Context *h, int mb_type)
     if (IS_INTRA(mb_type))
         return 0;
 
-    fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+    fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                              top_type, left_type, mb_xy, 0);
     if (h->list_count == 2)
-        fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+        fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                                  top_type, left_type, mb_xy, 1);
 
     nnz       = h->non_zero_count[mb_xy];
@@ -3557,57 +3876,56 @@ static int fill_filter_caches(H264Context *h, int mb_type)
 
 static void loop_filter(H264Context *h, int start_x, int end_x)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize, mb_x, mb_y;
-    const int end_mb_y       = s->mb_y + FRAME_MBAFF;
+    const int end_mb_y       = h->mb_y + FRAME_MBAFF;
     const int old_slice_type = h->slice_type;
     const int pixel_shift    = h->pixel_shift;
-    const int block_h        = 16 >> s->chroma_y_shift;
+    const int block_h        = 16 >> h->chroma_y_shift;
 
     if (h->deblocking_filter) {
         for (mb_x = start_x; mb_x < end_x; mb_x++)
             for (mb_y = end_mb_y - FRAME_MBAFF; mb_y <= end_mb_y; mb_y++) {
                 int mb_xy, mb_type;
-                mb_xy         = h->mb_xy = mb_x + mb_y * s->mb_stride;
+                mb_xy         = h->mb_xy = mb_x + mb_y * h->mb_stride;
                 h->slice_num  = h->slice_table[mb_xy];
-                mb_type       = s->current_picture.f.mb_type[mb_xy];
+                mb_type       = h->cur_pic.f.mb_type[mb_xy];
                 h->list_count = h->list_counts[mb_xy];
 
                 if (FRAME_MBAFF)
                     h->mb_mbaff               =
                     h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);
 
-                s->mb_x = mb_x;
-                s->mb_y = mb_y;
-                dest_y  = s->current_picture.f.data[0] +
-                          ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
-                dest_cb = s->current_picture.f.data[1] +
+                h->mb_x = mb_x;
+                h->mb_y = mb_y;
+                dest_y  = h->cur_pic.f.data[0] +
+                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;
+                dest_cb = h->cur_pic.f.data[1] +
                           (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
-                dest_cr = s->current_picture.f.data[2] +
+                          mb_y * h->uvlinesize * block_h;
+                dest_cr = h->cur_pic.f.data[2] +
                           (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
+                          mb_y * h->uvlinesize * block_h;
                 // FIXME simplify above
 
                 if (MB_FIELD) {
-                    linesize   = h->mb_linesize   = s->linesize   * 2;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
+                    linesize   = h->mb_linesize   = h->linesize   * 2;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize * 2;
                     if (mb_y & 1) { // FIXME move out of this function?
-                        dest_y  -= s->linesize   * 15;
-                        dest_cb -= s->uvlinesize * (block_h - 1);
-                        dest_cr -= s->uvlinesize * (block_h - 1);
+                        dest_y  -= h->linesize   * 15;
+                        dest_cb -= h->uvlinesize * (block_h - 1);
+                        dest_cr -= h->uvlinesize * (block_h - 1);
                     }
                 } else {
-                    linesize   = h->mb_linesize   = s->linesize;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+                    linesize   = h->mb_linesize   = h->linesize;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize;
                 }
                 backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
                 if (fill_filter_caches(h, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mb_xy]);
+                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mb_xy]);
+                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mb_xy]);
 
                 if (FRAME_MBAFF) {
                     ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
@@ -3619,20 +3937,19 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
             }
     }
     h->slice_type   = old_slice_type;
-    s->mb_x         = end_x;
-    s->mb_y         = end_mb_y - FRAME_MBAFF;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->mb_x         = end_x;
+    h->mb_y         = end_mb_y - FRAME_MBAFF;
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
 }
 
 static void predict_field_decoding_flag(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+    const int mb_xy = h->mb_x + h->mb_y * h->mb_stride;
     int mb_type     = (h->slice_table[mb_xy - 1] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - 1] :
-                      (h->slice_table[mb_xy - s->mb_stride] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - s->mb_stride] : 0;
+                      h->cur_pic.f.mb_type[mb_xy - 1] :
+                      (h->slice_table[mb_xy - h->mb_stride] == h->slice_num) ?
+                      h->cur_pic.f.mb_type[mb_xy - h->mb_stride] : 0;
     h->mb_mbaff     = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
 }
 
@@ -3641,9 +3958,8 @@ static void predict_field_decoding_flag(H264Context *h)
  */
 static void decode_finish_row(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int top            = 16 * (s->mb_y      >> FIELD_PICTURE);
-    int pic_height     = 16 *  s->mb_height >> FIELD_PICTURE;
+    int top            = 16 * (h->mb_y      >> FIELD_PICTURE);
+    int pic_height     = 16 *  h->mb_height >> FIELD_PICTURE;
     int height         =  16      << FRAME_MBAFF;
     int deblock_border = (16 + 4) << FRAME_MBAFF;
 
@@ -3662,19 +3978,19 @@ static void decode_finish_row(H264Context *h)
         top    = 0;
     }
 
-    ff_mpeg_draw_horiz_band(s, top, height);
+    ff_h264_draw_horiz_band(h, top, height);
 
-    if (s->droppable)
+    if (h->droppable)
         return;
 
-    ff_thread_report_progress(&s->current_picture_ptr->f, top + height - 1,
-                              s->picture_structure == PICT_BOTTOM_FIELD);
+    ff_thread_report_progress(&h->cur_pic_ptr->f, top + height - 1,
+                              h->picture_structure == PICT_BOTTOM_FIELD);
 }
 
 static void er_add_slice(H264Context *h, int startx, int starty,
                          int endx, int endy, int status)
 {
-    ERContext *er = &h->s.er;
+    ERContext *er = &h->er;
 
     er->ref_count = h->ref_count[0];
     ff_er_add_slice(er, startx, starty, endx, endy, status);
@@ -3683,24 +3999,23 @@ static void er_add_slice(H264Context *h, int startx, int starty,
 static int decode_slice(struct AVCodecContext *avctx, void *arg)
 {
     H264Context *h = *(void **)arg;
-    MpegEncContext *const s = &h->s;
-    int lf_x_start = s->mb_x;
+    int lf_x_start = h->mb_x;
 
-    s->mb_skip_run = -1;
+    h->mb_skip_run = -1;
 
-    h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME ||
-                    s->codec_id != AV_CODEC_ID_H264 ||
-                    (CONFIG_GRAY && (s->flags & CODEC_FLAG_GRAY));
+    h->is_complex = FRAME_MBAFF || h->picture_structure != PICT_FRAME ||
+                    avctx->codec_id != AV_CODEC_ID_H264 ||
+                    (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
 
     if (h->pps.cabac) {
         /* realign */
-        align_get_bits(&s->gb);
+        align_get_bits(&h->gb);
 
         /* init cabac */
         ff_init_cabac_states(&h->cabac);
         ff_init_cabac_decoder(&h->cabac,
-                              s->gb.buffer + get_bits_count(&s->gb) / 8,
-                              (get_bits_left(&s->gb) + 7) / 8);
+                              h->gb.buffer + get_bits_count(&h->gb) / 8,
+                              (get_bits_left(&h->gb) + 7) / 8);
 
         ff_h264_init_cabac_states(h);
 
@@ -3715,53 +4030,53 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+                h->mb_y++;
 
                 ret = ff_h264_decode_mb_cabac(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
             eos = get_cabac_terminate(&h->cabac);
 
-            if ((s->workaround_bugs & FF_BUG_TRUNCATED) &&
+            if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
                 h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END);
-                if (s->mb_x >= lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x + 1);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
+                                h->mb_y, ER_MB_END);
+                if (h->mb_x >= lf_x_start)
+                    loop_filter(h, lf_x_start, h->mb_x + 1);
                 return 0;
             }
             if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d, bytestream (%td)\n",
-                       s->mb_x, s->mb_y,
+                       h->mb_x, h->mb_y,
                        h->cabac.bytestream_end - h->cabac.bytestream);
-                er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                h->mb_y, ER_MB_ERROR);
                 return -1;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
+                ++h->mb_y;
                 if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                    ++h->mb_y;
+                    if (FRAME_MBAFF && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
             }
 
-            if (eos || s->mb_y >= s->mb_height) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END);
-                if (s->mb_x > lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x);
+            if (eos || h->mb_y >= h->mb_height) {
+                tprintf(h->avctx, "slice end %d %d\n",
+                        get_bits_count(&h->gb), h->gb.size_in_bits);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
+                                h->mb_y, ER_MB_END);
+                if (h->mb_x > lf_x_start)
+                    loop_filter(h, lf_x_start, h->mb_x);
                 return 0;
             }
         }
@@ -3774,45 +4089,45 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+                h->mb_y++;
                 ret = ff_h264_decode_mb_cavlc(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
 
             if (ret < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
-                       "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
-                er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR);
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                h->mb_y, ER_MB_ERROR);
                 return -1;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
+                ++h->mb_y;
                 if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                    ++h->mb_y;
+                    if (FRAME_MBAFF && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
-                if (s->mb_y >= s->mb_height) {
-                    tprintf(s->avctx, "slice end %d %d\n",
-                            get_bits_count(&s->gb), s->gb.size_in_bits);
+                if (h->mb_y >= h->mb_height) {
+                    tprintf(h->avctx, "slice end %d %d\n",
+                            get_bits_count(&h->gb), h->gb.size_in_bits);
 
-                    if (get_bits_left(&s->gb) == 0) {
-                        er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x - 1, s->mb_y,
+                    if (get_bits_left(&h->gb) == 0) {
+                        er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                        h->mb_x - 1, h->mb_y,
                                         ER_MB_END);
 
                         return 0;
                     } else {
-                        er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x - 1, s->mb_y,
+                        er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                        h->mb_x - 1, h->mb_y,
                                         ER_MB_END);
 
                         return -1;
@@ -3820,20 +4135,20 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 }
             }
 
-            if (get_bits_left(&s->gb) <= 0 && s->mb_skip_run <= 0) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                if (get_bits_left(&s->gb) == 0) {
-                    er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
-                                    s->mb_x - 1, s->mb_y,
+            if (get_bits_left(&h->gb) <= 0 && h->mb_skip_run <= 0) {
+                tprintf(h->avctx, "slice end %d %d\n",
+                        get_bits_count(&h->gb), h->gb.size_in_bits);
+                if (get_bits_left(&h->gb) == 0) {
+                    er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                    h->mb_x - 1, h->mb_y,
                                     ER_MB_END);
-                    if (s->mb_x > lf_x_start)
-                        loop_filter(h, lf_x_start, s->mb_x);
+                    if (h->mb_x > lf_x_start)
+                        loop_filter(h, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
-                    er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                    s->mb_y, ER_MB_ERROR);
+                    er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                    h->mb_y, ER_MB_ERROR);
 
                     return -1;
                 }
@@ -3850,21 +4165,19 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
  */
 static int execute_decode_slices(H264Context *h, int context_count)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx;
     int i;
 
-    if (s->avctx->hwaccel ||
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+    if (h->avctx->hwaccel ||
+        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
         return 0;
     if (context_count == 1) {
         return decode_slice(avctx, &h);
     } else {
         for (i = 1; i < context_count; i++) {
             hx                    = h->thread_context[i];
-            hx->s.err_recognition = avctx->err_recognition;
-            hx->s.er.error_count  = 0;
+            hx->er.error_count  = 0;
         }
 
         avctx->execute(avctx, decode_slice, h->thread_context,
@@ -3872,12 +4185,12 @@ static int execute_decode_slices(H264Context *h, int context_count)
 
         /* pull back stuff from slices to master context */
         hx                   = h->thread_context[context_count - 1];
-        s->mb_x              = hx->s.mb_x;
-        s->mb_y              = hx->s.mb_y;
-        s->droppable         = hx->s.droppable;
-        s->picture_structure = hx->s.picture_structure;
+        h->mb_x              = hx->mb_x;
+        h->mb_y              = hx->mb_y;
+        h->droppable         = hx->droppable;
+        h->picture_structure = hx->picture_structure;
         for (i = 1; i < context_count; i++)
-            h->s.er.error_count += h->thread_context[i]->s.er.error_count;
+            h->er.error_count += h->thread_context[i]->er.error_count;
     }
 
     return 0;
@@ -3886,8 +4199,7 @@ static int execute_decode_slices(H264Context *h, int context_count)
 static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                             int parse_extradata)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx; ///< thread context
     int buf_index;
     int context_count;
@@ -3896,11 +4208,11 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
     int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
     int nal_index;
 
-    h->max_contexts = s->slice_context_count;
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS)) {
+    h->max_contexts = h->slice_context_count;
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
         h->current_slice = 0;
-        if (!s->first_field)
-            s->current_picture_ptr = NULL;
+        if (!h->first_field)
+            h->cur_pic_ptr = NULL;
         ff_h264_reset_sei(h);
     }
 
@@ -3924,7 +4236,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                 for (i = 0; i < h->nal_length_size; i++)
                     nalsize = (nalsize << 8) | buf[buf_index++];
                 if (nalsize <= 0 || nalsize > buf_size - buf_index) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "AVC: nal size %d\n", nalsize);
                     break;
                 }
@@ -3957,25 +4269,25 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                 goto end;
             }
             i = buf_index + consumed;
-            if ((s->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
+            if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
                 buf[i]     == 0x00 && buf[i + 1] == 0x00 &&
                 buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)
-                s->workaround_bugs |= FF_BUG_TRUNCATED;
+                h->workaround_bugs |= FF_BUG_TRUNCATED;
 
-            if (!(s->workaround_bugs & FF_BUG_TRUNCATED))
+            if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
                 while (ptr[dst_length - 1] == 0 && dst_length > 0)
                     dst_length--;
             bit_length = !dst_length ? 0
                                      : (8 * dst_length -
                                         decode_rbsp_trailing(h, ptr + dst_length - 1));
 
-            if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                av_log(h->s.avctx, AV_LOG_DEBUG,
+            if (h->avctx->debug & FF_DEBUG_STARTCODE)
+                av_log(h->avctx, AV_LOG_DEBUG,
                        "NAL %d at %d/%d length %d\n",
                        hx->nal_unit_type, buf_index, buf_size, dst_length);
 
             if (h->is_avc && (nalsize != consumed) && nalsize)
-                av_log(h->s.avctx, AV_LOG_DEBUG,
+                av_log(h->avctx, AV_LOG_DEBUG,
                        "AVC: Consumed only %d bytes instead of %d\n",
                        consumed, nalsize);
 
@@ -3995,8 +4307,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                 case NAL_DPA:
                 case NAL_IDR_SLICE:
                 case NAL_SLICE:
-                    init_get_bits(&hx->s.gb, ptr, bit_length);
-                    if (!get_ue_golomb(&hx->s.gb))
+                    init_get_bits(&hx->gb, ptr, bit_length);
+                    if (!get_ue_golomb(&hx->gb))
                         nals_needed = nal_index;
                 }
                 continue;
@@ -4011,7 +4323,7 @@ again:
              * parsing. Decoding slices is not possible in codec init
              * with frame-mt */
             if (parse_extradata && HAVE_THREADS &&
-                (s->avctx->active_thread_type & FF_THREAD_FRAME) &&
+                (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
                 (hx->nal_unit_type != NAL_PPS &&
                  hx->nal_unit_type != NAL_SPS)) {
                 av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
@@ -4022,35 +4334,35 @@ again:
             switch (hx->nal_unit_type) {
             case NAL_IDR_SLICE:
                 if (h->nal_unit_type != NAL_IDR_SLICE) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "Invalid mix of idr and non-idr slices\n");
                     buf_index = -1;
                     goto end;
                 }
                 idr(h); // FIXME ensure we don't lose some frames if there is reordering
             case NAL_SLICE:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
+                init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr        =
-                    hx->inter_gb_ptr    = &hx->s.gb;
-                hx->s.data_partitioning = 0;
+                    hx->inter_gb_ptr    = &hx->gb;
+                hx->data_partitioning = 0;
 
                 if ((err = decode_slice_header(hx, h)))
                     break;
 
-                s->current_picture_ptr->f.key_frame |=
+                h->cur_pic_ptr->f.key_frame |=
                     (hx->nal_unit_type == NAL_IDR_SLICE) ||
                     (h->sei_recovery_frame_cnt >= 0);
 
                 if (h->current_slice == 1) {
-                    if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
+                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
                         decode_postinit(h, nal_index >= nals_needed);
 
-                    if (s->avctx->hwaccel &&
-                        s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
+                    if (h->avctx->hwaccel &&
+                        h->avctx->hwaccel->start_frame(h->avctx, NULL, 0) < 0)
                         return -1;
                     if (CONFIG_H264_VDPAU_DECODER &&
-                        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-                        ff_vdpau_h264_picture_start(s);
+                        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+                        ff_vdpau_h264_picture_start(h);
                 }
 
                 if (hx->redundant_pic_count == 0 &&
@@ -4067,26 +4379,26 @@ again:
                                                          consumed) < 0)
                             return -1;
                     } else if (CONFIG_H264_VDPAU_DECODER &&
-                               s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
+                               h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
                         static const uint8_t start_code[] = {
                             0x00, 0x00, 0x01 };
-                        ff_vdpau_add_data_chunk(s, start_code,
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], start_code,
                                                 sizeof(start_code));
-                        ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed],
+                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], &buf[buf_index - consumed],
                                                 consumed);
                     } else
                         context_count++;
                 }
                 break;
             case NAL_DPA:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
+                init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr =
                 hx->inter_gb_ptr = NULL;
 
                 if ((err = decode_slice_header(hx, h)) < 0)
                     break;
 
-                hx->s.data_partitioning = 1;
+                hx->data_partitioning = 1;
                 break;
             case NAL_DPB:
                 init_get_bits(&hx->intra_gb, ptr, bit_length);
@@ -4098,9 +4410,8 @@ again:
 
                 if (hx->redundant_pic_count == 0 &&
                     hx->intra_gb_ptr &&
-                    hx->s.data_partitioning &&
-                    s->current_picture_ptr &&
-                    s->context_initialized &&
+                    hx->data_partitioning &&
+                    h->cur_pic_ptr && h->context_initialized &&
                     (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&
                     (avctx->skip_frame < AVDISCARD_BIDIR  ||
                      hx->slice_type_nos != AV_PICTURE_TYPE_B) &&
@@ -4110,16 +4421,16 @@ again:
                     context_count++;
                 break;
             case NAL_SEI:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_sei(h);
                 break;
             case NAL_SPS:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 if (ff_h264_decode_seq_parameter_set(h) < 0 &&
                     h->is_avc && (nalsize != consumed) && nalsize) {
-                    av_log(h->s.avctx, AV_LOG_DEBUG,
+                    av_log(h->avctx, AV_LOG_DEBUG,
                            "SPS decoding failure, trying again with the complete NAL\n");
-                    init_get_bits(&s->gb, buf + buf_index + 1 - consumed,
+                    init_get_bits(&h->gb, buf + buf_index + 1 - consumed,
                                   8 * (nalsize - 1));
                     ff_h264_decode_seq_parameter_set(h);
                 }
@@ -4130,7 +4441,7 @@ again:
                 }
                 break;
             case NAL_PPS:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_picture_parameter_set(h, bit_length);
                 break;
             case NAL_AUD:
@@ -4153,7 +4464,7 @@ again:
             }
 
             if (err < 0)
-                av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n");
+                av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
             else if (err == 1) {
                 /* Slice could not be decoded in parallel mode, copy down
                  * NAL unit stuff to context 0 and restart. Note that
@@ -4171,10 +4482,10 @@ again:
 
 end:
     /* clean up */
-    if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s &&
-        !s->droppable) {
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
+    if (h->cur_pic_ptr && h->cur_pic_ptr->owner2 == h &&
+        !h->droppable) {
+        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
     return buf_index;
@@ -4183,7 +4494,7 @@ end:
 /**
  * Return the number of bytes consumed for building the current frame.
  */
-static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size)
+static int get_consumed_bytes(int pos, int buf_size)
 {
     if (pos == 0)
         pos = 1;          // avoid infinite loops (i doubt that is needed but ...)
@@ -4199,12 +4510,10 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     H264Context *h     = avctx->priv_data;
-    MpegEncContext *s  = &h->s;
     AVFrame *pict      = data;
     int buf_index      = 0;
 
-    s->flags  = avctx->flags;
-    s->flags2 = avctx->flags2;
+    h->flags  = avctx->flags;
 
     /* end of stream, output what is still in the buffers */
 out:
@@ -4212,7 +4521,7 @@ out:
         Picture *out;
         int i, out_idx;
 
-        s->current_picture_ptr = NULL;
+        h->cur_pic_ptr = NULL;
 
         // FIXME factorize this with the output code below
         out     = h->delayed_pic[0];
@@ -4242,25 +4551,24 @@ out:
     if (buf_index < 0)
         return -1;
 
-    if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
+    if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
         buf_size = 0;
         goto out;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr) {
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
         if (avctx->skip_frame >= AVDISCARD_NONREF)
             return 0;
         av_log(avctx, AV_LOG_ERROR, "no frame!\n");
         return -1;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) ||
-        (s->mb_y >= s->mb_height && s->mb_height)) {
-        if (s->flags2 & CODEC_FLAG2_CHUNKS)
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
+        (h->mb_y >= h->mb_height && h->mb_height)) {
+        if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
             decode_postinit(h, 1);
 
         field_end(h, 0);
-        h->context_reinitialized = 0;
 
         if (!h->next_output_pic) {
             /* Wait for second field. */
@@ -4272,9 +4580,8 @@ out:
     }
 
     assert(pict->data[0] || !*got_frame);
-    ff_print_debug_info(s, pict);
 
-    return get_consumed_bytes(s, buf_index, buf_size);
+    return get_consumed_bytes(buf_index, buf_size);
 }
 
 av_cold void ff_h264_free_context(H264Context *h)
@@ -4293,13 +4600,16 @@ av_cold void ff_h264_free_context(H264Context *h)
 static av_cold int h264_decode_end(AVCodecContext *avctx)
 {
     H264Context *h    = avctx->priv_data;
-    MpegEncContext *s = &h->s;
+    int i;
 
     ff_h264_free_context(h);
 
-    ff_MPV_common_end(s);
-
-    // memset(h, 0, sizeof(H264Context));
+    if (h->DPB && !h->avctx->internal->is_copy) {
+        for (i = 0; i < h->picture_count; i++) {
+            free_picture(h, &h->DPB[i]);
+        }
+    }
+    av_freep(&h->DPB);
 
     return 0;
 }
index c4addbe..45c134e 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "libavutil/intreadwrite.h"
 #include "cabac.h"
+#include "get_bits.h"
 #include "mpegvideo.h"
 #include "h264chroma.h"
 #include "h264dsp.h"
@@ -60,7 +61,7 @@
 #define MB_MBAFF    h->mb_mbaff
 #define MB_FIELD    h->mb_field_decoding_flag
 #define FRAME_MBAFF h->mb_aff_frame
-#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
+#define FIELD_PICTURE (h->picture_structure != PICT_FRAME)
 #define LEFT_MBS 2
 #define LTOP     0
 #define LBOT     1
@@ -250,15 +251,42 @@ typedef struct MMCO {
  * H264Context
  */
 typedef struct H264Context {
-    MpegEncContext s;
+    AVCodecContext *avctx;
+    DSPContext       dsp;
+    VideoDSPContext vdsp;
     H264DSPContext h264dsp;
     H264ChromaContext h264chroma;
     H264QpelContext h264qpel;
+    MotionEstContext me;
+    ParseContext parse_context;
+    GetBitContext gb;
+    ERContext er;
+
+    Picture *DPB;
+    Picture *cur_pic_ptr;
+    Picture cur_pic;
+    int picture_count;
+    int picture_range_start, picture_range_end;
+
     int pixel_shift;    ///< 0 for 8-bit H264, 1 for high-bit-depth H264
     int chroma_qp[2];   // QPc
 
     int qp_thresh;      ///< QP threshold to skip loopfilter
 
+    int width, height;
+    int linesize, uvlinesize;
+    int chroma_x_shift, chroma_y_shift;
+
+    int qscale;
+    int droppable;
+    int data_partitioning;
+    int coded_picture_number;
+    int low_delay;
+
+    int context_initialized;
+    int flags;
+    int workaround_bugs;
+
     int prev_mb_skipped;
     int next_mb_skipped;
 
@@ -348,6 +376,8 @@ typedef struct H264Context {
     int mb_aff_frame;
     int mb_field_decoding_flag;
     int mb_mbaff;               ///< mb_aff_frame && mb_field_decoding_flag
+    int picture_structure;
+    int first_field;
 
     DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4];
 
@@ -424,6 +454,13 @@ typedef struct H264Context {
 
     int x264_build;
 
+    int mb_x, mb_y;
+    int resync_mb_x;
+    int resync_mb_y;
+    int mb_skip_run;
+    int mb_height, mb_width;
+    int mb_stride;
+    int mb_num;
     int mb_xy;
 
     int is_complex;
@@ -448,7 +485,8 @@ typedef struct H264Context {
     int nal_length_size;  ///< Number of bytes used for nal length (1, 2 or 4)
     int got_first;        ///< this flag is != 0 if we've parsed a frame
 
-    int context_reinitialized;
+    int bit_depth_luma;         ///< luma bit depth from sps to detect changes
+    int chroma_format_idc;      ///< chroma format from sps to detect changes
 
     SPS *sps_buffers[MAX_SPS_COUNT];
     PPS *pps_buffers[MAX_PPS_COUNT];
@@ -521,12 +559,16 @@ typedef struct H264Context {
      */
     int max_contexts;
 
+    int slice_context_count;
+
     /**
      *  1 if the single thread fallback warning has already been
      *  displayed, 0 otherwise.
      */
     int single_decode_warning;
 
+    enum AVPictureType pict_type;
+
     int last_slice_type;
     /** @} */
 
@@ -578,6 +620,8 @@ typedef struct H264Context {
 
     int cur_chroma_format_idc;
     uint8_t *bipred_scratchpad;
+    uint8_t *edge_emu_buffer;
+    int16_t *dc_val_base;
 } H264Context;
 
 extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
@@ -786,7 +830,7 @@ static av_always_inline int pred_intra_mode(H264Context *h, int n)
     const int top    = h->intra4x4_pred_mode_cache[index8 - 8];
     const int min    = FFMIN(left, top);
 
-    tprintf(h->s.avctx, "mode:%d %d min:%d\n", left, top, min);
+    tprintf(h->avctx, "mode:%d %d min:%d\n", left, top, min);
 
     if (min < 0)
         return DC_PRED;
@@ -820,7 +864,7 @@ static av_always_inline void write_back_non_zero_count(H264Context *h)
     AV_COPY32(&nnz[32], &nnz_cache[4 + 8 * 11]);
     AV_COPY32(&nnz[36], &nnz_cache[4 + 8 * 12]);
 
-    if (!h->s.chroma_y_shift) {
+    if (!h->chroma_y_shift) {
         AV_COPY32(&nnz[24], &nnz_cache[4 + 8 * 8]);
         AV_COPY32(&nnz[28], &nnz_cache[4 + 8 * 9]);
         AV_COPY32(&nnz[40], &nnz_cache[4 + 8 * 13]);
@@ -829,12 +873,11 @@ static av_always_inline void write_back_non_zero_count(H264Context *h)
 }
 
 static av_always_inline void write_back_motion_list(H264Context *h,
-                                                    MpegEncContext *const s,
                                                     int b_stride,
                                                     int b_xy, int b8_xy,
                                                     int mb_type, int list)
 {
-    int16_t(*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
+    int16_t(*mv_dst)[2] = &h->cur_pic.f.motion_val[list][b_xy];
     int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
     AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
     AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
@@ -855,7 +898,7 @@ static av_always_inline void write_back_motion_list(H264Context *h,
     }
 
     {
-        int8_t *ref_index = &s->current_picture.f.ref_index[list][b8_xy];
+        int8_t *ref_index = &h->cur_pic.f.ref_index[list][b8_xy];
         int8_t *ref_cache = h->ref_cache[list];
         ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
         ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
@@ -866,19 +909,18 @@ static av_always_inline void write_back_motion_list(H264Context *h,
 
 static av_always_inline void write_back_motion(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int b_stride      = h->b_stride;
-    const int b_xy  = 4 * s->mb_x + 4 * s->mb_y * h->b_stride; // try mb2b(8)_xy
+    const int b_xy  = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; // try mb2b(8)_xy
     const int b8_xy = 4 * h->mb_xy;
 
     if (USES_LIST(mb_type, 0)) {
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 0);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0);
     } else {
-        fill_rectangle(&s->current_picture.f.ref_index[0][b8_xy],
+        fill_rectangle(&h->cur_pic.f.ref_index[0][b8_xy],
                        2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
     }
     if (USES_LIST(mb_type, 1))
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 1);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 1);
 
     if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC) {
         if (IS_8X8(mb_type)) {
@@ -902,4 +944,6 @@ static av_always_inline int get_dct8x8_allowed(H264Context *h)
                   0x0001000100010001ULL));
 }
 
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
+
 #endif /* AVCODEC_H264_H */
index 1926ce6..8fc6b95 100644 (file)
@@ -1260,10 +1260,9 @@ static const int8_t cabac_context_init_PB[3][1024][2] =
 };
 
 void ff_h264_init_cabac_states(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int i;
     const int8_t (*tab)[2];
-    const int slice_qp = av_clip(s->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
+    const int slice_qp = av_clip(h->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I;
     else                                 tab = cabac_context_init_PB[h->cabac_init_idc];
@@ -1281,13 +1280,12 @@ void ff_h264_init_cabac_states(H264Context *h) {
 }
 
 static int decode_cabac_field_decoding_flag(H264Context *h) {
-    MpegEncContext * const s = &h->s;
-    const long mbb_xy = h->mb_xy - 2L*s->mb_stride;
+    const long mbb_xy = h->mb_xy - 2L*h->mb_stride;
 
     unsigned long ctx = 0;
 
-    ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
-    ctx += (s->current_picture.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
+    ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+    ctx += (h->cur_pic.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
 
     return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
 }
@@ -1323,34 +1321,33 @@ static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_sl
 }
 
 static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
-    MpegEncContext * const s = &h->s;
     int mba_xy, mbb_xy;
     int ctx = 0;
 
     if(FRAME_MBAFF){ //FIXME merge with the stuff in fill_caches?
-        int mb_xy = mb_x + (mb_y&~1)*s->mb_stride;
+        int mb_xy = mb_x + (mb_y&~1)*h->mb_stride;
         mba_xy = mb_xy - 1;
         if( (mb_y&1)
             && h->slice_table[mba_xy] == h->slice_num
-            && MB_FIELD == !!IS_INTERLACED( s->current_picture.f.mb_type[mba_xy] ) )
-            mba_xy += s->mb_stride;
+            && MB_FIELD == !!IS_INTERLACED( h->cur_pic.f.mb_type[mba_xy] ) )
+            mba_xy += h->mb_stride;
         if( MB_FIELD ){
-            mbb_xy = mb_xy - s->mb_stride;
+            mbb_xy = mb_xy - h->mb_stride;
             if( !(mb_y&1)
                 && h->slice_table[mbb_xy] == h->slice_num
-                && IS_INTERLACED( s->current_picture.f.mb_type[mbb_xy] ) )
-                mbb_xy -= s->mb_stride;
+                && IS_INTERLACED( h->cur_pic.f.mb_type[mbb_xy] ) )
+                mbb_xy -= h->mb_stride;
         }else
-            mbb_xy = mb_x + (mb_y-1)*s->mb_stride;
+            mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
     }else{
         int mb_xy = h->mb_xy;
         mba_xy = mb_xy - 1;
-        mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
+        mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE);
     }
 
-    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mba_xy] ))
+    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mba_xy] ))
         ctx++;
-    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mbb_xy] ))
+    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mbb_xy] ))
         ctx++;
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B )
@@ -1507,7 +1504,7 @@ static int decode_cabac_mb_mvd( H264Context *h, int ctxbase, int amvd, int *mvda
             mvd += 1 << k;
             k++;
             if(k>24){
-                av_log(h->s.avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
+                av_log(h->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
                 return INT_MIN;
             }
         }
@@ -1832,8 +1829,7 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
     static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
     const uint32_t *qmul;
     int i8x8, i4x4;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if( IS_INTRA16x16( mb_type ) ) {
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -1879,28 +1875,27 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
  */
 int ff_h264_decode_mb_cabac(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int mb_type, partition_count, cbp = 0;
     int dct8x8_allowed= h->pps.transform_8x8_mode;
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     const int pixel_shift = h->pixel_shift;
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     if( h->slice_type_nos != AV_PICTURE_TYPE_I ) {
         int skip;
         /* a skipped mb needs the aff flag from the following mb */
-        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )
+        if( FRAME_MBAFF && (h->mb_y&1)==1 && h->prev_mb_skipped )
             skip = h->next_mb_skipped;
         else
-            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );
+            skip = decode_cabac_mb_skip( h, h->mb_x, h->mb_y );
         /* read skip flags */
         if( skip ) {
-            if( FRAME_MBAFF && (s->mb_y&1)==0 ){
-                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_SKIP;
-                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );
+            if( FRAME_MBAFF && (h->mb_y&1)==0 ){
+                h->cur_pic.f.mb_type[mb_xy] = MB_TYPE_SKIP;
+                h->next_mb_skipped = decode_cabac_mb_skip( h, h->mb_x, h->mb_y+1 );
                 if(!h->next_mb_skipped)
                     h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
             }
@@ -1916,7 +1911,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
         }
     }
     if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
+        if( (h->mb_y&1) == 0 )
             h->mb_mbaff =
             h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
     }
@@ -2017,10 +2012,10 @@ decode_intra_mb:
         h->cbp_table[mb_xy] = 0xf7ef;
         h->chroma_pred_mode_table[mb_xy] = 0;
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.f.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.f.mb_type[mb_xy] = mb_type;
         h->last_qscale_diff = 0;
         return 0;
     }
@@ -2042,7 +2037,7 @@ decode_intra_mb:
                     int pred = pred_intra_mode( h, i );
                     h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );
 
-                    av_dlog(s->avctx, "i4x4 pred=%d mode=%d\n", pred,
+                    av_dlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
                             h->intra4x4_pred_mode_cache[scan8[i]]);
                 }
             }
@@ -2097,7 +2092,7 @@ decode_intra_mb:
                         if (rc > 1) {
                             ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );
                             if (ref[list][i] >= (unsigned) rc) {
-                                av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
+                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
                                 return -1;
                             }
                         }else
@@ -2132,7 +2127,7 @@ decode_intra_mb:
                         uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, index)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -2183,7 +2178,7 @@ decode_intra_mb:
                     if (rc > 1) {
                         ref= decode_cabac_mb_ref(h, list, 0);
                         if (ref >= (unsigned) rc) {
-                            av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                             return -1;
                         }
                     }else
@@ -2196,7 +2191,7 @@ decode_intra_mb:
                     int mx,my,mpx,mpy;
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
                     DECODE_CABAC_MB_MVD( h, list, 0)
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
@@ -2211,7 +2206,7 @@ decode_intra_mb:
                             if (rc > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 8*i );
                                 if (ref >= (unsigned) rc) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                                     return -1;
                                 }
                             }else
@@ -2227,7 +2222,7 @@ decode_intra_mb:
                         int mx,my,mpx,mpy;
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 8*i)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
@@ -2246,7 +2241,7 @@ decode_intra_mb:
                             if (rc > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 4*i );
                                 if (ref >= (unsigned) rc) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                                     return -1;
                                 }
                             }else
@@ -2263,7 +2258,7 @@ decode_intra_mb:
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 4*i)
 
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
                     }else{
@@ -2314,18 +2309,18 @@ decode_intra_mb:
             AV_WN32A(&nnz_cache[4+8*10], top_empty);
         }
     }
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.f.mb_type[mb_xy] = mb_type;
 
     if( cbp || IS_INTRA16x16( mb_type ) ) {
         const uint8_t *scan, *scan8x8;
         const uint32_t *qmul;
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
         // decode_cabac_mb_dqp
@@ -2338,7 +2333,7 @@ decode_intra_mb:
                 ctx= 3;
                 val++;
                 if(val > 2*max_qp){ //prevent infinite loop
-                    av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", h->mb_x, h->mb_y);
                     return -1;
                 }
             }
@@ -2348,13 +2343,13 @@ decode_intra_mb:
             else
                 val= -((val + 1)>>1);
             h->last_qscale_diff = val;
-            s->qscale += val;
-            if(((unsigned)s->qscale) > max_qp){
-                if(s->qscale<0) s->qscale+= max_qp+1;
-                else            s->qscale-= max_qp+1;
+            h->qscale += val;
+            if(((unsigned)h->qscale) > max_qp){
+                if(h->qscale<0) h->qscale+= max_qp+1;
+                else            h->qscale-= max_qp+1;
             }
-            h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-            h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+            h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+            h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
         }else
             h->last_qscale_diff=0;
 
@@ -2416,7 +2411,7 @@ decode_intra_mb:
         h->last_qscale_diff = 0;
     }
 
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
index be1cdf1..9585b77 100644 (file)
@@ -292,7 +292,7 @@ static inline int pred_non_zero_count(H264Context *h, int n){
 
     if(i<64) i= (i+1)>>1;
 
-    tprintf(h->s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
+    tprintf(h->avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
 
     return i&31;
 }
@@ -443,7 +443,6 @@ static inline int get_level_prefix(GetBitContext *gb){
  * @return <0 if an error occurred
  */
 static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
-    MpegEncContext * const s = &h->s;
     static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
     int level[16];
     int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
@@ -474,12 +473,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in
     if(total_coeff==0)
         return 0;
     if(total_coeff > (unsigned)max_coeff) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s->mb_x, s->mb_y, total_coeff);
+        av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", h->mb_x, h->mb_y, total_coeff);
         return -1;
     }
 
     trailing_ones= coeff_token&3;
-    tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
+    tprintf(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
     assert(total_coeff<=16);
 
     i = show_bits(gb, 3);
@@ -515,7 +514,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in
                 level_code= 30 + get_bits(gb, prefix-3); //part
                 if(prefix>=16){
                     if(prefix > 25+3){
-                        av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+                        av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
                         return -1;
                     }
                     level_code += (1<<(prefix-3))-4096;
@@ -611,8 +610,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in
     }
 
     if (zeros_left < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
-               "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
+        av_log(h->avctx, AV_LOG_ERROR,
+               "negative number of zero coeffs at %d %d\n", h->mb_x, h->mb_y);
         return AVERROR_INVALIDDATA;
     }
 
@@ -627,8 +626,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in
 
 static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
     int i4x4, i8x8;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if(IS_INTRA16x16(mb_type)){
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -693,7 +691,6 @@ static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *
 }
 
 int ff_h264_decode_mb_cavlc(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int partition_count;
     unsigned int mb_type, cbp;
@@ -701,32 +698,32 @@ int ff_h264_decode_mb_cavlc(H264Context *h){
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     const int pixel_shift = h->pixel_shift;
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                 down the code */
     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
-        if(s->mb_skip_run==-1)
-            s->mb_skip_run= get_ue_golomb(&s->gb);
+        if(h->mb_skip_run==-1)
+            h->mb_skip_run= get_ue_golomb(&h->gb);
 
-        if (s->mb_skip_run--) {
-            if(FRAME_MBAFF && (s->mb_y&1) == 0){
-                if(s->mb_skip_run==0)
-                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+        if (h->mb_skip_run--) {
+            if(FRAME_MBAFF && (h->mb_y&1) == 0){
+                if(h->mb_skip_run==0)
+                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
             }
             decode_mb_skip(h);
             return 0;
         }
     }
     if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
-            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+        if( (h->mb_y&1) == 0 )
+            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
     }
 
     h->prev_mb_skipped= 0;
 
-    mb_type= get_ue_golomb(&s->gb);
+    mb_type= get_ue_golomb(&h->gb);
     if(h->slice_type_nos == AV_PICTURE_TYPE_B){
         if(mb_type < 23){
             partition_count= b_mb_type_info[mb_type].partition_count;
@@ -749,7 +746,7 @@ int ff_h264_decode_mb_cavlc(H264Context *h){
             mb_type--;
 decode_intra_mb:
         if(mb_type > 25){
-            av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), s->mb_x, s->mb_y);
+            av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), h->mb_x, h->mb_y);
             return -1;
         }
         partition_count=0;
@@ -769,19 +766,19 @@ decode_intra_mb:
                             h->sps.bit_depth_luma >> 3;
 
         // We assume these blocks are very rare so we do not optimize it.
-        align_get_bits(&s->gb);
+        align_get_bits(&h->gb);
 
         // The pixels are stored in the same order as levels in h->mb array.
         for(x=0; x < mb_size; x++){
-            ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
+            ((uint8_t*)h->mb)[x]= get_bits(&h->gb, 8);
         }
 
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.f.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
 
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.f.mb_type[mb_xy] = mb_type;
         return 0;
     }
 
@@ -795,7 +792,7 @@ decode_intra_mb:
         if(IS_INTRA4x4(mb_type)){
             int i;
             int di = 1;
-            if(dct8x8_allowed && get_bits1(&s->gb)){
+            if(dct8x8_allowed && get_bits1(&h->gb)){
                 mb_type |= MB_TYPE_8x8DCT;
                 di = 4;
             }
@@ -804,8 +801,8 @@ decode_intra_mb:
             for(i=0; i<16; i+=di){
                 int mode= pred_intra_mode(h, i);
 
-                if(!get_bits1(&s->gb)){
-                    const int rem_mode= get_bits(&s->gb, 3);
+                if(!get_bits1(&h->gb)){
+                    const int rem_mode= get_bits(&h->gb, 3);
                     mode = rem_mode + (rem_mode >= mode);
                 }
 
@@ -823,7 +820,7 @@ decode_intra_mb:
                 return -1;
         }
         if(decode_chroma){
-            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb), 1);
+            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&h->gb), 1);
             if(pred_mode < 0)
                 return -1;
             h->chroma_pred_mode= pred_mode;
@@ -835,9 +832,9 @@ decode_intra_mb:
 
         if(h->slice_type_nos == AV_PICTURE_TYPE_B){
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=13){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -853,9 +850,9 @@ decode_intra_mb:
         }else{
             assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=4){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -872,11 +869,11 @@ decode_intra_mb:
                     if(ref_count == 1){
                         tmp= 0;
                     }else if(ref_count == 2){
-                        tmp= get_bits1(&s->gb)^1;
+                        tmp= get_bits1(&h->gb)^1;
                     }else{
-                        tmp= get_ue_golomb_31(&s->gb);
+                        tmp= get_ue_golomb_31(&h->gb);
                         if(tmp>=ref_count){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
+                            av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
                             return -1;
                         }
                     }
@@ -908,9 +905,9 @@ decode_intra_mb:
                         const int index= 4*i + block_width*j;
                         int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -948,11 +945,11 @@ decode_intra_mb:
                         if (rc == 1) {
                             val= 0;
                         } else if (rc == 2) {
-                            val= get_bits1(&s->gb)^1;
+                            val= get_bits1(&h->gb)^1;
                         }else{
-                            val= get_ue_golomb_31(&s->gb);
+                            val= get_ue_golomb_31(&h->gb);
                             if (val >= rc) {
-                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                 return -1;
                             }
                         }
@@ -962,9 +959,9 @@ decode_intra_mb:
             for(list=0; list<h->list_count; list++){
                 if(IS_DIR(mb_type, 0, list)){
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
-                    mx += get_se_golomb(&s->gb);
-                    my += get_se_golomb(&s->gb);
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    mx += get_se_golomb(&h->gb);
+                    my += get_se_golomb(&h->gb);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
                 }
@@ -979,11 +976,11 @@ decode_intra_mb:
                             if (rc == 1) {
                                 val= 0;
                             } else if (rc == 2) {
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if (val >= rc) {
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -997,9 +994,9 @@ decode_intra_mb:
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1017,11 +1014,11 @@ decode_intra_mb:
                             if (rc == 1) {
                                 val= 0;
                             } else if (rc == 2) {
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if (val >= rc) {
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -1035,9 +1032,9 @@ decode_intra_mb:
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1052,18 +1049,18 @@ decode_intra_mb:
         write_back_motion(h, mb_type);
 
     if(!IS_INTRA16x16(mb_type)){
-        cbp= get_ue_golomb(&s->gb);
+        cbp= get_ue_golomb(&h->gb);
 
         if(decode_chroma){
             if(cbp > 47){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
             else                     cbp= golomb_to_inter_cbp   [cbp];
         }else{
             if(cbp > 15){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
@@ -1072,11 +1069,11 @@ decode_intra_mb:
     }
 
     if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
-        mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb);
+        mb_type |= MB_TYPE_8x8DCT*get_bits1(&h->gb);
     }
     h->cbp=
     h->cbp_table[mb_xy]= cbp;
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.f.mb_type[mb_xy] = mb_type;
 
     if(cbp || IS_INTRA16x16(mb_type)){
         int i4x4, i8x8, chroma_idx;
@@ -1087,28 +1084,28 @@ decode_intra_mb:
         const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
-        dquant= get_se_golomb(&s->gb);
+        dquant= get_se_golomb(&h->gb);
 
-        s->qscale += dquant;
+        h->qscale += dquant;
 
-        if(((unsigned)s->qscale) > max_qp){
-            if(s->qscale<0) s->qscale+= max_qp+1;
-            else            s->qscale-= max_qp+1;
-            if(((unsigned)s->qscale) > max_qp){
-                av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
+        if(((unsigned)h->qscale) > max_qp){
+            if(h->qscale<0) h->qscale+= max_qp+1;
+            else            h->qscale-= max_qp+1;
+            if(((unsigned)h->qscale) > max_qp){
+                av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, h->mb_x, h->mb_y);
                 return -1;
             }
         }
 
-        h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);
-        h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);
+        h->chroma_qp[0]= get_chroma_qp(h, 0, h->qscale);
+        h->chroma_qp[1]= get_chroma_qp(h, 1, h->qscale);
 
         if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
             return -1;
@@ -1176,7 +1173,7 @@ decode_intra_mb:
         fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
         fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
     }
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
index 2306b97..e7a0b61 100644 (file)
@@ -50,14 +50,13 @@ static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){
 }
 
 void ff_h264_direct_dist_scale_factor(H264Context * const h){
-    MpegEncContext * const s = &h->s;
-    const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
+    const int poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
     const int poc1 = h->ref_list[1][0].poc;
     int i, field;
 
     if (FRAME_MBAFF)
         for (field = 0; field < 2; field++){
-            const int poc  = h->s.current_picture_ptr->field_poc[field];
+            const int poc  = h->cur_pic_ptr->field_poc[field];
             const int poc1 = h->ref_list[1][0].field_poc[field];
             for (i = 0; i < 2 * h->ref_count[0]; i++)
                 h->dist_scale_factor_field[field][i^field] =
@@ -70,12 +69,11 @@ void ff_h264_direct_dist_scale_factor(H264Context * const h){
 }
 
 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
     int j, old_ref, rfield;
     int start= mbafi ? 16                      : 0;
     int end  = mbafi ? 16+2*h->ref_count[0]    : h->ref_count[0];
-    int interl= mbafi || s->picture_structure != PICT_FRAME;
+    int interl= mbafi || h->picture_structure != PICT_FRAME;
 
     /* bogus; fills in for missing frames */
     memset(map[list], 0, sizeof(map[list]));
@@ -104,11 +102,10 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
 }
 
 void ff_h264_direct_ref_list_init(H264Context * const h){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
-    Picture * const cur = s->current_picture_ptr;
+    Picture * const cur = h->cur_pic_ptr;
     int list, j, field;
-    int sidx= (s->picture_structure&1)^1;
+    int sidx= (h->picture_structure&1)^1;
     int ref1sidx = (ref1->f.reference&1)^1;
 
     for(list=0; list<2; list++){
@@ -117,7 +114,7 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
             cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3);
     }
 
-    if(s->picture_structure == PICT_FRAME){
+    if(h->picture_structure == PICT_FRAME){
         memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
         memcpy(cur->ref_poc  [1], cur->ref_poc  [0], sizeof(cur->ref_poc  [0]));
     }
@@ -125,12 +122,12 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
     cur->mbaff= FRAME_MBAFF;
 
     h->col_fieldoff= 0;
-    if(s->picture_structure == PICT_FRAME){
-        int cur_poc = s->current_picture_ptr->poc;
+    if(h->picture_structure == PICT_FRAME){
+        int cur_poc = h->cur_pic_ptr->poc;
         int *col_poc = h->ref_list[1]->field_poc;
         h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
         ref1sidx=sidx= h->col_parity;
-    } else if (!(s->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
+    } else if (!(h->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
         h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3;
     }
 
@@ -149,9 +146,9 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y
 {
     int ref_field = ref->f.reference - 1;
     int ref_field_picture = ref->field_picture;
-    int ref_height = 16*h->s.mb_height >> ref_field_picture;
+    int ref_height = 16*h->mb_height >> ref_field_picture;
 
-    if(!HAVE_THREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME))
+    if(!HAVE_THREADS || !(h->avctx->active_thread_type&FF_THREAD_FRAME))
         return;
 
     //FIXME it can be safe to access mb stuff
@@ -163,10 +160,9 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y
 }
 
 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -179,7 +175,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
 
     assert(h->ref_list[1][0].f.reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
 
@@ -241,21 +237,21 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
 
     if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
             mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -298,7 +294,7 @@ single_col:
     l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
     l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -414,10 +410,9 @@ single_col:
 }
 
 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -427,25 +422,25 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
 
     assert(h->ref_list[1][0].f.reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
     if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
             mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -489,7 +484,7 @@ single_col:
     l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
     l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -503,9 +498,9 @@ single_col:
         int ref_offset;
 
         if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
-            map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
-            map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
-            dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];
+            map_col_to_list0[0] = h->map_col_to_list0_field[h->mb_y&1][0];
+            map_col_to_list0[1] = h->map_col_to_list0_field[h->mb_y&1][1];
+            dist_scale_factor   =h->dist_scale_factor_field[h->mb_y&1];
         }
         ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0
 
index 45e1cdf..929997c 100644 (file)
@@ -244,8 +244,7 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
                                                           unsigned int uvlinesize,
                                                           int pixel_shift)
 {
-    MpegEncContext * const s = &h->s;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
     int chroma444 = CHROMA444;
     int chroma422 = CHROMA422;
 
@@ -257,10 +256,10 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
 
-    int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int qp      = s->current_picture.f.qscale_table[mb_xy];
-    int qp0     = s->current_picture.f.qscale_table[mb_xy - 1];
-    int qp1     = s->current_picture.f.qscale_table[h->top_mb_xy];
+    int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    int qp      = h->cur_pic.f.qscale_table[mb_xy];
+    int qp0     = h->cur_pic.f.qscale_table[mb_xy - 1];
+    int qp1     = h->cur_pic.f.qscale_table[h->top_mb_xy];
     int qpc = get_chroma_qp( h, 0, qp );
     int qpc0 = get_chroma_qp( h, 0, qp0 );
     int qpc1 = get_chroma_qp( h, 0, qp1 );
@@ -465,7 +464,6 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
 }
 
 static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) {
-    MpegEncContext * const s = &h->s;
     int edge;
     int chroma_qp_avg[2];
     int chroma444 = CHROMA444;
@@ -493,16 +491,16 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             //
             unsigned int tmp_linesize   = 2 *   linesize;
             unsigned int tmp_uvlinesize = 2 * uvlinesize;
-            int mbn_xy = mb_xy - 2 * s->mb_stride;
+            int mbn_xy = mb_xy - 2 * h->mb_stride;
             int j;
 
-            for(j=0; j<2; j++, mbn_xy += s->mb_stride){
+            for(j=0; j<2; j++, mbn_xy += h->mb_stride){
                 DECLARE_ALIGNED(8, int16_t, bS)[4];
                 int qp;
-                if (IS_INTRA(mb_type | s->current_picture.f.mb_type[mbn_xy])) {
+                if (IS_INTRA(mb_type | h->cur_pic.f.mb_type[mbn_xy])) {
                     AV_WN64A(bS, 0x0003000300030003ULL);
                 } else {
-                    if (!CABAC && IS_8x8DCT(s->current_picture.f.mb_type[mbn_xy])) {
+                    if (!CABAC && IS_8x8DCT(h->cur_pic.f.mb_type[mbn_xy])) {
                         bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
                         bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
                         bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
@@ -517,12 +515,12 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
                 }
                 // Do not use s->qscale as luma quantizer because it has not the same
                 // value in IPCM macroblocks.
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbn_xy] + 1) >> 1;
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
-                { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbn_xy] + 1) >> 1;
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
+                { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
                 if (chroma) {
                     if (chroma444) {
                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
@@ -540,7 +538,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             if( IS_INTRA(mb_type|mbm_type)) {
                 AV_WN64A(bS, 0x0003000300030003ULL);
                 if (   (!IS_INTERLACED(mb_type|mbm_type))
-                    || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
+                    || ((FRAME_MBAFF || (h->picture_structure != PICT_FRAME)) && (dir == 0))
                 )
                     AV_WN64A(bS, 0x0004000400040004ULL);
             } else {
@@ -582,10 +580,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             // Do not use s->qscale as luma quantizer because it has not the same
             // value in IPCM macroblocks.
             if(bS[0]+bS[1]+bS[2]+bS[3]){
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
+                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbm_xy] + 1) >> 1;
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
                 if( dir == 0 ) {
                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                     if (chroma) {
@@ -665,8 +663,8 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
         /* Filter edge */
         // Do not use s->qscale as luma quantizer because it has not the same
         // value in IPCM macroblocks.
-        qp = s->current_picture.f.qscale_table[mb_xy];
-        tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+        qp = h->cur_pic.f.qscale_table[mb_xy];
+        tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
         if( dir == 0 ) {
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
             if (chroma) {
@@ -703,13 +701,12 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
 }
 
 void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
-    MpegEncContext * const s = &h->s;
-    const int mb_xy= mb_x + mb_y*s->mb_stride;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_xy= mb_x + mb_y*h->mb_stride;
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
     int first_vertical_edge_done = 0;
     av_unused int dir;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
     int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
@@ -761,9 +758,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
             }
         }
 
-        mb_qp   = s->current_picture.f.qscale_table[mb_xy];
-        mbn0_qp = s->current_picture.f.qscale_table[h->left_mb_xy[0]];
-        mbn1_qp = s->current_picture.f.qscale_table[h->left_mb_xy[1]];
+        mb_qp   = h->cur_pic.f.qscale_table[mb_xy];
+        mbn0_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[0]];
+        mbn1_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[1]];
         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
@@ -776,8 +773,8 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
                    get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
 
         /* Filter edge */
-        tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
-        { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+        tprintf(h->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
+        { int i; for (i = 0; i < 8; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
         if(MB_FIELD){
             filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0], a, b, 1 );
             filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1], a, b, 1 );
index 167509e..7ff7edd 100644 (file)
 
 static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize /*dct_offset*/;
     int i, j;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
     /* is_h264 should always be true if SVQ3 is disabled. */
-    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || s->codec_id == AV_CODEC_ID_H264;
+    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || h->avctx->codec_id == AV_CODEC_ID_H264;
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
-    const int block_h   = 16 >> s->chroma_y_shift;
+    const int block_h   = 16 >> h->chroma_y_shift;
     const int chroma422 = CHROMA422;
 
-    dest_y  = s->current_picture.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * s->linesize)  * 16;
-    dest_cb = s->current_picture.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
-    dest_cr = s->current_picture.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
+    dest_y  = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * h->linesize)  * 16;
+    dest_cb = h->cur_pic.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
+    dest_cr = h->cur_pic.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
 
-    s->vdsp.prefetch(dest_y  + (s->mb_x & 3) * 4 * s->linesize   + (64 << PIXEL_SHIFT), s->linesize,       4);
-    s->vdsp.prefetch(dest_cb + (s->mb_x & 7)     * s->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
+    h->vdsp.prefetch(dest_y  + (h->mb_x & 3) * 4 * h->linesize   + (64 << PIXEL_SHIFT), h->linesize,       4);
+    h->vdsp.prefetch(dest_cb + (h->mb_x & 7)     * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
 
     h->list_counts[mb_xy] = h->list_count;
 
     if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = s->linesize * 2;
-        uvlinesize   = h->mb_uvlinesize = s->uvlinesize * 2;
+        linesize     = h->mb_linesize = h->linesize * 2;
+        uvlinesize   = h->mb_uvlinesize = h->uvlinesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) { // FIXME move out of this function?
-            dest_y  -= s->linesize * 15;
-            dest_cb -= s->uvlinesize * (block_h - 1);
-            dest_cr -= s->uvlinesize * (block_h - 1);
+            dest_y  -= h->linesize * 15;
+            dest_cb -= h->uvlinesize * (block_h - 1);
+            dest_cr -= h->uvlinesize * (block_h - 1);
         }
         if (FRAME_MBAFF) {
             int list;
@@ -81,20 +80,20 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize   = h->mb_linesize   = s->linesize;
-        uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+        linesize   = h->mb_linesize   = h->linesize;
+        uvlinesize = h->mb_uvlinesize = h->uvlinesize;
         // dct_offset = s->linesize * 16;
     }
 
@@ -111,7 +110,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                 for (j = 0; j < 16; j++)
                     tmp_y[j] = get_bits(&gb, bit_depth);
             }
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
@@ -139,7 +138,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         } else {
             for (i = 0; i < 16; i++)
                 memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         memset(dest_cb + i * uvlinesize, 128, 8);
@@ -161,7 +160,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                 xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
 
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cb, uvlinesize);
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
             }
@@ -176,14 +175,14 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         } else if (is_h264) {
             if (chroma422) {
                 FUNC(hl_motion_422)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             } else {
                 FUNC(hl_motion_420)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             }
@@ -192,7 +191,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         hl_decode_mb_idct_luma(h, mb_type, is_h264, SIMPLE, transform_bypass,
                                PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
 
-        if ((SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) &&
+        if ((SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) &&
             (h->cbp & 0x30)) {
             uint8_t *dest[2] = { dest_cb, dest_cr };
             if (transform_bypass) {
@@ -208,7 +207,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                                                             h->mb + (16 * 16 * 2 << PIXEL_SHIFT),
                                                             uvlinesize);
                 } else {
-                    idct_add = s->dsp.add_pixels4;
+                    idct_add = h->dsp.add_pixels4;
                     for (j = 1; j < 3; j++) {
                         for (i = j * 16; i < j * 16 + 4; i++)
                             if (h->non_zero_count_cache[scan8[i]] ||
@@ -256,7 +255,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                                 uint8_t *const ptr = dest[j - 1] + block_offset[i];
                                 ff_svq3_add_idct_c(ptr, h->mb + i * 16,
                                                    uvlinesize,
-                                                   ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
+                                                   ff_h264_chroma_qp[0][h->qscale + 12] - 12, 2);
                             }
                     }
                 }
@@ -264,8 +263,8 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         }
     }
     if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
+        h->dsp.clear_blocks(h->mb);
+        h->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
     }
 }
 
@@ -277,33 +276,32 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
 
 static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
     uint8_t *dest[3];
     int linesize;
     int i, j, p;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
-    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
+    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
 
     for (p = 0; p < plane_count; p++) {
-        dest[p] = s->current_picture.f.data[p] +
-                  ((mb_x << PIXEL_SHIFT) + mb_y * s->linesize) * 16;
-        s->vdsp.prefetch(dest[p] + (s->mb_x & 3) * 4 * s->linesize + (64 << PIXEL_SHIFT),
-                         s->linesize, 4);
+        dest[p] = h->cur_pic.f.data[p] +
+                  ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16;
+        h->vdsp.prefetch(dest[p] + (h->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT),
+                         h->linesize, 4);
     }
 
     h->list_counts[mb_xy] = h->list_count;
 
     if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = h->mb_uvlinesize = s->linesize * 2;
+        linesize     = h->mb_linesize = h->mb_uvlinesize = h->linesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) // FIXME move out of this function?
             for (p = 0; p < 3; p++)
-                dest[p] -= s->linesize * 15;
+                dest[p] -= h->linesize * 15;
         if (FRAME_MBAFF) {
             int list;
             for (list = 0; list < h->list_count; list++) {
@@ -311,19 +309,19 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize;
+        linesize = h->mb_linesize = h->mb_uvlinesize = h->linesize;
     }
 
     if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
@@ -360,8 +358,8 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
                                linesize, 0, 1, SIMPLE, PIXEL_SHIFT);
         } else {
             FUNC(hl_motion_444)(h, dest[0], dest[1], dest[2],
-                      s->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
-                      s->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
+                      h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                      h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                       h->h264dsp.weight_h264_pixels_tab,
                       h->h264dsp.biweight_h264_pixels_tab);
         }
@@ -372,8 +370,8 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
                                    dest[p], p);
     }
     if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
+        h->dsp.clear_blocks(h->mb);
+        h->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
     }
 }
 
index a3af39b..ad54558 100644 (file)
@@ -46,7 +46,7 @@ static void mc_part(H264Context *h, int n, int square,
                     int list0, int list1)
 {
     if ((h->use_weight == 2 && list0 && list1 &&
-         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->s.mb_y & 1] != 32)) ||
+         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) ||
         h->use_weight == 1)
         mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
                          x_offset, y_offset, qpix_put, chroma_put,
@@ -67,13 +67,12 @@ static void MCFUNC(hl_motion)(H264Context *h, uint8_t *dest_y,
                               h264_weight_func *weight_op,
                               h264_biweight_func *weight_avg)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
 
     assert(IS_INTER(mb_type));
 
-    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+    if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME))
         await_references(h);
     prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
 
index 5244c29..b49ff31 100644 (file)
@@ -39,32 +39,31 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
                                               int i, int list, int part_width)
 {
     const int topright_ref = h->ref_cache[list][i - 8 + part_width];
-    MpegEncContext *s      = &h->s;
 
     /* there is no consistent mapping of mvs to neighboring locations that will
      * make mbaff happy, so we can't move all this logic to fill_caches */
     if (FRAME_MBAFF) {
 #define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4)                              \
         const int xy = XY, y4 = Y4;                                     \
-        const int mb_type = mb_types[xy + (y4 >> 2) * s->mb_stride];    \
+        const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride];    \
         if (!USES_LIST(mb_type, list))                                  \
             return LIST_NOT_USED;                                       \
-        mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+        mv = h->cur_pic_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
         h->mv_cache[list][scan8[0] - 2][0] = mv[0];                     \
         h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP;               \
-        return s->current_picture_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+        return h->cur_pic_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
 
         if (topright_ref == PART_NOT_AVAILABLE
             && i >= scan8[0] + 8 && (i & 7) == 4
             && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
-            const uint32_t *mb_types = s->current_picture_ptr->f.mb_type;
+            const uint32_t *mb_types = h->cur_pic_ptr->f.mb_type;
             const int16_t *mv;
             AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
             *C = h->mv_cache[list][scan8[0] - 2];
 
             if (!MB_FIELD && IS_INTERLACED(h->left_type[0])) {
-                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + s->mb_stride,
-                            (s->mb_y & 1) * 2 + (i >> 5));
+                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + h->mb_stride,
+                            (h->mb_y & 1) * 2 + (i >> 5));
             }
             if (MB_FIELD && !IS_INTERLACED(h->left_type[0])) {
                 // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
@@ -78,7 +77,7 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
         *C = h->mv_cache[list][i - 8 + part_width];
         return topright_ref;
     } else {
-        tprintf(s->avctx, "topright MV not available\n");
+        tprintf(h->avctx, "topright MV not available\n");
 
         *C = h->mv_cache[list][i - 8 - 1];
         return h->ref_cache[list][i - 8 - 1];
@@ -116,7 +115,7 @@ static av_always_inline void pred_motion(H264Context *const h, int n,
 
     diagonal_ref = fetch_diagonal_mv(h, &C, index8, list, part_width);
     match_count  = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
-    tprintf(h->s.avctx, "pred_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_motion match_count=%d\n", match_count);
     if (match_count > 1) { //most common
         *mx = mid_pred(A[0], B[0], C[0]);
         *my = mid_pred(A[1], B[1], C[1]);
@@ -143,10 +142,10 @@ static av_always_inline void pred_motion(H264Context *const h, int n,
         }
     }
 
-    tprintf(h->s.avctx,
+    tprintf(h->avctx,
             "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
             top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
-            A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list);
+            A[0], A[1], ref, *mx, *my, h->mb_x, h->mb_y, n, list);
 }
 
 /**
@@ -163,8 +162,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
         const int top_ref      = h->ref_cache[list][scan8[0] - 8];
         const int16_t *const B = h->mv_cache[list][scan8[0] - 8];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                top_ref, B[0], B[1], h->mb_x, h->mb_y, n, list);
 
         if (top_ref == ref) {
             *mx = B[0];
@@ -175,8 +174,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
         const int left_ref     = h->ref_cache[list][scan8[8] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[8] - 1];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -203,8 +202,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
         const int left_ref     = h->ref_cache[list][scan8[0] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[0] - 1];
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -217,8 +216,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
 
         diagonal_ref = fetch_diagonal_mv(h, &C, scan8[4], list, 2);
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                diagonal_ref, C[0], C[1], h->mb_x, h->mb_y, n, list);
 
         if (diagonal_ref == ref) {
             *mx = C[0];
@@ -254,9 +253,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
 {
     DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
     DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
-    MpegEncContext *const s = &h->s;
-    int8_t *ref     = s->current_picture.f.ref_index[0];
-    int16_t(*mv)[2] = s->current_picture.f.motion_val[0];
+    int8_t *ref     = h->cur_pic.f.ref_index[0];
+    int16_t(*mv)[2] = h->cur_pic.f.motion_val[0];
     int top_ref, left_ref, diagonal_ref, match_count, mx, my;
     const int16_t *A, *B, *C;
     int b_stride = h->b_stride;
@@ -294,8 +292,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
         goto zeromv;
     }
 
-    tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
-            top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+    tprintf(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
+            top_ref, left_ref, h->mb_x, h->mb_y);
 
     if (USES_LIST(h->topright_type, 0)) {
         diagonal_ref = ref[4 * h->topright_mb_xy + 2];
@@ -321,7 +319,7 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
     }
 
     match_count = !diagonal_ref + !top_ref + !left_ref;
-    tprintf(h->s.avctx, "pred_pskip_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_pskip_motion match_count=%d\n", match_count);
     if (match_count > 1) {
         mx = mid_pred(A[0], B[0], C[0]);
         my = mid_pred(A[1], B[1], C[1]);
@@ -351,7 +349,6 @@ zeromv:
 
 static void fill_decode_neighbors(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     static const uint8_t left_block_options[4][32] = {
@@ -363,7 +360,7 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
 
     h->topleft_partition = -1;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD);
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
@@ -373,16 +370,16 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     h->left_block = left_block_options[0];
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag) {
-                left_xy[LBOT] = left_xy[LTOP] = mb_xy - s->mb_stride - 1;
+                left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1;
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
-                    topleft_xy += s->mb_stride;
+                    topleft_xy += h->mb_stride;
                     /* take top left mv from the middle of the mb, as opposed
                      * to all other modes which use the bottom right partition */
                     h->topleft_partition = 0;
@@ -391,13 +388,13 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
             }
         } else {
             if (curr_mb_field_flag) {
-                topleft_xy  += s->mb_stride & (((s->current_picture.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
-                topright_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
-                top_xy      += s->mb_stride & (((s->current_picture.f.mb_type[top_xy]     >> 7) & 1) - 1);
+                topleft_xy  += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
+                topright_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
+                top_xy      += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy]     >> 7) & 1) - 1);
             }
             if (left_mb_field_flag != curr_mb_field_flag) {
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
                     h->left_block = left_block_options[2];
@@ -413,11 +410,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     h->left_mb_xy[LBOT] = left_xy[LBOT];
     //FIXME do we need all in the context?
 
-    h->topleft_type    = s->current_picture.f.mb_type[topleft_xy];
-    h->top_type        = s->current_picture.f.mb_type[top_xy];
-    h->topright_type   = s->current_picture.f.mb_type[topright_xy];
-    h->left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    h->left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    h->topleft_type    = h->cur_pic.f.mb_type[topleft_xy];
+    h->top_type        = h->cur_pic.f.mb_type[top_xy];
+    h->topright_type   = h->cur_pic.f.mb_type[topright_xy];
+    h->left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
+    h->left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
 
     if (FMO) {
         if (h->slice_table[topleft_xy] != h->slice_num)
@@ -441,7 +438,6 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
 
 static void fill_decode_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
     const uint8_t *left_block = h->left_block;
@@ -484,7 +480,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                         h->left_samples_available    &= 0xFF5F;
                     }
                 } else {
-                    int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
+                    int left_typei = h->cur_pic.f.mb_type[left_xy[LTOP] + h->mb_stride];
 
                     assert(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
@@ -541,7 +537,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
         if (top_type) {
             nnz = h->non_zero_count[top_xy];
             AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
-            if (!s->chroma_y_shift) {
+            if (!h->chroma_y_shift) {
                 AV_COPY32(&nnz_cache[4 + 8 *  5], &nnz[4 *  7]);
                 AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
             } else {
@@ -606,9 +602,9 @@ static void fill_decode_caches(H264Context *h, int mb_type)
         int b_stride = h->b_stride;
         for (list = 0; list < h->list_count; list++) {
             int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
-            int8_t *ref       = s->current_picture.f.ref_index[list];
+            int8_t *ref       = h->cur_pic.f.ref_index[list];
             int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
-            int16_t(*mv)[2]       = s->current_picture.f.motion_val[list];
+            int16_t(*mv)[2]       = h->cur_pic.f.motion_val[list];
             if (!USES_LIST(mb_type, list))
                 continue;
             assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
@@ -800,7 +796,6 @@ static void fill_decode_caches(H264Context *h, int mb_type)
  */
 static void av_unused decode_mb_skip(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int mb_type     = 0;
 
@@ -826,10 +821,10 @@ static void av_unused decode_mb_skip(H264Context *h)
     }
 
     write_back_motion(h, mb_type);
-    s->current_picture.f.mb_type[mb_xy]      = mb_type;
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
-    h->slice_table[mb_xy]                    = h->slice_num;
-    h->prev_mb_skipped                       = 1;
+    h->cur_pic.f.mb_type[mb_xy]      = mb_type;
+    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
+    h->slice_table[mb_xy]            = h->slice_num;
+    h->prev_mb_skipped               = 1;
 }
 
 #endif /* AVCODEC_H264_MVPRED_H */
index 0464476..8c84d43 100644 (file)
@@ -36,7 +36,7 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_si
 {
     int i;
     uint32_t state;
-    ParseContext *pc = &(h->s.parse_context);
+    ParseContext *pc = &h->parse_context;
 //    mb_addr= pc->mb_addr - 1;
     state= pc->state;
     if(state>13)
@@ -119,7 +119,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
     s->pict_type = AV_PICTURE_TYPE_I;
     s->key_frame = 0;
 
-    h->s.avctx= avctx;
+    h->avctx= avctx;
     h->sei_recovery_frame_cnt = -1;
     h->sei_dpb_output_delay         =  0;
     h->sei_cpb_removal_delay        = -1;
@@ -147,13 +147,13 @@ static inline int parse_nal_units(AVCodecParserContext *s,
         if (ptr==NULL || dst_length < 0)
             break;
 
-        init_get_bits(&h->s.gb, ptr, 8*dst_length);
+        init_get_bits(&h->gb, ptr, 8*dst_length);
         switch(h->nal_unit_type) {
         case NAL_SPS:
             ff_h264_decode_seq_parameter_set(h);
             break;
         case NAL_PPS:
-            ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits);
+            ff_h264_decode_picture_parameter_set(h, h->gb.size_in_bits);
             break;
         case NAL_SEI:
             ff_h264_decode_sei(h);
@@ -162,40 +162,40 @@ static inline int parse_nal_units(AVCodecParserContext *s,
             s->key_frame = 1;
             /* fall through */
         case NAL_SLICE:
-            get_ue_golomb(&h->s.gb);  // skip first_mb_in_slice
-            slice_type = get_ue_golomb_31(&h->s.gb);
+            get_ue_golomb(&h->gb);  // skip first_mb_in_slice
+            slice_type = get_ue_golomb_31(&h->gb);
             s->pict_type = golomb_to_pict_type[slice_type % 5];
             if (h->sei_recovery_frame_cnt >= 0) {
                 /* key frame, since recovery_frame_cnt is set */
                 s->key_frame = 1;
             }
-            pps_id= get_ue_golomb(&h->s.gb);
+            pps_id= get_ue_golomb(&h->gb);
             if(pps_id>=MAX_PPS_COUNT) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
+                av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
                 return -1;
             }
             if(!h->pps_buffers[pps_id]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
+                av_log(h->avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
                 return -1;
             }
             h->pps= *h->pps_buffers[pps_id];
             if(!h->sps_buffers[h->pps.sps_id]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
+                av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
                 return -1;
             }
             h->sps = *h->sps_buffers[h->pps.sps_id];
-            h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num);
+            h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
             avctx->profile = ff_h264_get_profile(&h->sps);
             avctx->level   = h->sps.level_idc;
 
             if(h->sps.frame_mbs_only_flag){
-                h->s.picture_structure= PICT_FRAME;
+                h->picture_structure= PICT_FRAME;
             }else{
-                if(get_bits1(&h->s.gb)) { //field_pic_flag
-                    h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag
+                if(get_bits1(&h->gb)) { //field_pic_flag
+                    h->picture_structure= PICT_TOP_FIELD + get_bits1(&h->gb); //bottom_field_flag
                 } else {
-                    h->s.picture_structure= PICT_FRAME;
+                    h->picture_structure= PICT_FRAME;
                 }
             }
 
@@ -221,11 +221,11 @@ static inline int parse_nal_units(AVCodecParserContext *s,
                         s->repeat_pict = 5;
                         break;
                     default:
-                        s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                        s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
                         break;
                 }
             } else {
-                s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
             }
 
             return 0; /* no need to evaluate the rest */
@@ -233,7 +233,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
         buf += consumed;
     }
     /* didn't find a picture! */
-    av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
     return -1;
 }
 
@@ -243,20 +243,20 @@ static int h264_parse(AVCodecParserContext *s,
                       const uint8_t *buf, int buf_size)
 {
     H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    ParseContext *pc = &h->parse_context;
     int next;
 
     if (!h->got_first) {
         h->got_first = 1;
         if (avctx->extradata_size) {
-            h->s.avctx = avctx;
+            h->avctx = avctx;
             // must be done like in the decoder.
             // otherwise opening the parser, creating extradata,
             // and then closing and opening again
             // will cause has_b_frames to be always set.
             // NB: estimate_timings_from_pts behaves exactly like this.
             if (!avctx->has_b_frames)
-                h->s.low_delay = 1;
+                h->low_delay = 1;
             ff_h264_decode_extradata(h);
         }
     }
@@ -326,7 +326,7 @@ static int h264_split(AVCodecContext *avctx,
 static void close(AVCodecParserContext *s)
 {
     H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    ParseContext *pc = &h->parse_context;
 
     av_free(pc->buffer);
     ff_h264_free_context(h);
@@ -336,7 +336,7 @@ static int init(AVCodecParserContext *s)
 {
     H264Context *h = s->priv_data;
     h->thread_context[0] = h;
-    h->s.slice_context_count = 1;
+    h->slice_context_count = 1;
     return 0;
 }
 
index 63f371c..e35dab2 100644 (file)
@@ -121,46 +121,44 @@ static const uint8_t default_scaling8[2][64]={
 }};
 
 static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
     int cpb_count, i;
-    cpb_count = get_ue_golomb_31(&s->gb) + 1;
+    cpb_count = get_ue_golomb_31(&h->gb) + 1;
 
     if(cpb_count > 32U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
+        av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
         return -1;
     }
 
-    get_bits(&s->gb, 4); /* bit_rate_scale */
-    get_bits(&s->gb, 4); /* cpb_size_scale */
+    get_bits(&h->gb, 4); /* bit_rate_scale */
+    get_bits(&h->gb, 4); /* cpb_size_scale */
     for(i=0; i<cpb_count; i++){
-        get_ue_golomb_long(&s->gb); /* bit_rate_value_minus1 */
-        get_ue_golomb_long(&s->gb); /* cpb_size_value_minus1 */
-        get_bits1(&s->gb);     /* cbr_flag */
+        get_ue_golomb_long(&h->gb); /* bit_rate_value_minus1 */
+        get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */
+        get_bits1(&h->gb);     /* cbr_flag */
     }
-    sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->time_offset_length = get_bits(&s->gb, 5);
+    sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
+    sps->cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
+    sps->dpb_output_delay_length = get_bits(&h->gb, 5) + 1;
+    sps->time_offset_length = get_bits(&h->gb, 5);
     sps->cpb_cnt = cpb_count;
     return 0;
 }
 
 static inline int decode_vui_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
     int aspect_ratio_info_present_flag;
     unsigned int aspect_ratio_idc;
 
-    aspect_ratio_info_present_flag= get_bits1(&s->gb);
+    aspect_ratio_info_present_flag= get_bits1(&h->gb);
 
     if( aspect_ratio_info_present_flag ) {
-        aspect_ratio_idc= get_bits(&s->gb, 8);
+        aspect_ratio_idc= get_bits(&h->gb, 8);
         if( aspect_ratio_idc == EXTENDED_SAR ) {
-            sps->sar.num= get_bits(&s->gb, 16);
-            sps->sar.den= get_bits(&s->gb, 16);
+            sps->sar.num= get_bits(&h->gb, 16);
+            sps->sar.den= get_bits(&h->gb, 16);
         }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){
             sps->sar=  pixel_aspect[aspect_ratio_idc];
         }else{
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
+            av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
             return -1;
         }
     }else{
@@ -169,20 +167,20 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
     }
 //            s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);
 
-    if(get_bits1(&s->gb)){      /* overscan_info_present_flag */
-        get_bits1(&s->gb);      /* overscan_appropriate_flag */
+    if(get_bits1(&h->gb)){      /* overscan_info_present_flag */
+        get_bits1(&h->gb);      /* overscan_appropriate_flag */
     }
 
-    sps->video_signal_type_present_flag = get_bits1(&s->gb);
+    sps->video_signal_type_present_flag = get_bits1(&h->gb);
     if(sps->video_signal_type_present_flag){
-        get_bits(&s->gb, 3);    /* video_format */
-        sps->full_range = get_bits1(&s->gb); /* video_full_range_flag */
+        get_bits(&h->gb, 3);    /* video_format */
+        sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */
 
-        sps->colour_description_present_flag = get_bits1(&s->gb);
+        sps->colour_description_present_flag = get_bits1(&h->gb);
         if(sps->colour_description_present_flag){
-            sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */
-            sps->color_trc       = get_bits(&s->gb, 8); /* transfer_characteristics */
-            sps->colorspace      = get_bits(&s->gb, 8); /* matrix_coefficients */
+            sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */
+            sps->color_trc       = get_bits(&h->gb, 8); /* transfer_characteristics */
+            sps->colorspace      = get_bits(&h->gb, 8); /* matrix_coefficients */
             if (sps->color_primaries >= AVCOL_PRI_NB)
                 sps->color_primaries  = AVCOL_PRI_UNSPECIFIED;
             if (sps->color_trc >= AVCOL_TRC_NB)
@@ -192,56 +190,56 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
         }
     }
 
-    if(get_bits1(&s->gb)){      /* chroma_location_info_present_flag */
-        s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1;  /* chroma_sample_location_type_top_field */
-     &