libavcodec/vc1dec.c
b761659b
 /*
  * VC-1 and WMV3 decoder
cad16562
  * Copyright (c) 2011 Mashiat Sarker Shakkhar
b761659b
  * Copyright (c) 2006-2007 Konstantin Shishkov
  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
ba87f080
  * @file
b761659b
  * VC-1 and WMV3 decoder
  */
50f97219
 
b761659b
 #include "internal.h"
 #include "avcodec.h"
5f401b7b
 #include "error_resilience.h"
b761659b
 #include "mpegvideo.h"
d68b27a9
 #include "h263.h"
79dad2a9
 #include "h264chroma.h"
b761659b
 #include "vc1.h"
 #include "vc1data.h"
 #include "vc1acdata.h"
 #include "msmpeg4data.h"
 #include "unary.h"
 #include "mathops.h"
a0c6c8e5
 #include "vdpau_internal.h"
b378a233
 #include "libavutil/avassert.h"
b761659b
 
 #undef NDEBUG
 #include <assert.h>
 
 #define MB_INTRA_VLC_BITS 9
 #define DC_VLC_BITS 9
 
 
cad16562
 // offset tables for interlaced picture MVDATA decoding
50f97219
 static const int offset_table1[9] = {  0,  1,  2,  4,  8, 16, 32,  64, 128 };
 static const int offset_table2[9] = {  0,  1,  3,  7, 15, 31, 63, 127, 255 };
cad16562
 
b761659b
 /***********************************************************************/
 /**
21a19b79
  * @name VC-1 Bitplane decoding
b761659b
  * @see 8.7, p56
  * @{
  */
 
 
0d194ee5
 static void init_block_index(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     ff_init_block_index(s);
6c9d28a2
     if (v->field_mode && !(v->second_field ^ v->tff)) {
0d194ee5
         s->dest[0] += s->current_picture_ptr->f.linesize[0];
         s->dest[1] += s->current_picture_ptr->f.linesize[1];
         s->dest[2] += s->current_picture_ptr->f.linesize[2];
     }
 }
 
b761659b
 /** @} */ //Bitplane group
 
7d2e03af
 static void vc1_put_signed_blocks_clamped(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
cad16562
     int topleft_mb_pos, top_mb_pos;
c6779c51
     int stride_y, fieldtx = 0;
cad16562
     int v_dist;
7d2e03af
 
     /* The put pixels loop is always one MB row behind the decoding loop,
      * because we can only put pixels when overlap filtering is done, and
      * for filtering of the bottom edge of a MB, we need the next MB row
      * present as well.
      * Within the row, the put pixels loop is also one MB col behind the
      * decoding loop. The reason for this is again, because for filtering
      * of the right MB edge, we need the next MB present. */
     if (!s->first_slice_line) {
         if (s->mb_x) {
cad16562
             topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
c6779c51
             if (v->fcm == ILACE_FRAME)
                 fieldtx = v->fieldtx_plane[topleft_mb_pos];
ee41963f
             stride_y       = s->linesize << fieldtx;
50f97219
             v_dist         = (16 - fieldtx) >> (fieldtx == 0);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
                                              s->dest[0] - 16 * s->linesize - 16,
cad16562
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
                                              s->dest[0] - 16 * s->linesize - 8,
cad16562
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
cad16562
                                              s->dest[0] - v_dist * s->linesize - 16,
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
cad16562
                                              s->dest[0] - v_dist * s->linesize - 8,
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
                                              s->dest[1] - 8 * s->uvlinesize - 8,
                                              s->uvlinesize);
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][5],
                                              s->dest[2] - 8 * s->uvlinesize - 8,
                                              s->uvlinesize);
         }
         if (s->mb_x == s->mb_width - 1) {
cad16562
             top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
c6779c51
             if (v->fcm == ILACE_FRAME)
                 fieldtx = v->fieldtx_plane[top_mb_pos];
50f97219
             stride_y   = s->linesize << fieldtx;
             v_dist     = fieldtx ? 15 : 8;
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
                                              s->dest[0] - 16 * s->linesize,
cad16562
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
                                              s->dest[0] - 16 * s->linesize + 8,
cad16562
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
cad16562
                                              s->dest[0] - v_dist * s->linesize,
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
cad16562
                                              s->dest[0] - v_dist * s->linesize + 8,
                                              stride_y);
7d2e03af
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
                                              s->dest[1] - 8 * s->uvlinesize,
                                              s->uvlinesize);
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][5],
                                              s->dest[2] - 8 * s->uvlinesize,
                                              s->uvlinesize);
         }
     }
 
 #define inc_blk_idx(idx) do { \
         idx++; \
         if (idx >= v->n_allocated_blks) \
             idx = 0; \
     } while (0)
 
     inc_blk_idx(v->topleft_blk_idx);
     inc_blk_idx(v->top_blk_idx);
     inc_blk_idx(v->left_blk_idx);
     inc_blk_idx(v->cur_blk_idx);
 }
 
12802ec0
 static void vc1_loop_filter_iblk(VC1Context *v, int pq)
b761659b
 {
12802ec0
     MpegEncContext *s = &v->s;
fca58a81
     int j;
     if (!s->first_slice_line) {
12802ec0
         v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
fca58a81
         if (s->mb_x)
50f97219
             v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
         v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
         for (j = 0; j < 2; j++) {
             v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
fca58a81
             if (s->mb_x)
50f97219
                 v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
fca58a81
         }
     }
50f97219
     v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq);
fca58a81
 
50f97219
     if (s->mb_y == s->end_mb_y - 1) {
fca58a81
         if (s->mb_x) {
12802ec0
             v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
             v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
             v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
fca58a81
         }
12802ec0
         v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
b761659b
     }
 }
 
7d2e03af
 static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
 {
     MpegEncContext *s = &v->s;
     int j;
 
     /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
      * means it runs two rows/cols behind the decoding loop. */
     if (!s->first_slice_line) {
         if (s->mb_x) {
             if (s->mb_y >= s->start_mb_y + 2) {
                 v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
 
                 if (s->mb_x >= 2)
                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq);
                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq);
50f97219
                 for (j = 0; j < 2; j++) {
                     v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
7d2e03af
                     if (s->mb_x >= 2) {
50f97219
                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
7d2e03af
                     }
                 }
             }
             v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16, s->linesize, pq);
         }
 
         if (s->mb_x == s->mb_width - 1) {
             if (s->mb_y >= s->start_mb_y + 2) {
                 v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
 
                 if (s->mb_x)
                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq);
                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq);
50f97219
                 for (j = 0; j < 2; j++) {
                     v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
7d2e03af
                     if (s->mb_x >= 2) {
50f97219
                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq);
7d2e03af
                     }
                 }
             }
             v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq);
         }
 
1cf82cab
         if (s->mb_y == s->end_mb_y) {
7d2e03af
             if (s->mb_x) {
                 if (s->mb_x >= 2)
                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq);
                 if (s->mb_x >= 2) {
50f97219
                     for (j = 0; j < 2; j++) {
                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
7d2e03af
                     }
                 }
             }
 
             if (s->mb_x == s->mb_width - 1) {
                 if (s->mb_x)
                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
                 if (s->mb_x) {
50f97219
                     for (j = 0; j < 2; j++) {
                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
7d2e03af
                     }
                 }
             }
         }
     }
 }
 
 static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     int mb_pos;
 
     if (v->condover == CONDOVER_NONE)
         return;
 
     mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 
     /* Within a MB, the horizontal overlap always runs before the vertical.
      * To accomplish that, we run the H on left and internal borders of the
      * currently decoded MB. Then, we wait for the next overlap iteration
      * to do H overlap on the right edge of this MB, before moving over and
      * running the V overlap. Therefore, the V overlap makes us trail by one
      * MB col and the H overlap filter makes us trail by one MB row. This
      * is reflected in the time at which we run the put_pixels loop. */
50f97219
     if (v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
         if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
                         v->over_flags_plane[mb_pos - 1])) {
7d2e03af
             v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
                                       v->block[v->cur_blk_idx][0]);
             v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
                                       v->block[v->cur_blk_idx][2]);
50f97219
             if (!(s->flags & CODEC_FLAG_GRAY)) {
7d2e03af
                 v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
                                           v->block[v->cur_blk_idx][4]);
                 v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
                                           v->block[v->cur_blk_idx][5]);
             }
         }
         v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
                                   v->block[v->cur_blk_idx][1]);
         v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
                                   v->block[v->cur_blk_idx][3]);
 
         if (s->mb_x == s->mb_width - 1) {
50f97219
             if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
                                          v->over_flags_plane[mb_pos - s->mb_stride])) {
7d2e03af
                 v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
                                           v->block[v->cur_blk_idx][0]);
                 v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
                                           v->block[v->cur_blk_idx][1]);
50f97219
                 if (!(s->flags & CODEC_FLAG_GRAY)) {
7d2e03af
                     v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
                                               v->block[v->cur_blk_idx][4]);
                     v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
                                               v->block[v->cur_blk_idx][5]);
                 }
             }
             v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
                                       v->block[v->cur_blk_idx][2]);
             v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
                                       v->block[v->cur_blk_idx][3]);
         }
     }
     if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos - 1])) {
50f97219
         if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
                                      v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
7d2e03af
             v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
                                       v->block[v->left_blk_idx][0]);
             v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
                                       v->block[v->left_blk_idx][1]);
50f97219
             if (!(s->flags & CODEC_FLAG_GRAY)) {
7d2e03af
                 v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
                                           v->block[v->left_blk_idx][4]);
                 v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
                                           v->block[v->left_blk_idx][5]);
             }
         }
         v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
                                   v->block[v->left_blk_idx][2]);
         v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
                                   v->block[v->left_blk_idx][3]);
     }
 }
 
b761659b
 /** Do motion compensation over 1 macroblock
  * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
  */
 static void vc1_mc_1mv(VC1Context *v, int dir)
 {
     MpegEncContext *s = &v->s;
79dad2a9
     H264ChromaContext *h264chroma = &v->h264chroma;
b761659b
     uint8_t *srcY, *srcU, *srcV;
     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
cad16562
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
db8403d0
     int i;
7e30bfcb
     uint8_t (*luty)[256], (*lutuv)[256];
100184cc
     int use_ic;
ae591aee
 
     if ((!v->field_mode ||
          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
         !v->s.last_picture.f.data[0])
cad16562
         return;
b761659b
 
     mx = s->mv[dir][0][0];
     my = s->mv[dir][0][1];
 
     // store motion vectors for further use in B frames
50f97219
     if (s->pict_type == AV_PICTURE_TYPE_P) {
db8403d0
         for (i = 0; i < 4; i++) {
             s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
             s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
         }
b761659b
     }
cad16562
 
b761659b
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     uvmy = (my + ((my & 3) == 3)) >> 1;
c47d3835
     v->luma_mv[s->mb_x][0] = uvmx;
     v->luma_mv[s->mb_x][1] = uvmy;
cad16562
 
     if (v->field_mode &&
         v->cur_field_type != v->ref_field_type[dir]) {
50f97219
         my   = my   - 2 + 4 * v->cur_field_type;
cad16562
         uvmy = uvmy - 2 + 4 * v->cur_field_type;
     }
 
1f948745
     // fastuvmc shall be ignored for interlaced frame picture
     if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
50f97219
         uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
         uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
b761659b
     }
72e5d919
     if (!dir) {
         if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
             srcY = s->current_picture.f.data[0];
             srcU = s->current_picture.f.data[1];
             srcV = s->current_picture.f.data[2];
d8b9dbe7
             luty  = v->curr_luty;
             lutuv = v->curr_lutuv;
64b98df3
             use_ic = *v->curr_use_ic;
cad16562
         } else {
             srcY = s->last_picture.f.data[0];
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
d8b9dbe7
             luty  = v->last_luty;
             lutuv = v->last_lutuv;
5053a9a1
             use_ic = v->last_use_ic;
cad16562
         }
72e5d919
     } else {
         srcY = s->next_picture.f.data[0];
         srcU = s->next_picture.f.data[1];
         srcV = s->next_picture.f.data[2];
d8b9dbe7
         luty  = v->next_luty;
         lutuv = v->next_lutuv;
5053a9a1
         use_ic = v->next_use_ic;
b761659b
     }
 
090cd063
     if (!srcY || !srcU) {
         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
3a04c18d
         return;
090cd063
     }
3a04c18d
 
50f97219
     src_x   = s->mb_x * 16 + (mx   >> 2);
     src_y   = s->mb_y * 16 + (my   >> 2);
     uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
     uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
b761659b
 
50f97219
     if (v->profile != PROFILE_ADVANCED) {
b761659b
         src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
         src_y   = av_clip(  src_y, -16, s->mb_height * 16);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
50f97219
     } else {
b761659b
         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
         src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
     }
 
50f97219
     srcY += src_y   * s->linesize   + src_x;
b761659b
     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
 
cad16562
     if (v->field_mode && v->ref_field_type[dir]) {
         srcY += s->current_picture_ptr->f.linesize[0];
         srcU += s->current_picture_ptr->f.linesize[1];
         srcV += s->current_picture_ptr->f.linesize[2];
     }
 
b761659b
     /* for grayscale we should not try to read from unknown area */
50f97219
     if (s->flags & CODEC_FLAG_GRAY) {
b761659b
         srcU = s->edge_emu_buffer + 18 * s->linesize;
         srcV = s->edge_emu_buffer + 18 * s->linesize;
     }
 
100184cc
     if (v->rangeredfrm || use_ic
d209c27b
         || s->h_edge_pos < 22 || v_edge_pos < 22
50f97219
         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
7cc3c4e1
         || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {
50f97219
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
b761659b
 
         srcY -= s->mspel * (1 + s->linesize);
458446ac
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
                                  s->linesize, s->linesize,
8c53d39e
                                  17 + s->mspel * 2, 17 + s->mspel * 2,
                                  src_x - s->mspel, src_y - s->mspel,
                                  s->h_edge_pos, v_edge_pos);
b761659b
         srcY = s->edge_emu_buffer;
458446ac
         s->vdsp.emulated_edge_mc(uvbuf, srcU,
                                  s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1,
91e00c4a
                                  uvsrc_x, uvsrc_y,
face578d
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
458446ac
         s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
                                  s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1,
91e00c4a
                                  uvsrc_x, uvsrc_y,
face578d
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
b761659b
         srcU = uvbuf;
         srcV = uvbuf + 16;
         /* if we deal with range reduction we need to scale source blocks */
50f97219
         if (v->rangeredfrm) {
b761659b
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
50f97219
             for (j = 0; j < 17 + s->mspel * 2; j++) {
                 for (i = 0; i < 17 + s->mspel * 2; i++)
                     src[i] = ((src[i] - 128) >> 1) + 128;
b761659b
                 src += s->linesize;
             }
50f97219
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
                 for (i = 0; i < 9; i++) {
                     src[i]  = ((src[i]  - 128) >> 1) + 128;
b761659b
                     src2[i] = ((src2[i] - 128) >> 1) + 128;
                 }
50f97219
                 src  += s->uvlinesize;
b761659b
                 src2 += s->uvlinesize;
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
100184cc
         if (use_ic) {
b761659b
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
50f97219
             for (j = 0; j < 17 + s->mspel * 2; j++) {
d8b9dbe7
                 int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
50f97219
                 for (i = 0; i < 17 + s->mspel * 2; i++)
7e30bfcb
                     src[i] = luty[f][src[i]];
b761659b
                 src += s->linesize;
             }
50f97219
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
d8b9dbe7
                 int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
50f97219
                 for (i = 0; i < 9; i++) {
7e30bfcb
                     src[i]  = lutuv[f][src[i]];
                     src2[i] = lutuv[f][src2[i]];
b761659b
                 }
50f97219
                 src  += s->uvlinesize;
b761659b
                 src2 += s->uvlinesize;
             }
         }
         srcY += s->mspel * (1 + s->linesize);
     }
 
50f97219
     if (s->mspel) {
b761659b
         dxy = ((my & 3) << 2) | (mx & 3);
3ca3709a
         v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0]    , srcY    , s->linesize, v->rnd);
         v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
b761659b
         srcY += s->linesize * 8;
3ca3709a
         v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
         v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
b761659b
     } else { // hpel mc - always used for luma
         dxy = (my & 2) | ((mx & 2) >> 1);
50f97219
         if (!v->rnd)
3ca3709a
             s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
b761659b
         else
3ca3709a
             s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
b761659b
     }
 
50f97219
     if (s->flags & CODEC_FLAG_GRAY) return;
b761659b
     /* Chroma MC always uses qpel bilinear */
50f97219
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
3ca3709a
         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
50f97219
     } else {
3ca3709a
         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
cad16562
     }
 }
 
 static inline int median4(int a, int b, int c, int d)
 {
50f97219
     if (a < b) {
         if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
         else       return (FFMIN(b, c) + FFMAX(a, d)) / 2;
cad16562
     } else {
50f97219
         if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
         else       return (FFMIN(a, c) + FFMAX(b, d)) / 2;
b761659b
     }
 }
 
 /** Do motion compensation for 4-MV macroblock - luminance block
  */
db8403d0
 static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
b761659b
 {
     MpegEncContext *s = &v->s;
     uint8_t *srcY;
     int dxy, mx, my, src_x, src_y;
     int off;
1f948745
     int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
cad16562
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
7e30bfcb
     uint8_t (*luty)[256];
100184cc
     int use_ic;
50f97219
 
ae591aee
     if ((!v->field_mode ||
          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
         !v->s.last_picture.f.data[0])
50f97219
         return;
 
cad16562
     mx = s->mv[dir][n][0];
     my = s->mv[dir][n][1];
 
     if (!dir) {
72e5d919
         if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
             srcY = s->current_picture.f.data[0];
7e30bfcb
             luty = v->curr_luty;
64b98df3
             use_ic = *v->curr_use_ic;
782ebd61
         } else {
cad16562
             srcY = s->last_picture.f.data[0];
7e30bfcb
             luty = v->last_luty;
5053a9a1
             use_ic = v->last_use_ic;
782ebd61
         }
     } else {
cad16562
         srcY = s->next_picture.f.data[0];
7e30bfcb
         luty = v->next_luty;
5053a9a1
         use_ic = v->next_use_ic;
782ebd61
     }
b761659b
 
090cd063
     if (!srcY) {
         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
3a04c18d
         return;
090cd063
     }
3a04c18d
 
cad16562
     if (v->field_mode) {
         if (v->cur_field_type != v->ref_field_type[dir])
             my = my - 2 + 4 * v->cur_field_type;
     }
 
     if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
         int same_count = 0, opp_count = 0, k;
         int chosen_mv[2][4][2], f;
         int tx, ty;
         for (k = 0; k < 4; k++) {
             f = v->mv_f[0][s->block_index[k] + v->blocks_off];
             chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
             chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
50f97219
             opp_count  += f;
cad16562
             same_count += 1 - f;
         }
         f = opp_count > same_count;
         switch (f ? opp_count : same_count) {
         case 4:
50f97219
             tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],
                          chosen_mv[f][2][0], chosen_mv[f][3][0]);
             ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],
                          chosen_mv[f][2][1], chosen_mv[f][3][1]);
cad16562
             break;
         case 3:
             tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
             ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
             break;
         case 2:
             tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
             ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
             break;
d8246d47
         default:
6c5bd7d7
             av_assert0(0);
cad16562
         }
759001c5
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
50f97219
         for (k = 0; k < 4; k++)
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
cad16562
     }
 
1f948745
     if (v->fcm == ILACE_FRAME) {  // not sure if needed for other types of picture
cad16562
         int qx, qy;
50f97219
         int width  = s->avctx->coded_width;
cad16562
         int height = s->avctx->coded_height >> 1;
db8403d0
         if (s->pict_type == AV_PICTURE_TYPE_P) {
             s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
             s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
         }
cad16562
         qx = (s->mb_x * 16) + (mx >> 2);
         qy = (s->mb_y *  8) + (my >> 3);
 
         if (qx < -17)
             mx -= 4 * (qx + 17);
         else if (qx > width)
             mx -= 4 * (qx - width);
         if (qy < -18)
             my -= 8 * (qy + 18);
         else if (qy > height + 1)
             my -= 8 * (qy - height - 1);
     }
 
1f948745
     if ((v->fcm == ILACE_FRAME) && fieldmv)
50f97219
         off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
cad16562
     else
50f97219
         off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
b761659b
 
50f97219
     src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
cad16562
     if (!fieldmv)
50f97219
         src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
cad16562
     else
         src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
b761659b
 
50f97219
     if (v->profile != PROFILE_ADVANCED) {
         src_x = av_clip(src_x, -16, s->mb_width  * 16);
         src_y = av_clip(src_y, -16, s->mb_height * 16);
     } else {
         src_x = av_clip(src_x, -17, s->avctx->coded_width);
1f948745
         if (v->fcm == ILACE_FRAME) {
cad16562
             if (src_y & 1)
50f97219
                 src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
cad16562
             else
50f97219
                 src_y = av_clip(src_y, -18, s->avctx->coded_height);
cad16562
         } else {
50f97219
             src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
cad16562
         }
b761659b
     }
 
     srcY += src_y * s->linesize + src_x;
cad16562
     if (v->field_mode && v->ref_field_type[dir])
         srcY += s->current_picture_ptr->f.linesize[0];
b761659b
 
cad16562
     if (fieldmv && !(src_y & 1))
         v_edge_pos--;
     if (fieldmv && (src_y & 1) && src_y < 4)
         src_y--;
100184cc
     if (v->rangeredfrm || use_ic
d209c27b
         || s->h_edge_pos < 13 || v_edge_pos < 23
50f97219
         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
         || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
cad16562
         srcY -= s->mspel * (1 + (s->linesize << fieldmv));
         /* check emulate edge stride and offset */
458446ac
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
                                  s->linesize, s->linesize,
8c53d39e
                                  9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,
                                  src_x - s->mspel, src_y - (s->mspel << fieldmv),
                                  s->h_edge_pos, v_edge_pos);
b761659b
         srcY = s->edge_emu_buffer;
         /* if we deal with range reduction we need to scale source blocks */
50f97219
         if (v->rangeredfrm) {
b761659b
             int i, j;
             uint8_t *src;
 
             src = srcY;
50f97219
             for (j = 0; j < 9 + s->mspel * 2; j++) {
                 for (i = 0; i < 9 + s->mspel * 2; i++)
                     src[i] = ((src[i] - 128) >> 1) + 128;
cad16562
                 src += s->linesize << fieldmv;
b761659b
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
100184cc
         if (use_ic) {
b761659b
             int i, j;
             uint8_t *src;
 
             src = srcY;
50f97219
             for (j = 0; j < 9 + s->mspel * 2; j++) {
d8b9dbe7
                 int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
50f97219
                 for (i = 0; i < 9 + s->mspel * 2; i++)
7e30bfcb
                     src[i] = luty[f][src[i]];
cad16562
                 src += s->linesize << fieldmv;
b761659b
             }
         }
cad16562
         srcY += s->mspel * (1 + (s->linesize << fieldmv));
b761659b
     }
 
50f97219
     if (s->mspel) {
b761659b
         dxy = ((my & 3) << 2) | (mx & 3);
db8403d0
         if (avg)
             v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
         else
             v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
b761659b
     } else { // hpel mc - always used for luma
         dxy = (my & 2) | ((mx & 2) >> 1);
50f97219
         if (!v->rnd)
4ba5dbc0
             s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
b761659b
         else
4ba5dbc0
             s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
b761659b
     }
 }
 
cad16562
 static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
b761659b
 {
cad16562
     int idx, i;
     static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
50f97219
 
     idx =  ((a[3] != flag) << 3)
          | ((a[2] != flag) << 2)
          | ((a[1] != flag) << 1)
          |  (a[0] != flag);
     if (!idx) {
cad16562
         *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
         *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
         return 4;
50f97219
     } else if (count[idx] == 1) {
         switch (idx) {
cad16562
         case 0x1:
             *tx = mid_pred(mvx[1], mvx[2], mvx[3]);
             *ty = mid_pred(mvy[1], mvy[2], mvy[3]);
             return 3;
         case 0x2:
             *tx = mid_pred(mvx[0], mvx[2], mvx[3]);
             *ty = mid_pred(mvy[0], mvy[2], mvy[3]);
             return 3;
         case 0x4:
             *tx = mid_pred(mvx[0], mvx[1], mvx[3]);
             *ty = mid_pred(mvy[0], mvy[1], mvy[3]);
             return 3;
         case 0x8:
             *tx = mid_pred(mvx[0], mvx[1], mvx[2]);
             *ty = mid_pred(mvy[0], mvy[1], mvy[2]);
             return 3;
         }
50f97219
     } else if (count[idx] == 2) {
cad16562
         int t1 = 0, t2 = 0;
         for (i = 0; i < 3; i++)
             if (!a[i]) {
                 t1 = i;
                 break;
             }
         for (i = t1 + 1; i < 4; i++)
             if (!a[i]) {
                 t2 = i;
                 break;
             }
         *tx = (mvx[t1] + mvx[t2]) / 2;
         *ty = (mvy[t1] + mvy[t2]) / 2;
         return 2;
b761659b
     } else {
cad16562
         return 0;
b761659b
     }
cad16562
     return -1;
b761659b
 }
 
 /** Do motion compensation for 4-MV macroblock - both chroma blocks
  */
cad16562
 static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
b761659b
 {
     MpegEncContext *s = &v->s;
79dad2a9
     H264ChromaContext *h264chroma = &v->h264chroma;
b761659b
     uint8_t *srcU, *srcV;
     int uvmx, uvmy, uvsrc_x, uvsrc_y;
cad16562
     int k, tx = 0, ty = 0;
     int mvx[4], mvy[4], intra[4], mv_f[4];
     int valid_count;
3ca3709a
     int chroma_ref_type = v->cur_field_type;
cad16562
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
7e30bfcb
     uint8_t (*lutuv)[256];
100184cc
     int use_ic;
b761659b
 
50f97219
     if (!v->field_mode && !v->s.last_picture.f.data[0])
         return;
     if (s->flags & CODEC_FLAG_GRAY)
         return;
b761659b
 
50f97219
     for (k = 0; k < 4; k++) {
cad16562
         mvx[k] = s->mv[dir][k][0];
         mvy[k] = s->mv[dir][k][1];
         intra[k] = v->mb_type[0][s->block_index[k]];
         if (v->field_mode)
             mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
b761659b
     }
 
     /* calculate chroma MV vector from four luma MVs */
cad16562
     if (!v->field_mode || (v->field_mode && !v->numref)) {
         valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
88058d9a
         chroma_ref_type = v->reffield;
cad16562
         if (!valid_count) {
759001c5
             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
cad16562
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
             return; //no need to do MC for intra blocks
b761659b
         }
     } else {
cad16562
         int dominant = 0;
         if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
             dominant = 1;
         valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
         if (dominant)
             chroma_ref_type = !v->cur_field_type;
b761659b
     }
ae591aee
     if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0])
         return;
759001c5
     s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
     s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
50f97219
     uvmx = (tx + ((tx & 3) == 3)) >> 1;
     uvmy = (ty + ((ty & 3) == 3)) >> 1;
cad16562
 
c47d3835
     v->luma_mv[s->mb_x][0] = uvmx;
     v->luma_mv[s->mb_x][1] = uvmy;
cad16562
 
50f97219
     if (v->fastuvmc) {
         uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
         uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
b761659b
     }
cad16562
     // Field conversion bias
     if (v->cur_field_type != chroma_ref_type)
         uvmy += 2 - 4 * chroma_ref_type;
b761659b
 
     uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
     uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
 
50f97219
     if (v->profile != PROFILE_ADVANCED) {
         uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width  * 8);
         uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
     } else {
         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
b761659b
     }
 
cad16562
     if (!dir) {
c5669f3c
         if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
236b0c40
             srcU = s->current_picture.f.data[1];
             srcV = s->current_picture.f.data[2];
d8b9dbe7
             lutuv = v->curr_lutuv;
64b98df3
             use_ic = *v->curr_use_ic;
cad16562
         } else {
8e749733
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
d8b9dbe7
             lutuv = v->last_lutuv;
5053a9a1
             use_ic = v->last_use_ic;
cad16562
         }
     } else {
8e749733
         srcU = s->next_picture.f.data[1];
         srcV = s->next_picture.f.data[2];
d8b9dbe7
         lutuv = v->next_lutuv;
5053a9a1
         use_ic = v->next_use_ic;
cad16562
     }
 
090cd063
     if (!srcU) {
         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
3a04c18d
         return;
090cd063
     }
3a04c18d
 
8e749733
     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
 
cad16562
     if (v->field_mode) {
         if (chroma_ref_type) {
             srcU += s->current_picture_ptr->f.linesize[1];
             srcV += s->current_picture_ptr->f.linesize[2];
         }
     }
 
100184cc
     if (v->rangeredfrm || use_ic
d209c27b
         || s->h_edge_pos < 18 || v_edge_pos < 18
50f97219
         || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
         || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
458446ac
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
                                  s->uvlinesize, s->uvlinesize,
8c53d39e
                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
458446ac
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
                                  s->uvlinesize, s->uvlinesize,
8c53d39e
                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
b761659b
         srcU = s->edge_emu_buffer;
         srcV = s->edge_emu_buffer + 16;
 
         /* if we deal with range reduction we need to scale source blocks */
50f97219
         if (v->rangeredfrm) {
b761659b
             int i, j;
             uint8_t *src, *src2;
 
50f97219
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
                 for (i = 0; i < 9; i++) {
                     src[i]  = ((src[i]  - 128) >> 1) + 128;
b761659b
                     src2[i] = ((src2[i] - 128) >> 1) + 128;
                 }
50f97219
                 src  += s->uvlinesize;
b761659b
                 src2 += s->uvlinesize;
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
100184cc
         if (use_ic) {
b761659b
             int i, j;
             uint8_t *src, *src2;
 
50f97219
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
d8b9dbe7
                 int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
50f97219
                 for (i = 0; i < 9; i++) {
7e30bfcb
                     src[i]  = lutuv[f][src[i]];
                     src2[i] = lutuv[f][src2[i]];
b761659b
                 }
50f97219
                 src  += s->uvlinesize;
b761659b
                 src2 += s->uvlinesize;
             }
         }
     }
 
     /* Chroma MC always uses qpel bilinear */
50f97219
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
3ca3709a
         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
50f97219
     } else {
3ca3709a
         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
cad16562
     }
 }
 
5183365a
 /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
cad16562
  */
9b49d397
 static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
cad16562
 {
     MpegEncContext *s = &v->s;
79dad2a9
     H264ChromaContext *h264chroma = &v->h264chroma;
cad16562
     uint8_t *srcU, *srcV;
     int uvsrc_x, uvsrc_y;
     int uvmx_field[4], uvmy_field[4];
     int i, off, tx, ty;
     int fieldmv = v->blk_mv_type[s->block_index[0]];
50f97219
     static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
cad16562
     int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
     int v_edge_pos = s->v_edge_pos >> 1;
9b49d397
     int use_ic;
     uint8_t (*lutuv)[256];
cad16562
 
50f97219
     if (s->flags & CODEC_FLAG_GRAY)
         return;
cad16562
 
     for (i = 0; i < 4; i++) {
1be175f9
         int d = i < 2 ? dir: dir2;
9b49d397
         tx = s->mv[d][i][0];
cad16562
         uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
9b49d397
         ty = s->mv[d][i][1];
cad16562
         if (fieldmv)
             uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
         else
             uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
     }
 
     for (i = 0; i < 4; i++) {
         off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
50f97219
         uvsrc_x = s->mb_x * 8 +  (i & 1) * 4           + (uvmx_field[i] >> 2);
cad16562
         uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
         // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
50f97219
         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
9b49d397
         if (i < 2 ? dir : dir2) {
6c4516d0
             srcU = s->next_picture.f.data[1];
             srcV = s->next_picture.f.data[2];
9b49d397
             lutuv  = v->next_lutuv;
             use_ic = v->next_use_ic;
         } else {
6c4516d0
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
9b49d397
             lutuv  = v->last_lutuv;
             use_ic = v->last_use_ic;
         }
6c4516d0
         if (!srcU)
             return;
         srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
         srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
cad16562
         uvmx_field[i] = (uvmx_field[i] & 3) << 1;
         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
 
         if (fieldmv && !(uvsrc_y & 1))
bde6f6ea
             v_edge_pos = (s->v_edge_pos >> 1) - 1;
 
cad16562
         if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
             uvsrc_y--;
5053a9a1
         if (use_ic
d209c27b
             || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
cad16562
             || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
50f97219
             || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
458446ac
             s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
                                      s->uvlinesize, s->uvlinesize,
8c53d39e
                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
                                      s->h_edge_pos >> 1, v_edge_pos);
458446ac
             s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
                                      s->uvlinesize, s->uvlinesize,
8c53d39e
                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
                                      s->h_edge_pos >> 1, v_edge_pos);
cad16562
             srcU = s->edge_emu_buffer;
             srcV = s->edge_emu_buffer + 16;
 
             /* if we deal with intensity compensation we need to scale source blocks */
100184cc
             if (use_ic) {
cad16562
                 int i, j;
                 uint8_t *src, *src2;
 
50f97219
                 src  = srcU;
                 src2 = srcV;
                 for (j = 0; j < 5; j++) {
1be175f9
                     int f = (uvsrc_y + (j << fieldmv)) & 1;
50f97219
                     for (i = 0; i < 5; i++) {
d29f9f4a
                         src[i]  = lutuv[f][src[i]];
                         src2[i] = lutuv[f][src2[i]];
cad16562
                     }
90c2e40e
                     src  += s->uvlinesize << fieldmv;
                     src2 += s->uvlinesize << fieldmv;
cad16562
                 }
             }
         }
9b49d397
         if (avg) {
             if (!v->rnd) {
                 h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
                 h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
             } else {
                 v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
                 v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
             }
         } else {
1be175f9
             if (!v->rnd) {
                 h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
                 h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
             } else {
                 v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
                 v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
             }
9b49d397
         }
b761659b
     }
 }
 
 /***********************************************************************/
 /**
21a19b79
  * @name VC-1 Block-level functions
b761659b
  * @see 7.1.4, p91 and 8.1.1.7, p(1)04
  * @{
  */
 
 /**
  * @def GET_MQUANT
  * @brief Get macroblock-level quantizer scale
  */
 #define GET_MQUANT()                                           \
50f97219
     if (v->dquantfrm) {                                        \
         int edges = 0;                                         \
         if (v->dqprofile == DQPROFILE_ALL_MBS) {               \
             if (v->dqbilevel) {                                \
                 mquant = (get_bits1(gb)) ? v->altpq : v->pq;   \
             } else {                                           \
                 mqdiff = get_bits(gb, 3);                      \
                 if (mqdiff != 7)                               \
                     mquant = v->pq + mqdiff;                   \
                 else                                           \
                     mquant = get_bits(gb, 5);                  \
             }                                                  \
         }                                                      \
         if (v->dqprofile == DQPROFILE_SINGLE_EDGE)             \
             edges = 1 << v->dqsbedge;                          \
         else if (v->dqprofile == DQPROFILE_DOUBLE_EDGES)       \
             edges = (3 << v->dqsbedge) % 15;                   \
         else if (v->dqprofile == DQPROFILE_FOUR_EDGES)         \
             edges = 15;                                        \
         if ((edges&1) && !s->mb_x)                             \
             mquant = v->altpq;                                 \
         if ((edges&2) && s->first_slice_line)                  \
             mquant = v->altpq;                                 \
         if ((edges&4) && s->mb_x == (s->mb_width - 1))         \
             mquant = v->altpq;                                 \
         if ((edges&8) && s->mb_y == (s->mb_height - 1))        \
             mquant = v->altpq;                                 \
a60a4d70
         if (!mquant || mquant > 31) {                          \
45838561
             av_log(v->s.avctx, AV_LOG_ERROR,                   \
                    "Overriding invalid mquant %d\n", mquant);  \
             mquant = 1;                                        \
         }                                                      \
50f97219
     }
b761659b
 
 /**
  * @def GET_MVDATA(_dmv_x, _dmv_y)
  * @brief Get MV differentials
  * @see MVDATA decoding from 8.3.5.2, p(1)20
  * @param _dmv_x Horizontal differential for decoded MV
  * @param _dmv_y Vertical differential for decoded MV
  */
50f97219
 #define GET_MVDATA(_dmv_x, _dmv_y)                                      \
     index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \
                          VC1_MV_DIFF_VLC_BITS, 2);                      \
     if (index > 36) {                                                   \
         mb_has_coeffs = 1;                                              \
         index -= 37;                                                    \
     } else                                                              \
         mb_has_coeffs = 0;                                              \
     s->mb_intra = 0;                                                    \
     if (!index) {                                                       \
         _dmv_x = _dmv_y = 0;                                            \
     } else if (index == 35) {                                           \
         _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample);          \
         _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample);          \
     } else if (index == 36) {                                           \
         _dmv_x = 0;                                                     \
         _dmv_y = 0;                                                     \
         s->mb_intra = 1;                                                \
     } else {                                                            \
         index1 = index % 6;                                             \
         if (!s->quarter_sample && index1 == 5) val = 1;                 \
         else                                   val = 0;                 \
         if (size_table[index1] - val > 0)                               \
             val = get_bits(gb, size_table[index1] - val);               \
         else                                   val = 0;                 \
         sign = 0 - (val&1);                                             \
         _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \
                                                                         \
         index1 = index / 6;                                             \
         if (!s->quarter_sample && index1 == 5) val = 1;                 \
         else                                   val = 0;                 \
         if (size_table[index1] - val > 0)                               \
             val = get_bits(gb, size_table[index1] - val);               \
         else                                   val = 0;                 \
         sign = 0 - (val & 1);                                           \
         _dmv_y = (sign ^ ((val >> 1) + offset_table[index1])) - sign;   \
     }
 
 static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x,
                                                    int *dmv_y, int *pred_flag)
cad16562
 {
     int index, index1;
     int extend_x = 0, extend_y = 0;
     GetBitContext *gb = &v->s.gb;
     int bits, esc;
     int val, sign;
     const int* offs_tab;
 
     if (v->numref) {
         bits = VC1_2REF_MVDATA_VLC_BITS;
50f97219
         esc  = 125;
cad16562
     } else {
         bits = VC1_1REF_MVDATA_VLC_BITS;
50f97219
         esc  = 71;
cad16562
     }
     switch (v->dmvrange) {
     case 1:
         extend_x = 1;
         break;
     case 2:
         extend_y = 1;
         break;
     case 3:
         extend_x = extend_y = 1;
         break;
     }
     index = get_vlc2(gb, v->imv_vlc->table, bits, 3);
     if (index == esc) {
         *dmv_x = get_bits(gb, v->k_x);
         *dmv_y = get_bits(gb, v->k_y);
         if (v->numref) {
7b8c5b26
             if (pred_flag) {
                 *pred_flag = *dmv_y & 1;
                 *dmv_y     = (*dmv_y + *pred_flag) >> 1;
             } else {
                 *dmv_y     = (*dmv_y + (*dmv_y & 1)) >> 1;
             }
cad16562
         }
     }
     else {
b378a233
         av_assert0(index < esc);
cad16562
         if (extend_x)
             offs_tab = offset_table2;
         else
             offs_tab = offset_table1;
         index1 = (index + 1) % 9;
         if (index1 != 0) {
50f97219
             val    = get_bits(gb, index1 + extend_x);
             sign   = 0 -(val & 1);
cad16562
             *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;
         } else
             *dmv_x = 0;
         if (extend_y)
             offs_tab = offset_table2;
         else
             offs_tab = offset_table1;
         index1 = (index + 1) / 9;
         if (index1 > v->numref) {
50f97219
             val    = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);
             sign   = 0 - (val & 1);
cad16562
             *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
         } else
             *dmv_y = 0;
7b8c5b26
         if (v->numref && pred_flag)
cad16562
             *pred_flag = index1 & 1;
     }
 }
 
 static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
 {
     int scaledvalue, refdist;
     int scalesame1, scalesame2;
     int scalezone1_x, zone1offset_x;
73447eb4
     int table_index = dir ^ v->second_field;
cad16562
 
     if (v->s.pict_type != AV_PICTURE_TYPE_B)
         refdist = v->refdist;
     else
         refdist = dir ? v->brfd : v->frfd;
     if (refdist > 3)
         refdist = 3;
5f2c159c
     scalesame1    = ff_vc1_field_mvpred_scales[table_index][1][refdist];
     scalesame2    = ff_vc1_field_mvpred_scales[table_index][2][refdist];
     scalezone1_x  = ff_vc1_field_mvpred_scales[table_index][3][refdist];
     zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist];
cad16562
 
     if (FFABS(n) > 255)
         scaledvalue = n;
     else {
         if (FFABS(n) < scalezone1_x)
             scaledvalue = (n * scalesame1) >> 8;
         else {
             if (n < 0)
                 scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
             else
                 scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
         }
     }
     return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
 }
 
 static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
 {
     int scaledvalue, refdist;
     int scalesame1, scalesame2;
     int scalezone1_y, zone1offset_y;
73447eb4
     int table_index = dir ^ v->second_field;
cad16562
 
     if (v->s.pict_type != AV_PICTURE_TYPE_B)
         refdist = v->refdist;
     else
         refdist = dir ? v->brfd : v->frfd;
     if (refdist > 3)
         refdist = 3;
5f2c159c
     scalesame1    = ff_vc1_field_mvpred_scales[table_index][1][refdist];
     scalesame2    = ff_vc1_field_mvpred_scales[table_index][2][refdist];
     scalezone1_y  = ff_vc1_field_mvpred_scales[table_index][4][refdist];
     zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist];
cad16562
 
     if (FFABS(n) > 63)
         scaledvalue = n;
     else {
         if (FFABS(n) < scalezone1_y)
             scaledvalue = (n * scalesame1) >> 8;
         else {
             if (n < 0)
                 scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
             else
                 scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
         }
     }
 
     if (v->cur_field_type && !v->ref_field_type[dir])
         return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
     else
         return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
 }
 
 static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
 {
     int scalezone1_x, zone1offset_x;
     int scaleopp1, scaleopp2, brfd;
     int scaledvalue;
 
     brfd = FFMIN(v->brfd, 3);
5f2c159c
     scalezone1_x  = ff_vc1_b_field_mvpred_scales[3][brfd];
     zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd];
     scaleopp1     = ff_vc1_b_field_mvpred_scales[1][brfd];
     scaleopp2     = ff_vc1_b_field_mvpred_scales[2][brfd];
cad16562
 
     if (FFABS(n) > 255)
         scaledvalue = n;
     else {
         if (FFABS(n) < scalezone1_x)
             scaledvalue = (n * scaleopp1) >> 8;
         else {
             if (n < 0)
                 scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
             else
                 scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
         }
     }
     return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
 }
 
 static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
 {
     int scalezone1_y, zone1offset_y;
     int scaleopp1, scaleopp2, brfd;
     int scaledvalue;
 
     brfd = FFMIN(v->brfd, 3);
5f2c159c
     scalezone1_y  = ff_vc1_b_field_mvpred_scales[4][brfd];
     zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd];
     scaleopp1     = ff_vc1_b_field_mvpred_scales[1][brfd];
     scaleopp2     = ff_vc1_b_field_mvpred_scales[2][brfd];
cad16562
 
     if (FFABS(n) > 63)
         scaledvalue = n;
     else {
         if (FFABS(n) < scalezone1_y)
             scaledvalue = (n * scaleopp1) >> 8;
         else {
             if (n < 0)
                 scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
             else
                 scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
         }
     }
     if (v->cur_field_type && !v->ref_field_type[dir]) {
         return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
     } else {
         return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
     }
 }
 
50f97219
 static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
                                          int dim, int dir)
cad16562
 {
     int brfd, scalesame;
6475a6e1
     int hpel = 1 - v->s.quarter_sample;
50f97219
 
6475a6e1
     n >>= hpel;
cad16562
     if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
         if (dim)
6475a6e1
             n = scaleforsame_y(v, i, n, dir) << hpel;
cad16562
         else
6475a6e1
             n = scaleforsame_x(v, n, dir) << hpel;
         return n;
cad16562
     }
50f97219
     brfd      = FFMIN(v->brfd, 3);
5f2c159c
     scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
50f97219
 
6475a6e1
     n = (n * scalesame >> 8) << hpel;
     return n;
cad16562
 }
 
50f97219
 static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
                                         int dim, int dir)
cad16562
 {
     int refdist, scaleopp;
6475a6e1
     int hpel = 1 - v->s.quarter_sample;
50f97219
 
6475a6e1
     n >>= hpel;
cad16562
     if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
         if (dim)
6475a6e1
             n = scaleforopp_y(v, n, dir) << hpel;
cad16562
         else
6475a6e1
             n = scaleforopp_x(v, n) << hpel;
         return n;
cad16562
     }
     if (v->s.pict_type != AV_PICTURE_TYPE_B)
         refdist = FFMIN(v->refdist, 3);
     else
         refdist = dir ? v->brfd : v->frfd;
5f2c159c
     scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
50f97219
 
6475a6e1
     n = (n * scaleopp >> 8) << hpel;
     return n;
cad16562
 }
 
b761659b
 /** Predict and set motion vector
  */
50f97219
 static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
                                int mv1, int r_x, int r_y, uint8_t* is_intra,
                                int pred_flag, int dir)
b761659b
 {
c47d3835
     MpegEncContext *s = &v->s;
b761659b
     int xy, wrap, off = 0;
     int16_t *A, *B, *C;
     int px, py;
     int sum;
cad16562
     int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
7fb35ee9
     int opposite, a_f, b_f, c_f;
4344ce08
     int16_t field_predA[2];
     int16_t field_predB[2];
     int16_t field_predC[2];
cad16562
     int a_valid, b_valid, c_valid;
     int hybridmv_thresh, y_bias = 0;
 
     if (v->mv_mode == MV_PMODE_MIXED_MV ||
50f97219
         ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
         mixedmv_pic = 1;
     else
         mixedmv_pic = 0;
b761659b
     /* scale MV difference to be quad-pel */
     dmv_x <<= 1 - s->quarter_sample;
     dmv_y <<= 1 - s->quarter_sample;
 
     wrap = s->b8_stride;
50f97219
     xy   = s->block_index[n];
b761659b
 
50f97219
     if (s->mb_intra) {
759001c5
         s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
         s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
         s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
         s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
50f97219
         if (mv1) { /* duplicate motion data for 1-MV block */
759001c5
             s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
             s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
             s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
             s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
             s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
             s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
c47d3835
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
759001c5
             s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
             s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
             s->current_picture.motion_val[1][xy + wrap][0]                     = 0;
             s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
             s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
             s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
b761659b
         }
         return;
     }
 
759001c5
     C = s->current_picture.motion_val[dir][xy -    1 + v->blocks_off];
     A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
50f97219
     if (mv1) {
cad16562
         if (v->field_mode && mixedmv_pic)
             off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
         else
             off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
     } else {
b761659b
         //in 4-MV mode different blocks have different B predictor position
cad16562
         switch (n) {
b761659b
         case 0:
             off = (s->mb_x > 0) ? -1 : 1;
             break;
         case 1:
             off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
             break;
         case 2:
             off = 1;
             break;
         case 3:
             off = -1;
         }
     }
759001c5
     B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
cad16562
 
50f97219
     a_valid = !s->first_slice_line || (n == 2 || n == 3);
cad16562
     b_valid = a_valid && (s->mb_width > 1);
50f97219
     c_valid = s->mb_x || (n == 1 || n == 3);
cad16562
     if (v->field_mode) {
         a_valid = a_valid && !is_intra[xy - wrap];
         b_valid = b_valid && !is_intra[xy - wrap + off];
         c_valid = c_valid && !is_intra[xy - 1];
     }
 
     if (a_valid) {
4344ce08
         a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
         num_oppfield  += a_f;
         num_samefield += 1 - a_f;
         field_predA[0] = A[0];
         field_predA[1] = A[1];
cad16562
     } else {
4344ce08
         field_predA[0] = field_predA[1] = 0;
         a_f = 0;
cad16562
     }
     if (b_valid) {
4344ce08
         b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
         num_oppfield  += b_f;
         num_samefield += 1 - b_f;
         field_predB[0] = B[0];
         field_predB[1] = B[1];
cad16562
     } else {
4344ce08
         field_predB[0] = field_predB[1] = 0;
         b_f = 0;
cad16562
     }
62622d04
     if (c_valid) {
         c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
         num_oppfield  += c_f;
         num_samefield += 1 - c_f;
         field_predC[0] = C[0];
         field_predC[1] = C[1];
cad16562
     } else {
62622d04
         field_predC[0] = field_predC[1] = 0;
         c_f = 0;
cad16562
     }
 
     if (v->field_mode) {
eb657ece
         if (!v->numref)
             // REFFIELD determines if the last field or the second-last field is
             // to be used as reference
             opposite = 1 - v->reffield;
         else {
             if (num_samefield <= num_oppfield)
                 opposite = 1 - pred_flag;
             else
                 opposite = pred_flag;
         }
cad16562
     } else
7fb35ee9
         opposite = 0;
     if (opposite) {
4344ce08
         if (a_valid && !a_f) {
             field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
             field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
         }
         if (b_valid && !b_f) {
             field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
             field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
         }
         if (c_valid && !c_f) {
             field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
             field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
         }
         v->mv_f[dir][xy + v->blocks_off] = 1;
cad16562
         v->ref_field_type[dir] = !v->cur_field_type;
     } else {
4344ce08
         if (a_valid && a_f) {
             field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
             field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
         }
         if (b_valid && b_f) {
             field_predB[0] = scaleforsame(v, n, field_predB[0], 0, dir);
             field_predB[1] = scaleforsame(v, n, field_predB[1], 1, dir);
         }
         if (c_valid && c_f) {
             field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
             field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
         }
         v->mv_f[dir][xy + v->blocks_off] = 0;
cad16562
         v->ref_field_type[dir] = v->cur_field_type;
b761659b
     }
cad16562
 
4344ce08
     if (a_valid) {
         px = field_predA[0];
         py = field_predA[1];
     } else if (c_valid) {
         px = field_predC[0];
         py = field_predC[1];
     } else if (b_valid) {
         px = field_predB[0];
         py = field_predB[1];
     } else {
         px = 0;
         py = 0;
     }
 
     if (num_samefield + num_oppfield > 1) {
         px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
         py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
     }
 
b761659b
     /* Pullback MV as specified in 8.3.5.3.4 */
cad16562
     if (!v->field_mode) {
b761659b
         int qx, qy, X, Y;
50f97219
         qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
         qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
         X  = (s->mb_width  << 6) - 4;
         Y  = (s->mb_height << 6) - 4;
         if (mv1) {
             if (qx + px < -60) px = -60 - qx;
             if (qy + py < -60) py = -60 - qy;
b761659b
         } else {
50f97219
             if (qx + px < -28) px = -28 - qx;
             if (qy + py < -28) py = -28 - qy;
b761659b
         }
50f97219
         if (qx + px > X) px = X - qx;
         if (qy + py > Y) py = Y - qy;
b761659b
     }
cad16562
 
     if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
         /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
4bceeaf0
         hybridmv_thresh = 32;
cad16562
         if (a_valid && c_valid) {
             if (is_intra[xy - wrap])
                 sum = FFABS(px) + FFABS(py);
             else
4344ce08
                 sum = FFABS(px - field_predA[0]) + FFABS(py - field_predA[1]);
cad16562
             if (sum > hybridmv_thresh) {
                 if (get_bits1(&s->gb)) {     // read HYBRIDPRED bit
4344ce08
                     px = field_predA[0];
                     py = field_predA[1];
cad16562
                 } else {
4344ce08
                     px = field_predC[0];
                     py = field_predC[1];
cad16562
                 }
b761659b
             } else {
cad16562
                 if (is_intra[xy - 1])
                     sum = FFABS(px) + FFABS(py);
                 else
4344ce08
                     sum = FFABS(px - field_predC[0]) + FFABS(py - field_predC[1]);
cad16562
                 if (sum > hybridmv_thresh) {
50f97219
                     if (get_bits1(&s->gb)) {
4344ce08
                         px = field_predA[0];
                         py = field_predA[1];
cad16562
                     } else {
4344ce08
                         px = field_predC[0];
                         py = field_predC[1];
cad16562
                     }
                 }
             }
         }
     }
 
     if (v->field_mode && v->numref)
         r_y >>= 1;
     if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
         y_bias = 1;
     /* store MV using signed modulus of MV range defined in 4.11 */
759001c5
     s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
     s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
50f97219
     if (mv1) { /* duplicate motion data for 1-MV block */
759001c5
         s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
         s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
         s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
         s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
         s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
         s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
50f97219
         v->mv_f[dir][xy +    1 + v->blocks_off] = v->mv_f[dir][xy +            v->blocks_off];
cad16562
         v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
     }
 }
 
 /** Predict and set motion vector for interlaced frame picture MBs
  */
50f97219
 static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
db8403d0
                                      int mvn, int r_x, int r_y, uint8_t* is_intra, int dir)
cad16562
 {
     MpegEncContext *s = &v->s;
     int xy, wrap, off = 0;
     int A[2], B[2], C[2];
6c5bd7d7
     int px = 0, py = 0;
cad16562
     int a_valid = 0, b_valid = 0, c_valid = 0;
     int field_a, field_b, field_c; // 0: same, 1: opposit
     int total_valid, num_samefield, num_oppfield;
     int pos_c, pos_b, n_adj;
 
     wrap = s->b8_stride;
     xy = s->block_index[n];
 
50f97219
     if (s->mb_intra) {
759001c5
         s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
         s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
         s->current_picture.motion_val[1][xy][0] = 0;
         s->current_picture.motion_val[1][xy][1] = 0;
50f97219
         if (mvn == 1) { /* duplicate motion data for 1-MV block */
759001c5
             s->current_picture.motion_val[0][xy + 1][0]        = 0;
             s->current_picture.motion_val[0][xy + 1][1]        = 0;
             s->current_picture.motion_val[0][xy + wrap][0]     = 0;
             s->current_picture.motion_val[0][xy + wrap][1]     = 0;
             s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
             s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
cad16562
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
759001c5
             s->current_picture.motion_val[1][xy + 1][0]        = 0;
             s->current_picture.motion_val[1][xy + 1][1]        = 0;
             s->current_picture.motion_val[1][xy + wrap][0]     = 0;
             s->current_picture.motion_val[1][xy + wrap][1]     = 0;
             s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
             s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
cad16562
         }
         return;
     }
 
     off = ((n == 0) || (n == 1)) ? 1 : -1;
     /* predict A */
     if (s->mb_x || (n == 1) || (n == 3)) {
         if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
50f97219
             || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
db8403d0
             A[0] = s->current_picture.motion_val[dir][xy - 1][0];
             A[1] = s->current_picture.motion_val[dir][xy - 1][1];
cad16562
             a_valid = 1;
         } else { // current block has frame mv and cand. has field MV (so average)
db8403d0
             A[0] = (s->current_picture.motion_val[dir][xy - 1][0]
                     + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
             A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
                     + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
cad16562
             a_valid = 1;
         }
         if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
             a_valid = 0;
             A[0] = A[1] = 0;
         }
50f97219
     } else
         A[0] = A[1] = 0;
cad16562
     /* Predict B and C */
     B[0] = B[1] = C[0] = C[1] = 0;
     if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
         if (!s->first_slice_line) {
             if (!v->is_intra[s->mb_x - s->mb_stride]) {
                 b_valid = 1;
50f97219
                 n_adj   = n | 2;
                 pos_b   = s->block_index[n_adj] - 2 * wrap;
cad16562
                 if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
                     n_adj = (n & 2) | (n & 1);
                 }
db8403d0
                 B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
                 B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
cad16562
                 if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
db8403d0
                     B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
                     B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
cad16562
                 }
b761659b
             }
cad16562
             if (s->mb_width > 1) {
                 if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
                     c_valid = 1;
50f97219
                     n_adj   = 2;
                     pos_c   = s->block_index[2] - 2 * wrap + 2;
cad16562
                     if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                         n_adj = n & 2;
                     }
db8403d0
                     C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
                     C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
cad16562
                     if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
db8403d0
                         C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
                         C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
cad16562
                     }
                     if (s->mb_x == s->mb_width - 1) {
                         if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
                             c_valid = 1;
50f97219
                             n_adj   = 3;
                             pos_c   = s->block_index[3] - 2 * wrap - 2;
cad16562
                             if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                                 n_adj = n | 1;
                             }
db8403d0
                             C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
                             C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
cad16562
                             if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
db8403d0
                                 C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
                                 C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
cad16562
                             }
50f97219
                         } else
                             c_valid = 0;
cad16562
                     }
                 }
             }
         }
     } else {
50f97219
         pos_b   = s->block_index[1];
cad16562
         b_valid = 1;
db8403d0
         B[0]    = s->current_picture.motion_val[dir][pos_b][0];
         B[1]    = s->current_picture.motion_val[dir][pos_b][1];
50f97219
         pos_c   = s->block_index[0];
cad16562
         c_valid = 1;
db8403d0
         C[0]    = s->current_picture.motion_val[dir][pos_c][0];
         C[1]    = s->current_picture.motion_val[dir][pos_c][1];
cad16562
     }
 
     total_valid = a_valid + b_valid + c_valid;
     // check if predictor A is out of bounds
50f97219
     if (!s->mb_x && !(n == 1 || n == 3)) {
cad16562
         A[0] = A[1] = 0;
     }
     // check if predictor B is out of bounds
     if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
         B[0] = B[1] = C[0] = C[1] = 0;
     }
     if (!v->blk_mv_type[xy]) {
50f97219
         if (s->mb_width == 1) {
cad16562
             px = B[0];
             py = B[1];
b761659b
         } else {
cad16562
             if (total_valid >= 2) {
                 px = mid_pred(A[0], B[0], C[0]);
                 py = mid_pred(A[1], B[1], C[1]);
             } else if (total_valid) {
6136b989
                 if      (a_valid) { px = A[0]; py = A[1]; }
                 else if (b_valid) { px = B[0]; py = B[1]; }
2c7c2a53
                 else              { px = C[0]; py = C[1]; }
6c5bd7d7
             }
cad16562
         }
     } else {
         if (a_valid)
             field_a = (A[1] & 4) ? 1 : 0;
         else
             field_a = 0;
         if (b_valid)
             field_b = (B[1] & 4) ? 1 : 0;
         else
             field_b = 0;
         if (c_valid)
             field_c = (C[1] & 4) ? 1 : 0;
         else
             field_c = 0;
 
50f97219
         num_oppfield  = field_a + field_b + field_c;
cad16562
         num_samefield = total_valid - num_oppfield;
         if (total_valid == 3) {
             if ((num_samefield == 3) || (num_oppfield == 3)) {
                 px = mid_pred(A[0], B[0], C[0]);
                 py = mid_pred(A[1], B[1], C[1]);
             } else if (num_samefield >= num_oppfield) {
                 /* take one MV from same field set depending on priority
                 the check for B may not be necessary */
50f97219
                 px = !field_a ? A[0] : B[0];
                 py = !field_a ? A[1] : B[1];
cad16562
             } else {
50f97219
                 px =  field_a ? A[0] : B[0];
                 py =  field_a ? A[1] : B[1];
cad16562
             }
         } else if (total_valid == 2) {
             if (num_samefield >= num_oppfield) {
                 if (!field_a && a_valid) {
b761659b
                     px = A[0];
                     py = A[1];
cad16562
                 } else if (!field_b && b_valid) {
                     px = B[0];
                     py = B[1];
fca435fe
                 } else /*if (c_valid)*/ {
                     av_assert1(c_valid);
cad16562
                     px = C[0];
                     py = C[1];
fca435fe
                 } /*else px = py = 0;*/
cad16562
             } else {
                 if (field_a && a_valid) {
                     px = A[0];
                     py = A[1];
fca435fe
                 } else /*if (field_b && b_valid)*/ {
                     av_assert1(field_b && b_valid);
cad16562
                     px = B[0];
                     py = B[1];
fca435fe
                 } /*else if (c_valid) {
b761659b
                     px = C[0];
                     py = C[1];
fca435fe
                 }*/
b761659b
             }
cad16562
         } else if (total_valid == 1) {
             px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
             py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
6c5bd7d7
         }
b761659b
     }
cad16562
 
b761659b
     /* store MV using signed modulus of MV range defined in 4.11 */
db8403d0
     s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
     s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
50f97219
     if (mvn == 1) { /* duplicate motion data for 1-MV block */
db8403d0
         s->current_picture.motion_val[dir][xy +    1    ][0] = s->current_picture.motion_val[dir][xy][0];
         s->current_picture.motion_val[dir][xy +    1    ][1] = s->current_picture.motion_val[dir][xy][1];
         s->current_picture.motion_val[dir][xy + wrap    ][0] = s->current_picture.motion_val[dir][xy][0];
         s->current_picture.motion_val[dir][xy + wrap    ][1] = s->current_picture.motion_val[dir][xy][1];
         s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
         s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][xy][1];
cad16562
     } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
db8403d0
         s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
         s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
         s->mv[dir][n + 1][0] = s->mv[dir][n][0];
         s->mv[dir][n + 1][1] = s->mv[dir][n][1];
b761659b
     }
 }
 
 /** Motion compensation for direct or interpolated blocks in B-frames
  */
 static void vc1_interp_mc(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
79dad2a9
     H264ChromaContext *h264chroma = &v->h264chroma;
b761659b
     uint8_t *srcY, *srcU, *srcV;
     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
cad16562
     int off, off_uv;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
100184cc
     int use_ic = v->next_use_ic;
b761659b
 
cad16562
     if (!v->field_mode && !v->s.next_picture.f.data[0])
         return;
b761659b
 
50f97219
     mx   = s->mv[1][0][0];
     my   = s->mv[1][0][1];
b761659b
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     uvmy = (my + ((my & 3) == 3)) >> 1;
cad16562
     if (v->field_mode) {
afd1f619
         if (v->cur_field_type != v->ref_field_type[1]) {
50f97219
             my   = my   - 2 + 4 * v->cur_field_type;
cad16562
             uvmy = uvmy - 2 + 4 * v->cur_field_type;
afd1f619
         }
cad16562
     }
50f97219
     if (v->fastuvmc) {
         uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
         uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
b761659b
     }
657ccb5a
     srcY = s->next_picture.f.data[0];
     srcU = s->next_picture.f.data[1];
     srcV = s->next_picture.f.data[2];
b761659b
 
50f97219
     src_x   = s->mb_x * 16 + (mx   >> 2);
     src_y   = s->mb_y * 16 + (my   >> 2);
     uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
     uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
b761659b
 
50f97219
     if (v->profile != PROFILE_ADVANCED) {
b761659b
         src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
         src_y   = av_clip(  src_y, -16, s->mb_height * 16);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
50f97219
     } else {
b761659b
         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
         src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
     }
 
50f97219
     srcY += src_y   * s->linesize   + src_x;
b761659b
     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
 
cad16562
     if (v->field_mode && v->ref_field_type[1]) {
         srcY += s->current_picture_ptr->f.linesize[0];
         srcU += s->current_picture_ptr->f.linesize[1];
         srcV += s->current_picture_ptr->f.linesize[2];
     }
 
b761659b
     /* for grayscale we should not try to read from unknown area */
50f97219
     if (s->flags & CODEC_FLAG_GRAY) {
b761659b
         srcU = s->edge_emu_buffer + 18 * s->linesize;
         srcV = s->edge_emu_buffer + 18 * s->linesize;
     }
 
100184cc
     if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
8379ea5e
         || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
         || (unsigned)(src_y - 1) > v_edge_pos    - (my & 3) - 16 - 3) {
50f97219
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
b761659b
 
         srcY -= s->mspel * (1 + s->linesize);
458446ac
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
                                  s->linesize, s->linesize,
8c53d39e
                                  17 + s->mspel * 2, 17 + s->mspel * 2,
                                  src_x - s->mspel, src_y - s->mspel,
                                  s->h_edge_pos, v_edge_pos);
b761659b
         srcY = s->edge_emu_buffer;
458446ac
         s->vdsp.emulated_edge_mc(uvbuf, srcU,
                                  s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1,
91e00c4a
                                  uvsrc_x, uvsrc_y,
face578d
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
458446ac
         s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
                                  s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1,
91e00c4a
                                  uvsrc_x, uvsrc_y,
face578d
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
b761659b
         srcU = uvbuf;
         srcV = uvbuf + 16;
         /* if we deal with range reduction we need to scale source blocks */
50f97219
         if (v->rangeredfrm) {
b761659b
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
50f97219
             for (j = 0; j < 17 + s->mspel * 2; j++) {
                 for (i = 0; i < 17 + s->mspel * 2; i++)
                     src[i] = ((src[i] - 128) >> 1) + 128;
b761659b
                 src += s->linesize;
             }
50f97219
             src = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
                 for (i = 0; i < 9; i++) {
                     src[i]  = ((src[i]  - 128) >> 1) + 128;
b761659b
                     src2[i] = ((src2[i] - 128) >> 1) + 128;
                 }
50f97219
                 src  += s->uvlinesize;
b761659b
                 src2 += s->uvlinesize;
             }
         }
84c0ec92
 
100184cc
         if (use_ic) {
7e30bfcb
             uint8_t (*luty )[256] = v->next_luty;
             uint8_t (*lutuv)[256] = v->next_lutuv;
84c0ec92
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
             for (j = 0; j < 17 + s->mspel * 2; j++) {
d8b9dbe7
                 int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
84c0ec92
                 for (i = 0; i < 17 + s->mspel * 2; i++)
7e30bfcb
                     src[i] = luty[f][src[i]];
84c0ec92
                 src += s->linesize;
             }
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
d8b9dbe7
                 int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
84c0ec92
                 for (i = 0; i < 9; i++) {
7e30bfcb
                     src[i]  = lutuv[f][src[i]];
                     src2[i] = lutuv[f][src2[i]];
84c0ec92
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
             }
         }
b761659b
         srcY += s->mspel * (1 + s->linesize);
     }
 
03136539
     off    = 0;
     off_uv = 0;
cad16562
 
50f97219
     if (s->mspel) {
b761659b
         dxy = ((my & 3) << 2) | (mx & 3);
cad16562
         v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off    , srcY    , s->linesize, v->rnd);
         v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
b761659b
         srcY += s->linesize * 8;
cad16562
         v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
         v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
b761659b
     } else { // hpel mc
         dxy = (my & 2) | ((mx & 2) >> 1);
 
50f97219
         if (!v->rnd)
4ba5dbc0
             s->hdsp.avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
b761659b
         else
4ba5dbc0
             s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
b761659b
     }
 
50f97219
     if (s->flags & CODEC_FLAG_GRAY) return;
b761659b
     /* Chroma MC always uses qpel blilinear */
50f97219
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
79dad2a9
         h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
         h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
50f97219
     } else {
cad16562
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
b761659b
     }
 }
 
 static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
 {
     int n = bfrac;
 
 #if B_FRACTION_DEN==256
50f97219
     if (inv)
b761659b
         n -= 256;
50f97219
     if (!qs)
b761659b
         return 2 * ((value * n + 255) >> 9);
     return (value * n + 128) >> 8;
 #else
50f97219
     if (inv)
b761659b
         n -= B_FRACTION_DEN;
50f97219
     if (!qs)
b761659b
         return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN));
     return (value * n + B_FRACTION_DEN/2) / B_FRACTION_DEN;
 #endif
 }
 
 /** Reconstruct motion vector for B-frame and do motion compensation
  */
50f97219
 static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
                             int direct, int mode)
b761659b
 {
50f97219
     if (direct) {
b761659b
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
         return;
     }
50f97219
     if (mode == BMV_TYPE_INTERPOLATED) {
b761659b
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
         return;
     }
 
     vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
 }
 
50f97219
 static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
                                  int direct, int mvtype)
b761659b
 {
     MpegEncContext *s = &v->s;
     int xy, wrap, off = 0;
     int16_t *A, *B, *C;
     int px, py;
     int sum;
     int r_x, r_y;
     const uint8_t *is_intra = v->mb_type[0];
 
41f97420
     av_assert0(!v->field_mode);
 
b761659b
     r_x = v->range_x;
     r_y = v->range_y;
     /* scale MV difference to be quad-pel */
     dmv_x[0] <<= 1 - s->quarter_sample;
     dmv_y[0] <<= 1 - s->quarter_sample;
     dmv_x[1] <<= 1 - s->quarter_sample;
     dmv_y[1] <<= 1 - s->quarter_sample;
 
     wrap = s->b8_stride;
     xy = s->block_index[0];
 
50f97219
     if (s->mb_intra) {
20be5108
         s->current_picture.motion_val[0][xy][0] =
         s->current_picture.motion_val[0][xy][1] =
         s->current_picture.motion_val[1][xy][0] =
         s->current_picture.motion_val[1][xy][1] = 0;
b761659b
         return;
     }
f4b288a6
         if (direct && s->next_picture_ptr->field_picture)
             av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
 
759001c5
         s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
         s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
         s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
         s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
b761659b
 
cad16562
         /* Pullback predicted motion vectors as specified in 8.4.5.4 */
         s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
         s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
         s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
         s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
50f97219
     if (direct) {
20be5108
         s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
         s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
         s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
         s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
b761659b
         return;
     }
 
50f97219
     if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
759001c5
         C   = s->current_picture.motion_val[0][xy - 2];
         A   = s->current_picture.motion_val[0][xy - wrap * 2];
b761659b
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
759001c5
         B   = s->current_picture.motion_val[0][xy - wrap * 2 + off];
b761659b
 
50f97219
         if (!s->mb_x) C[0] = C[1] = 0;
         if (!s->first_slice_line) { // predictor A is not out of bounds
             if (s->mb_width == 1) {
b761659b
                 px = A[0];
                 py = A[1];
             } else {
                 px = mid_pred(A[0], B[0], C[0]);
                 py = mid_pred(A[1], B[1], C[1]);
             }
50f97219
         } else if (s->mb_x) { // predictor C is not out of bounds
b761659b
             px = C[0];
             py = C[1];
         } else {
             px = py = 0;
         }
         /* Pullback MV as specified in 8.3.5.3.4 */
         {
             int qx, qy, X, Y;
50f97219
             if (v->profile < PROFILE_ADVANCED) {
b761659b
                 qx = (s->mb_x << 5);
                 qy = (s->mb_y << 5);
50f97219
                 X  = (s->mb_width  << 5) - 4;
                 Y  = (s->mb_height << 5) - 4;
                 if (qx + px < -28) px = -28 - qx;
                 if (qy + py < -28) py = -28 - qy;
                 if (qx + px > X) px = X - qx;
                 if (qy + py > Y) py = Y - qy;
b761659b
             } else {
                 qx = (s->mb_x << 6);
                 qy = (s->mb_y << 6);
50f97219
                 X  = (s->mb_width  << 6) - 4;
                 Y  = (s->mb_height << 6) - 4;
                 if (qx + px < -60) px = -60 - qx;
                 if (qy + py < -60) py = -60 - qy;
                 if (qx + px > X) px = X - qx;
                 if (qy + py > Y) py = Y - qy;
b761659b
             }
         }
         /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
50f97219
         if (0 && !s->first_slice_line && s->mb_x) {
             if (is_intra[xy - wrap])
b761659b
                 sum = FFABS(px) + FFABS(py);
             else
                 sum = FFABS(px - A[0]) + FFABS(py - A[1]);
50f97219
             if (sum > 32) {
                 if (get_bits1(&s->gb)) {
b761659b
                     px = A[0];
                     py = A[1];
                 } else {
                     px = C[0];
                     py = C[1];
                 }
             } else {
50f97219
                 if (is_intra[xy - 2])
b761659b
                     sum = FFABS(px) + FFABS(py);
                 else
                     sum = FFABS(px - C[0]) + FFABS(py - C[1]);
50f97219
                 if (sum > 32) {
                     if (get_bits1(&s->gb)) {
b761659b
                         px = A[0];
                         py = A[1];
                     } else {
                         px = C[0];
                         py = C[1];
                     }
                 }
             }
         }
         /* store MV using signed modulus of MV range defined in 4.11 */
         s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
         s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
50f97219
     if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
759001c5
         C   = s->current_picture.motion_val[1][xy - 2];
         A   = s->current_picture.motion_val[1][xy - wrap * 2];
b761659b
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
759001c5
         B   = s->current_picture.motion_val[1][xy - wrap * 2 + off];
b761659b
 
50f97219
         if (!s->mb_x)
             C[0] = C[1] = 0;
         if (!s->first_slice_line) { // predictor A is not out of bounds
             if (s->mb_width == 1) {
b761659b
                 px = A[0];
                 py = A[1];
             } else {
                 px = mid_pred(A[0], B[0], C[0]);
                 py = mid_pred(A[1], B[1], C[1]);
             }
50f97219
         } else if (s->mb_x) { // predictor C is not out of bounds
b761659b
             px = C[0];
             py = C[1];
         } else {
             px = py = 0;
         }
         /* Pullback MV as specified in 8.3.5.3.4 */
         {
             int qx, qy, X, Y;
50f97219
             if (v->profile < PROFILE_ADVANCED) {
b761659b
                 qx = (s->mb_x << 5);
                 qy = (s->mb_y << 5);
50f97219
                 X  = (s->mb_width  << 5) - 4;
                 Y  = (s->mb_height << 5) - 4;
                 if (qx + px < -28) px = -28 - qx;
                 if (qy + py < -28) py = -28 - qy;
                 if (qx + px > X) px = X - qx;
                 if (qy + py > Y) py = Y - qy;
b761659b
             } else {
                 qx = (s->mb_x << 6);
                 qy = (s->mb_y << 6);
50f97219
                 X  = (s->mb_width  << 6) - 4;
                 Y  = (s->mb_height << 6) - 4;
                 if (qx + px < -60) px = -60 - qx;
                 if (qy + py < -60) py = -60 - qy;
                 if (qx + px > X) px = X - qx;
                 if (qy + py > Y) py = Y - qy;
b761659b
             }
         }
         /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
50f97219
         if (0 && !s->first_slice_line && s->mb_x) {
             if (is_intra[xy - wrap])
b761659b
                 sum = FFABS(px) + FFABS(py);
             else
                 sum = FFABS(px - A[0]) + FFABS(py - A[1]);
50f97219
             if (sum > 32) {
                 if (get_bits1(&s->gb)) {
b761659b
                     px = A[0];
                     py = A[1];
                 } else {
                     px = C[0];
                     py = C[1];
                 }
             } else {
50f97219
                 if (is_intra[xy - 2])
b761659b
                     sum = FFABS(px) + FFABS(py);
                 else
                     sum = FFABS(px - C[0]) + FFABS(py - C[1]);
50f97219
                 if (sum > 32) {
                     if (get_bits1(&s->gb)) {
b761659b
                         px = A[0];
                         py = A[1];
                     } else {
                         px = C[0];
                         py = C[1];
                     }
                 }
             }
         }
         /* store MV using signed modulus of MV range defined in 4.11 */
 
         s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
         s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
759001c5
     s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
     s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
     s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
     s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
b761659b
 }
 
cad16562
 static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
 {
     int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
     MpegEncContext *s = &v->s;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 
     if (v->bmvtype == BMV_TYPE_DIRECT) {
         int total_opp, k, f;
759001c5
         if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
             s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
9cc74c9f
                                       v->bfraction, 0, s->quarter_sample);
759001c5
             s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
9cc74c9f
                                       v->bfraction, 0, s->quarter_sample);
759001c5
             s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
9cc74c9f
                                       v->bfraction, 1, s->quarter_sample);
759001c5
             s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
9cc74c9f
                                       v->bfraction, 1, s->quarter_sample);
cad16562
 
             total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
                       + v->mv_f_next[0][s->block_index[1] + v->blocks_off]
                       + v->mv_f_next[0][s->block_index[2] + v->blocks_off]
                       + v->mv_f_next[0][s->block_index[3] + v->blocks_off];
             f = (total_opp > 2) ? 1 : 0;
         } else {
             s->mv[0][0][0] = s->mv[0][0][1] = 0;
             s->mv[1][0][0] = s->mv[1][0][1] = 0;
             f = 0;
         }
         v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
         for (k = 0; k < 4; k++) {
759001c5
             s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
             s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
             s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
             s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
cad16562
             v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
         }
         return;
     }
     if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
         vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0],   1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
         vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1],   1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
         return;
     }
     if (dir) { // backward
         vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
         if (n == 3 || mv1) {
50f97219
             vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0],   1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
cad16562
         }
     } else { // forward
         vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
         if (n == 3 || mv1) {
50f97219
             vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1],   1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
cad16562
         }
     }
 }
 
b761659b
 /** Get predicted DC value for I-frames only
  * prediction dir: left=0, top=1
  * @param s MpegEncContext
  * @param overlap flag indicating that overlap filtering is used
  * @param pq integer part of picture quantizer
  * @param[in] n block index in the current MB
  * @param dc_val_ptr Pointer to DC predictor
  * @param dir_ptr Prediction direction for use in AC prediction
  */
 static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
50f97219
                                 int16_t **dc_val_ptr, int *dir_ptr)
b761659b
 {
     int a, b, c, wrap, pred, scale;
     int16_t *dc_val;
     static const uint16_t dcpred[32] = {
50f97219
         -1, 1024,  512,  341,  256,  205,  171,  146,  128,
              114,  102,   93,   85,   79,   73,   68,   64,
               60,   57,   54,   51,   49,   47,   45,   43,
               41,   39,   38,   37,   35,   34,   33
b761659b
     };
 
     /* find prediction - wmv3_dc_scale always used here in fact */
50f97219
     if (n < 4) scale = s->y_dc_scale;
     else       scale = s->c_dc_scale;
b761659b
 
50f97219
     wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
b761659b
 
     /* B A
      * C X
      */
     c = dc_val[ - 1];
     b = dc_val[ - 1 - wrap];
     a = dc_val[ - wrap];
 
50f97219
     if (pq < 9 || !overlap) {
b761659b
         /* Set outer values */
50f97219
         if (s->first_slice_line && (n != 2 && n != 3))
             b = a = dcpred[scale];
         if (s->mb_x == 0 && (n != 1 && n != 3))
             b = c = dcpred[scale];
     } else {
b761659b
         /* Set outer values */
50f97219
         if (s->first_slice_line && (n != 2 && n != 3))
             b = a = 0;
         if (s->mb_x == 0 && (n != 1 && n != 3))
             b = c = 0;
b761659b
     }
 
     if (abs(a - b) <= abs(b - c)) {
50f97219
         pred     = c;
         *dir_ptr = 1; // left
b761659b
     } else {
50f97219
         pred     = a;
         *dir_ptr = 0; // top
b761659b
     }
 
     /* update predictor */
     *dc_val_ptr = &dc_val[0];
     return pred;
 }
 
 
 /** Get predicted DC value
  * prediction dir: left=0, top=1
  * @param s MpegEncContext
  * @param overlap flag indicating that overlap filtering is used
  * @param pq integer part of picture quantizer
  * @param[in] n block index in the current MB
  * @param a_avail flag indicating top block availability
  * @param c_avail flag indicating left block availability
  * @param dc_val_ptr Pointer to DC predictor
  * @param dir_ptr Prediction direction for use in AC prediction
  */
 static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
                               int a_avail, int c_avail,
                               int16_t **dc_val_ptr, int *dir_ptr)
 {
     int a, b, c, wrap, pred;
     int16_t *dc_val;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int q1, q2 = 0;
95b192de
     int dqscale_index;
b761659b
 
     wrap = s->block_wrap[n];
50f97219
     dc_val = s->dc_val[0] + s->block_index[n];
b761659b
 
     /* B A
      * C X
      */
     c = dc_val[ - 1];
     b = dc_val[ - 1 - wrap];
     a = dc_val[ - wrap];
     /* scale predictors if needed */
759001c5
     q1 = s->current_picture.qscale_table[mb_pos];
95b192de
     dqscale_index = s->y_dc_scale_table[q1] - 1;
     if (dqscale_index < 0)
         return 0;
50f97219
     if (c_avail && (n != 1 && n != 3)) {
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - 1];
50f97219
         if (q2 && q2 != q1)
95b192de
             c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
b761659b
     }
50f97219
     if (a_avail && (n != 2 && n != 3)) {
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
50f97219
         if (q2 && q2 != q1)
95b192de
             a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
b761659b
     }
50f97219
     if (a_avail && c_avail && (n != 3)) {
b761659b
         int off = mb_pos;
50f97219
         if (n != 1)
             off--;
         if (n != 2)
             off -= s->mb_stride;
759001c5
         q2 = s->current_picture.qscale_table[off];
50f97219
         if (q2 && q2 != q1)
95b192de
             b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
b761659b
     }
 
50f97219
     if (a_avail && c_avail) {
         if (abs(a - b) <= abs(b - c)) {
             pred     = c;
             *dir_ptr = 1; // left
b761659b
         } else {
50f97219
             pred     = a;
             *dir_ptr = 0; // top
         }
     } else if (a_avail) {
         pred     = a;
         *dir_ptr = 0; // top
     } else if (c_avail) {
         pred     = c;
         *dir_ptr = 1; // left
b761659b
     } else {
50f97219
         pred     = 0;
         *dir_ptr = 1; // left
b761659b
     }
 
     /* update predictor */
     *dc_val_ptr = &dc_val[0];
     return pred;
 }
 
 /** @} */ // Block group
 
 /**
21a19b79
  * @name VC1 Macroblock-level functions in Simple/Main Profiles
b761659b
  * @see 7.1.4, p91 and 8.1.1.7, p(1)04
  * @{
  */
 
50f97219
 static inline int vc1_coded_block_pred(MpegEncContext * s, int n,
                                        uint8_t **coded_block_ptr)
b761659b
 {
     int xy, wrap, pred, a, b, c;
 
50f97219
     xy   = s->block_index[n];
b761659b
     wrap = s->b8_stride;
 
     /* B C
      * A X
      */
     a = s->coded_block[xy - 1       ];
     b = s->coded_block[xy - 1 - wrap];
     c = s->coded_block[xy     - wrap];
 
     if (b == c) {
         pred = a;
     } else {
         pred = c;
     }
 
     /* store value */
     *coded_block_ptr = &s->coded_block[xy];
 
     return pred;
 }
 
 /**
  * Decode one AC coefficient
  * @param v The VC1 context
  * @param last Last coefficient
  * @param skip How much zero coefficients to skip
  * @param value Decoded AC coefficient value
  * @param codingset set of VLC to decode data
  * @see 8.1.3.4
  */
50f97219
 static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
                                 int *value, int codingset)
b761659b
 {
     GetBitContext *gb = &v->s.gb;
     int index, escape, run = 0, level = 0, lst = 0;
 
     index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
3c715383
     if (index != ff_vc1_ac_sizes[codingset] - 1) {
50f97219
         run   = vc1_index_decode_table[codingset][index][0];
b761659b
         level = vc1_index_decode_table[codingset][index][1];
50f97219
         lst   = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0;
         if (get_bits1(gb))
b761659b
             level = -level;
     } else {
         escape = decode210(gb);
         if (escape != 2) {
             index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
50f97219
             run   = vc1_index_decode_table[codingset][index][0];
b761659b
             level = vc1_index_decode_table[codingset][index][1];
50f97219
             lst   = index >= vc1_last_decode_table[codingset];
             if (escape == 0) {
                 if (lst)
b761659b
                     level += vc1_last_delta_level_table[codingset][run];
                 else
                     level += vc1_delta_level_table[codingset][run];
             } else {
50f97219
                 if (lst)
b761659b
                     run += vc1_last_delta_run_table[codingset][level] + 1;
                 else
                     run += vc1_delta_run_table[codingset][level] + 1;
             }
50f97219
             if (get_bits1(gb))
b761659b
                 level = -level;
         } else {
             int sign;
             lst = get_bits1(gb);
50f97219
             if (v->s.esc3_level_length == 0) {
                 if (v->pq < 8 || v->dquantfrm) { // table 59
b761659b
                     v->s.esc3_level_length = get_bits(gb, 3);
50f97219
                     if (!v->s.esc3_level_length)
b761659b
                         v->s.esc3_level_length = get_bits(gb, 2) + 8;
50f97219
                 } else { // table 60
b761659b
                     v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;
                 }
                 v->s.esc3_run_length = 3 + get_bits(gb, 2);
             }
50f97219
             run   = get_bits(gb, v->s.esc3_run_length);
             sign  = get_bits1(gb);
b761659b
             level = get_bits(gb, v->s.esc3_level_length);
50f97219
             if (sign)
b761659b
                 level = -level;
         }
     }
 
50f97219
     *last  = lst;
     *skip  = run;
b761659b
     *value = level;
 }
 
 /** Decode intra block in intra frames - should be faster than decode_intra_block
  * @param v VC1Context
  * @param block block to decode
  * @param[in] n subblock index
  * @param coded are AC coeffs present or not
  * @param codingset set of VLC to decode data
  */
88bd7fdc
 static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
50f97219
                               int coded, int codingset)
b761659b
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
     int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int i;
     int16_t *dc_val;
     int16_t *ac_val, *ac_val2;
     int dcdiff;
 
     /* Get DC differential */
     if (n < 4) {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     } else {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     }
50f97219
     if (dcdiff < 0) {
b761659b
         av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
         return -1;
     }
50f97219
     if (dcdiff) {
         if (dcdiff == 119 /* ESC index value */) {
b761659b
             /* TODO: Optimize */
50f97219
             if (v->pq == 1)      dcdiff = get_bits(gb, 10);
b761659b
             else if (v->pq == 2) dcdiff = get_bits(gb, 9);
50f97219
             else                 dcdiff = get_bits(gb, 8);
         } else {
b761659b
             if (v->pq == 1)
50f97219
                 dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
b761659b
             else if (v->pq == 2)
50f97219
                 dcdiff = (dcdiff << 1) + get_bits1(gb)   - 1;
b761659b
         }
         if (get_bits1(gb))
             dcdiff = -dcdiff;
     }
 
     /* Prediction */
     dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
     if (n < 4) {
         block[0] = dcdiff * s->y_dc_scale;
     } else {
         block[0] = dcdiff * s->c_dc_scale;
     }
     /* Skip ? */
     if (!coded) {
         goto not_coded;
     }
 
50f97219
     // AC Decoding
b761659b
     i = 1;
 
     {
         int last = 0, skip, value;
0724a674
         const uint8_t *zz_table;
b761659b
         int scale;
         int k;
 
         scale = v->pq * 2 + v->halfpq;
 
50f97219
         if (v->s.ac_pred) {
             if (!dc_pred_dir)
1da6ea39
                 zz_table = v->zz_8x8[2];
b761659b
             else
1da6ea39
                 zz_table = v->zz_8x8[3];
b761659b
         } else
1da6ea39
             zz_table = v->zz_8x8[1];
b761659b
 
50f97219
         ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;
b761659b
         ac_val2 = ac_val;
50f97219
         if (dc_pred_dir) // left
b761659b
             ac_val -= 16;
50f97219
         else // top
b761659b
             ac_val -= 16 * s->block_wrap[n];
 
         while (!last) {
             vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
             i += skip;
50f97219
             if (i > 63)
b761659b
                 break;
             block[zz_table[i++]] = value;
         }
 
         /* apply AC prediction if needed */
50f97219
         if (s->ac_pred) {
             if (dc_pred_dir) { // left
                 for (k = 1; k < 8; k++)
58bb6b7d
                     block[k << v->left_blk_sh] += ac_val[k];
50f97219
             } else { // top
                 for (k = 1; k < 8; k++)
58bb6b7d
                     block[k << v->top_blk_sh] += ac_val[k + 8];
b761659b
             }
         }
         /* save AC coeffs for further prediction */
50f97219
         for (k = 1; k < 8; k++) {
58bb6b7d
             ac_val2[k]     = block[k << v->left_blk_sh];
             ac_val2[k + 8] = block[k << v->top_blk_sh];
b761659b
         }
 
         /* scale AC coeffs */
50f97219
         for (k = 1; k < 64; k++)
             if (block[k]) {
b761659b
                 block[k] *= scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[k] += (block[k] < 0) ? -v->pq : v->pq;
             }
 
50f97219
         if (s->ac_pred) i = 63;
b761659b
     }
 
 not_coded:
50f97219
     if (!coded) {
b761659b
         int k, scale;
50f97219
         ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;
b761659b
         ac_val2 = ac_val;
 
         i = 0;
         scale = v->pq * 2 + v->halfpq;
         memset(ac_val2, 0, 16 * 2);
50f97219
         if (dc_pred_dir) { // left
b761659b
             ac_val -= 16;
50f97219
             if (s->ac_pred)
b761659b
                 memcpy(ac_val2, ac_val, 8 * 2);
50f97219
         } else { // top
b761659b
             ac_val -= 16 * s->block_wrap[n];
50f97219
             if (s->ac_pred)
b761659b
                 memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
         }
 
         /* apply AC prediction if needed */
50f97219
         if (s->ac_pred) {
             if (dc_pred_dir) { //left
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->left_blk_sh] = ac_val[k] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->left_blk_sh])
58bb6b7d
                         block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -v->pq : v->pq;
b761659b
                 }
50f97219
             } else { // top
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->top_blk_sh] = ac_val[k + 8] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->top_blk_sh])
58bb6b7d
                         block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -v->pq : v->pq;
b761659b
                 }
             }
             i = 63;
         }
     }
     s->block_last_index[n] = i;
 
     return 0;
 }
 
 /** Decode intra block in intra frames - should be faster than decode_intra_block
  * @param v VC1Context
  * @param block block to decode
  * @param[in] n subblock number
  * @param coded are AC coeffs present or not
  * @param codingset set of VLC to decode data
  * @param mquant quantizer value for this macroblock
  */
88bd7fdc
 static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
50f97219
                                   int coded, int codingset, int mquant)
b761659b
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
     int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int i;
63c61f0b
     int16_t *dc_val = NULL;
b761659b
     int16_t *ac_val, *ac_val2;
     int dcdiff;
     int a_avail = v->a_avail, c_avail = v->c_avail;
     int use_pred = s->ac_pred;
     int scale;
     int q1, q2 = 0;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 
     /* Get DC differential */
     if (n < 4) {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     } else {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     }
50f97219
     if (dcdiff < 0) {
b761659b
         av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
         return -1;
     }
50f97219
     if (dcdiff) {
         if (dcdiff == 119 /* ESC index value */) {
b761659b
             /* TODO: Optimize */
50f97219
             if (mquant == 1)      dcdiff = get_bits(gb, 10);
b761659b
             else if (mquant == 2) dcdiff = get_bits(gb, 9);
50f97219
             else                  dcdiff = get_bits(gb, 8);
         } else {
b761659b
             if (mquant == 1)
50f97219
                 dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
b761659b
             else if (mquant == 2)
50f97219
                 dcdiff = (dcdiff << 1) + get_bits1(gb)   - 1;
b761659b
         }
         if (get_bits1(gb))
             dcdiff = -dcdiff;
     }
 
     /* Prediction */
     dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, v->a_avail, v->c_avail, &dc_val, &dc_pred_dir);
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
     if (n < 4) {
         block[0] = dcdiff * s->y_dc_scale;
     } else {
         block[0] = dcdiff * s->c_dc_scale;
     }
 
     //AC Decoding
     i = 1;
 
     /* check if AC is needed at all */
50f97219
     if (!a_avail && !c_avail)
         use_pred = 0;
     ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;
b761659b
     ac_val2 = ac_val;
 
     scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0);
 
50f97219
     if (dc_pred_dir) // left
b761659b
         ac_val -= 16;
50f97219
     else // top
b761659b
         ac_val -= 16 * s->block_wrap[n];
 
759001c5
     q1 = s->current_picture.qscale_table[mb_pos];
50f97219
     if ( dc_pred_dir && c_avail && mb_pos)
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - 1];
50f97219
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
50f97219
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
         q2 = q1;
     if (n == 3)
         q2 = q1;
 
     if (coded) {
b761659b
         int last = 0, skip, value;
0724a674
         const uint8_t *zz_table;
b761659b
         int k;
 
50f97219
         if (v->s.ac_pred) {
1f948745
             if (!use_pred && v->fcm == ILACE_FRAME) {
cad16562
                 zz_table = v->zzi_8x8;
             } else {
50f97219
                 if (!dc_pred_dir) // top
cad16562
                     zz_table = v->zz_8x8[2];
50f97219
                 else // left
cad16562
                     zz_table = v->zz_8x8[3];
             }
         } else {
1f948745
             if (v->fcm != ILACE_FRAME)
cad16562
                 zz_table = v->zz_8x8[1];
b761659b
             else
cad16562
                 zz_table = v->zzi_8x8;
         }
b761659b
 
         while (!last) {
             vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
             i += skip;
50f97219
             if (i > 63)
b761659b
                 break;
             block[zz_table[i++]] = value;
         }
 
         /* apply AC prediction if needed */
50f97219
         if (use_pred) {
b761659b
             /* scale predictors if needed*/
50f97219
             if (q2 && q1 != q2) {
b761659b
                 q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                 q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
 
95b192de
                 if (q1 < 1)
                     return AVERROR_INVALIDDATA;
50f97219
                 if (dc_pred_dir) { // left
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
50f97219
                 } else { // top
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
b761659b
                 }
             } else {
50f97219
                 if (dc_pred_dir) { //left
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->left_blk_sh] += ac_val[k];
b761659b
                 } else { //top
50f97219
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->top_blk_sh] += ac_val[k + 8];
b761659b
                 }
             }
         }
         /* save AC coeffs for further prediction */
50f97219
         for (k = 1; k < 8; k++) {
58bb6b7d
             ac_val2[k    ] = block[k << v->left_blk_sh];
             ac_val2[k + 8] = block[k << v->top_blk_sh];
b761659b
         }
 
         /* scale AC coeffs */
50f97219
         for (k = 1; k < 64; k++)
             if (block[k]) {
b761659b
                 block[k] *= scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[k] += (block[k] < 0) ? -mquant : mquant;
             }
 
50f97219
         if (use_pred) i = 63;
b761659b
     } else { // no AC coeffs
         int k;
 
         memset(ac_val2, 0, 16 * 2);
50f97219
         if (dc_pred_dir) { // left
             if (use_pred) {
b761659b
                 memcpy(ac_val2, ac_val, 8 * 2);
50f97219
                 if (q2 && q1 != q2) {
b761659b
                     q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                     q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
95b192de
                     if (q1 < 1)
                         return AVERROR_INVALIDDATA;
50f97219
                     for (k = 1; k < 8; k++)
b761659b
                         ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                 }
             }
50f97219
         } else { // top
             if (use_pred) {
b761659b
                 memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
50f97219
                 if (q2 && q1 != q2) {
b761659b
                     q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                     q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
95b192de
                     if (q1 < 1)
                         return AVERROR_INVALIDDATA;
50f97219
                     for (k = 1; k < 8; k++)
b761659b
                         ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                 }
             }
         }
 
         /* apply AC prediction if needed */
50f97219
         if (use_pred) {
             if (dc_pred_dir) { // left
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->left_blk_sh] = ac_val2[k] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->left_blk_sh])
58bb6b7d
                         block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
b761659b
                 }
50f97219
             } else { // top
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->top_blk_sh])
58bb6b7d
                         block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
b761659b
                 }
             }
             i = 63;
         }
     }
     s->block_last_index[n] = i;
 
     return 0;
 }
 
 /** Decode intra block in inter frames - more generic version than vc1_decode_i_block
  * @param v VC1Context
  * @param block block to decode
  * @param[in] n subblock index
  * @param coded are AC coeffs present or not
  * @param mquant block quantizer
  * @param codingset set of VLC to decode data
  */
88bd7fdc
 static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
50f97219
                                   int coded, int mquant, int codingset)
b761659b
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
     int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int i;
63c61f0b
     int16_t *dc_val = NULL;
b761659b
     int16_t *ac_val, *ac_val2;
     int dcdiff;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int a_avail = v->a_avail, c_avail = v->c_avail;
     int use_pred = s->ac_pred;
     int scale;
     int q1, q2 = 0;
 
010f98f9
     s->dsp.clear_block(block);
 
b761659b
     /* XXX: Guard against dumb values of mquant */
50f97219
     mquant = (mquant < 1) ? 0 : ((mquant > 31) ? 31 : mquant);
b761659b
 
     /* Set DC scale - y and c use the same */
     s->y_dc_scale = s->y_dc_scale_table[mquant];
     s->c_dc_scale = s->c_dc_scale_table[mquant];
 
     /* Get DC differential */
     if (n < 4) {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     } else {
         dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
     }
50f97219
     if (dcdiff < 0) {
b761659b
         av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
         return -1;
     }
50f97219
     if (dcdiff) {
         if (dcdiff == 119 /* ESC index value */) {
b761659b
             /* TODO: Optimize */
50f97219
             if (mquant == 1)      dcdiff = get_bits(gb, 10);
b761659b
             else if (mquant == 2) dcdiff = get_bits(gb, 9);
50f97219
             else                  dcdiff = get_bits(gb, 8);
         } else {
b761659b
             if (mquant == 1)
50f97219
                 dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
b761659b
             else if (mquant == 2)
50f97219
                 dcdiff = (dcdiff << 1) + get_bits1(gb)   - 1;
b761659b
         }
         if (get_bits1(gb))
             dcdiff = -dcdiff;
     }
 
     /* Prediction */
     dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
     *dc_val = dcdiff;
 
     /* Store the quantized DC coeff, used for prediction */
 
     if (n < 4) {
         block[0] = dcdiff * s->y_dc_scale;
     } else {
         block[0] = dcdiff * s->c_dc_scale;
     }
 
     //AC Decoding
     i = 1;
 
     /* check if AC is needed at all and adjust direction if needed */
50f97219
     if (!a_avail) dc_pred_dir = 1;
     if (!c_avail) dc_pred_dir = 0;
     if (!a_avail && !c_avail) use_pred = 0;
b761659b
     ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
     ac_val2 = ac_val;
 
     scale = mquant * 2 + v->halfpq;
 
50f97219
     if (dc_pred_dir) //left
b761659b
         ac_val -= 16;
     else //top
         ac_val -= 16 * s->block_wrap[n];
 
759001c5
     q1 = s->current_picture.qscale_table[mb_pos];
50f97219
     if (dc_pred_dir && c_avail && mb_pos)
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - 1];
50f97219
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
759001c5
         q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
50f97219
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
         q2 = q1;
     if (n == 3) q2 = q1;
b761659b
 
50f97219
     if (coded) {
b761659b
         int last = 0, skip, value;
         int k;
 
         while (!last) {
             vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
             i += skip;
50f97219
             if (i > 63)
b761659b
                 break;
1f948745
             if (v->fcm == PROGRESSIVE)
cad16562
                 block[v->zz_8x8[0][i++]] = value;
             else {
1f948745
                 if (use_pred && (v->fcm == ILACE_FRAME)) {
50f97219
                     if (!dc_pred_dir) // top
cad16562
                         block[v->zz_8x8[2][i++]] = value;
50f97219
                     else // left
cad16562
                         block[v->zz_8x8[3][i++]] = value;
                 } else {
                     block[v->zzi_8x8[i++]] = value;
                 }
             }
b761659b
         }
 
         /* apply AC prediction if needed */
50f97219
         if (use_pred) {
b761659b
             /* scale predictors if needed*/
50f97219
             if (q2 && q1 != q2) {
b761659b
                 q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                 q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
 
95b192de
                 if (q1 < 1)
                     return AVERROR_INVALIDDATA;
50f97219
                 if (dc_pred_dir) { // left
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
b761659b
                 } else { //top
50f97219
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
b761659b
                 }
             } else {
50f97219
                 if (dc_pred_dir) { // left
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->left_blk_sh] += ac_val[k];
50f97219
                 } else { // top
                     for (k = 1; k < 8; k++)
58bb6b7d
                         block[k << v->top_blk_sh] += ac_val[k + 8];
b761659b
                 }
             }
         }
         /* save AC coeffs for further prediction */
50f97219
         for (k = 1; k < 8; k++) {
58bb6b7d
             ac_val2[k    ] = block[k << v->left_blk_sh];
             ac_val2[k + 8] = block[k << v->top_blk_sh];
b761659b
         }
 
         /* scale AC coeffs */
50f97219
         for (k = 1; k < 64; k++)
             if (block[k]) {
b761659b
                 block[k] *= scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[k] += (block[k] < 0) ? -mquant : mquant;
             }
 
50f97219
         if (use_pred) i = 63;
b761659b
     } else { // no AC coeffs
         int k;
 
         memset(ac_val2, 0, 16 * 2);
50f97219
         if (dc_pred_dir) { // left
             if (use_pred) {
b761659b
                 memcpy(ac_val2, ac_val, 8 * 2);
50f97219
                 if (q2 && q1 != q2) {
b761659b
                     q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                     q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
95b192de
                     if (q1 < 1)
                         return AVERROR_INVALIDDATA;
50f97219
                     for (k = 1; k < 8; k++)
b761659b
                         ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                 }
             }
50f97219
         } else { // top
             if (use_pred) {
b761659b
                 memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
50f97219
                 if (q2 && q1 != q2) {
b761659b
                     q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                     q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
95b192de
                     if (q1 < 1)
                         return AVERROR_INVALIDDATA;
50f97219
                     for (k = 1; k < 8; k++)
b761659b
                         ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                 }
             }
         }
 
         /* apply AC prediction if needed */
50f97219
         if (use_pred) {
             if (dc_pred_dir) { // left
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->left_blk_sh] = ac_val2[k] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->left_blk_sh])
58bb6b7d
                         block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
b761659b
                 }
50f97219
             } else { // top
                 for (k = 1; k < 8; k++) {
58bb6b7d
                     block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
50f97219
                     if (!v->pquantizer && block[k << v->top_blk_sh])
58bb6b7d
                         block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
b761659b
                 }
             }
             i = 63;
         }
     }
     s->block_last_index[n] = i;
 
     return 0;
 }
 
 /** Decode P block
  */
88bd7fdc
 static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
50f97219
                               int mquant, int ttmb, int first_block,
                               uint8_t *dst, int linesize, int skip_block,
                               int *ttmb_out)
b761659b
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
     int i, j;
     int subblkpat = 0;
     int scale, off, idx, last, skip, value;
     int ttblk = ttmb & 7;
     int pat = 0;
 
010f98f9
     s->dsp.clear_block(block);
 
50f97219
     if (ttmb == -1) {
b761659b
         ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
     }
50f97219
     if (ttblk == TT_4X4) {
b761659b
         subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
     }
50f97219
     if ((ttblk != TT_8X8 && ttblk != TT_4X4)
42ff9d7a
         && ((v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))
             || (!v->res_rtm_flag && !first_block))) {
b761659b
         subblkpat = decode012(gb);
50f97219
         if (subblkpat)
             subblkpat ^= 3; // swap decoded pattern bits
         if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM)
             ttblk = TT_8X4;
         if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT)
             ttblk = TT_4X8;
b761659b
     }
     scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0);
 
     // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
50f97219
     if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
b761659b
         subblkpat = 2 - (ttblk == TT_8X4_TOP);
50f97219
         ttblk     = TT_8X4;
b761659b
     }
50f97219
     if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
b761659b
         subblkpat = 2 - (ttblk == TT_4X8_LEFT);
50f97219
         ttblk     = TT_4X8;
b761659b
     }
50f97219
     switch (ttblk) {
b761659b
     case TT_8X8:
50f97219
         pat  = 0xF;
         i    = 0;
b761659b
         last = 0;
         while (!last) {
             vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
             i += skip;
50f97219
             if (i > 63)
b761659b
                 break;
801393bc
             if (!v->fcm)
cad16562
                 idx = v->zz_8x8[0][i++];
             else
                 idx = v->zzi_8x8[i++];
b761659b
             block[idx] = value * scale;
50f97219
             if (!v->pquantizer)
b761659b
                 block[idx] += (block[idx] < 0) ? -mquant : mquant;
         }
50f97219
         if (!skip_block) {
             if (i == 1)
12802ec0
                 v->vc1dsp.vc1_inv_trans_8x8_dc(dst, linesize, block);
50f97219
             else {
18b6a69c
                 v->vc1dsp.vc1_inv_trans_8x8(block);
                 s->dsp.add_pixels_clamped(block, dst, linesize);
4f717c69
             }
b761659b
         }
         break;
     case TT_4X4:
         pat = ~subblkpat & 0xF;
50f97219
         for (j = 0; j < 4; j++) {
b761659b
             last = subblkpat & (1 << (3 - j));
50f97219
             i    = 0;
             off  = (j & 1) * 4 + (j & 2) * 16;
b761659b
             while (!last) {
                 vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                 i += skip;
50f97219
                 if (i > 15)
b761659b
                     break;
801393bc
                 if (!v->fcm)
cad16562
                     idx = ff_vc1_simple_progressive_4x4_zz[i++];
                 else
                     idx = ff_vc1_adv_interlaced_4x4_zz[i++];
b761659b
                 block[idx + off] = value * scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
             }
50f97219
             if (!(subblkpat & (1 << (3 - j))) && !skip_block) {
                 if (i == 1)
                     v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
4f717c69
                 else
50f97219
                     v->vc1dsp.vc1_inv_trans_4x4(dst + (j & 1) * 4 + (j & 2) *  2 * linesize, linesize, block + off);
b761659b
             }
         }
         break;
     case TT_8X4:
50f97219
         pat = ~((subblkpat & 2) * 6 + (subblkpat & 1) * 3) & 0xF;
         for (j = 0; j < 2; j++) {
b761659b
             last = subblkpat & (1 << (1 - j));
50f97219
             i    = 0;
             off  = j * 32;
b761659b
             while (!last) {
                 vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                 i += skip;
50f97219
                 if (i > 31)
b761659b
                     break;
801393bc
                 if (!v->fcm)
cad16562
                     idx = v->zz_8x4[i++] + off;
                 else
                     idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
b761659b
                 block[idx] = value * scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[idx] += (block[idx] < 0) ? -mquant : mquant;
             }
50f97219
             if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
                 if (i == 1)
                     v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j * 4 * linesize, linesize, block + off);
4f717c69
                 else
50f97219
                     v->vc1dsp.vc1_inv_trans_8x4(dst + j * 4 * linesize, linesize, block + off);
b761659b
             }
         }
         break;
     case TT_4X8:
50f97219
         pat = ~(subblkpat * 5) & 0xF;
         for (j = 0; j < 2; j++) {
b761659b
             last = subblkpat & (1 << (1 - j));
50f97219
             i    = 0;
             off  = j * 4;
b761659b
             while (!last) {
                 vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                 i += skip;
50f97219
                 if (i > 31)
b761659b
                     break;
801393bc
                 if (!v->fcm)
cad16562
                     idx = v->zz_4x8[i++] + off;
                 else
                     idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
b761659b
                 block[idx] = value * scale;
50f97219
                 if (!v->pquantizer)
b761659b
                     block[idx] += (block[idx] < 0) ? -mquant : mquant;
             }
50f97219
             if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
                 if (i == 1)
                     v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j * 4, linesize, block + off);
4f717c69
                 else
12802ec0
                     v->vc1dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);
b761659b
             }
         }
         break;
     }
c47d3835
     if (ttmb_out)
         *ttmb_out |= ttblk << (n * 4);
b761659b
     return pat;
 }
 
 /** @} */ // Macroblock group
 
 static const int size_table  [6] = { 0, 2, 3, 4,  5,  8 };
 static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 };
 
c47d3835
 static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)
 {
50f97219
     MpegEncContext *s  = &v->s;
c47d3835
     int mb_cbp         = v->cbp[s->mb_x - s->mb_stride],
         block_cbp      = mb_cbp      >> (block_num * 4), bottom_cbp,
         mb_is_intra    = v->is_intra[s->mb_x - s->mb_stride],
         block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;
50f97219
     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
c47d3835
     uint8_t *dst;
 
50f97219
     if (block_num > 3) {
c47d3835
         dst      = s->dest[block_num - 3];
     } else {
         dst      = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;
     }
1cf82cab
     if (s->mb_y != s->end_mb_y || block_num < 2) {
c47d3835
         int16_t (*mv)[2];
         int mv_stride;
 
50f97219
         if (block_num > 3) {
c47d3835
             bottom_cbp      = v->cbp[s->mb_x]      >> (block_num * 4);
             bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);
             mv              = &v->luma_mv[s->mb_x - s->mb_stride];
             mv_stride       = s->mb_stride;
         } else {
50f97219
             bottom_cbp      = (block_num < 2) ? (mb_cbp               >> ((block_num + 2) * 4))
                                               : (v->cbp[s->mb_x]      >> ((block_num - 2) * 4));
             bottom_is_intra = (block_num < 2) ? (mb_is_intra          >> ((block_num + 2) * 4))
                                               : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
c47d3835
             mv_stride       = s->b8_stride;
759001c5
             mv              = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
c47d3835
         }
 
         if (bottom_is_intra & 1 || block_is_intra & 1 ||
             mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
             v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
         } else {
             idx = ((bottom_cbp >> 2) | block_cbp) & 3;
50f97219
             if (idx == 3) {
c47d3835
                 v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
             } else if (idx) {
                 if (idx == 1)
                     v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
                 else
                     v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);
             }
         }
     }
 
     dst -= 4 * linesize;
50f97219
     ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
c47d3835
     if (ttblk == TT_4X4 || ttblk == TT_8X4) {
         idx = (block_cbp | (block_cbp >> 2)) & 3;
         if (idx == 3) {
             v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
         } else if (idx) {
             if (idx == 1)
                 v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
             else
                 v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);
         }
     }
 }
 
 static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num)
 {
50f97219
     MpegEncContext *s  = &v->s;
c47d3835
     int mb_cbp         = v->cbp[s->mb_x - 1 - s->mb_stride],
         block_cbp      = mb_cbp      >> (block_num * 4), right_cbp,
         mb_is_intra    = v->is_intra[s->mb_x - 1 - s->mb_stride],
         block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra;
50f97219
     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
c47d3835
     uint8_t *dst;
 
     if (block_num > 3) {
         dst = s->dest[block_num - 3] - 8 * linesize;
     } else {
         dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) * linesize - 8;
     }
 
     if (s->mb_x != s->mb_width || !(block_num & 5)) {
         int16_t (*mv)[2];
 
50f97219
         if (block_num > 3) {
c47d3835
             right_cbp      = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
             right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num * 4);
             mv             = &v->luma_mv[s->mb_x - s->mb_stride - 1];
50f97219
         } else {
             right_cbp      = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride]      >> ((block_num - 1) * 4))
                                              : (mb_cbp                              >> ((block_num + 1) * 4));
             right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
                                              : (mb_is_intra                         >> ((block_num + 1) * 4));
759001c5
             mv             = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
c47d3835
         }
         if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
         } else {
             idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
             if (idx == 5) {
                 v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
             } else if (idx) {
                 if (idx == 1)
50f97219
                     v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize, v->pq);
c47d3835
                 else
50f97219
                     v->vc1dsp.vc1_h_loop_filter4(dst,                linesize, v->pq);
c47d3835
             }
         }
     }
 
     dst -= 4;
     ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
     if (ttblk == TT_4X4 || ttblk == TT_4X8) {
         idx = (block_cbp | (block_cbp >> 1)) & 5;
         if (idx == 5) {
             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
         } else if (idx) {
             if (idx == 1)
50f97219
                 v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize, v->pq);
c47d3835
             else
50f97219
                 v->vc1dsp.vc1_h_loop_filter4(dst,                linesize, v->pq);
c47d3835
         }
     }
 }
 
 static void vc1_apply_p_loop_filter(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     int i;
 
     for (i = 0; i < 6; i++) {
         vc1_apply_p_v_loop_filter(v, i);
     }
 
da9cea77
     /* V always precedes H, therefore we run H one MB before V;
c47d3835
      * at the end of a row, we catch up to complete the row */
     if (s->mb_x) {
         for (i = 0; i < 6; i++) {
             vc1_apply_p_h_loop_filter(v, i);
         }
         if (s->mb_x == s->mb_width - 1) {
             s->mb_x++;
             ff_update_block_index(s);
             for (i = 0; i < 6; i++) {
                 vc1_apply_p_h_loop_filter(v, i);
             }
         }
     }
 }
 
cad16562
 /** Decode one P-frame MB
b761659b
  */
 static int vc1_decode_p_mb(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
18b6a69c
     int i, j;
b761659b
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
 
     int mb_has_coeffs = 1; /* last_flag */
     int dmv_x, dmv_y; /* Differential MV components */
     int index, index1; /* LUT indexes */
     int val, sign; /* temp values */
     int first_block = 1;
     int dst_idx, off;
     int skipped, fourmv;
c47d3835
     int block_cbp = 0, pat, block_tt = 0, block_intra = 0;
b761659b
 
da9cea77
     mquant = v->pq; /* lossy initialization */
b761659b
 
     if (v->mv_type_is_raw)
         fourmv = get_bits1(gb);
     else
         fourmv = v->mv_type_mb_plane[mb_pos];
     if (v->skip_is_raw)
         skipped = get_bits1(gb);
     else
         skipped = v->s.mbskip_table[mb_pos];
 
50f97219
     if (!fourmv) { /* 1MV mode */
         if (!skipped) {
b761659b
             GET_MVDATA(dmv_x, dmv_y);
 
             if (s->mb_intra) {
759001c5
                 s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
                 s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
b761659b
             }
759001c5
             s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
cad16562
             vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
b761659b
 
             /* FIXME Set DC val for inter block ? */
50f97219
             if (s->mb_intra && !mb_has_coeffs) {
b761659b
                 GET_MQUANT();
                 s->ac_pred = get_bits1(gb);
50f97219
                 cbp        = 0;
             } else if (mb_has_coeffs) {
cad16562
                 if (s->mb_intra)
                     s->ac_pred = get_bits1(gb);
b761659b
                 cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
                 GET_MQUANT();
50f97219
             } else {
b761659b
                 mquant = v->pq;
50f97219
                 cbp    = 0;
b761659b
             }
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
b761659b
 
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
                                 VC1_TTMB_VLC_BITS, 2);
50f97219
             if (!s->mb_intra) vc1_mc_1mv(v, 0);
b761659b
             dst_idx = 0;
50f97219
             for (i = 0; i < 6; i++) {
b761659b
                 s->dc_val[0][s->block_index[i]] = 0;
                 dst_idx += i >> 2;
                 val = ((cbp >> (5 - i)) & 1);
                 off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
                 v->mb_type[0][s->block_index[i]] = s->mb_intra;
50f97219
                 if (s->mb_intra) {
b761659b
                     /* check if prediction blocks A and C are available */
                     v->a_avail = v->c_avail = 0;
50f97219
                     if (i == 2 || i == 3 || !s->first_slice_line)
b761659b
                         v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
                     if (i == 1 || i == 3 || s->mb_x)
b761659b
                         v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
                     vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                            (i & 4) ? v->codingset2 : v->codingset);
                     if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
                         continue;
18b6a69c
                     v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
50f97219
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             s->block[i][j] <<= 1;
18b6a69c
                     s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
50f97219
                     if (v->pq >= 9 && v->overlap) {
                         if (v->c_avail)
12802ec0
                             v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
50f97219
                         if (v->a_avail)
12802ec0
                             v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
b761659b
                     }
50f97219
                     block_cbp   |= 0xF << (i << 2);
c47d3835
                     block_intra |= 1 << i;
50f97219
                 } else if (val) {
                     pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block,
                                              s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize,
                                              (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
b761659b
                     block_cbp |= pat << (i << 2);
50f97219
                     if (!v->ttmbf && ttmb < 8)
                         ttmb = -1;
b761659b
                     first_block = 0;
                 }
             }
50f97219
         } else { // skipped
b761659b
             s->mb_intra = 0;
50f97219
             for (i = 0; i < 6; i++) {
b761659b
                 v->mb_type[0][s->block_index[i]] = 0;
50f97219
                 s->dc_val[0][s->block_index[i]]  = 0;
b761659b
             }
759001c5
             s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
             s->current_picture.qscale_table[mb_pos] = 0;
cad16562
             vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
b761659b
             vc1_mc_1mv(v, 0);
         }
50f97219
     } else { // 4MV mode
         if (!skipped /* unskipped MB */) {
b761659b
             int intra_count = 0, coded_inter = 0;
             int is_intra[6], is_coded[6];
             /* Get CBPCY */
             cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
50f97219
             for (i = 0; i < 6; i++) {
b761659b
                 val = ((cbp >> (5 - i)) & 1);
                 s->dc_val[0][s->block_index[i]] = 0;
50f97219
                 s->mb_intra                     = 0;
                 if (i < 4) {
b761659b
                     dmv_x = dmv_y = 0;
50f97219
                     s->mb_intra   = 0;
b761659b
                     mb_has_coeffs = 0;
50f97219
                     if (val) {
b761659b
                         GET_MVDATA(dmv_x, dmv_y);
                     }
cad16562
                     vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
50f97219
                     if (!s->mb_intra)
db8403d0
                         vc1_mc_4mv_luma(v, i, 0, 0);
b761659b
                     intra_count += s->mb_intra;
50f97219
                     is_intra[i]  = s->mb_intra;
                     is_coded[i]  = mb_has_coeffs;
b761659b
                 }
50f97219
                 if (i & 4) {
b761659b
                     is_intra[i] = (intra_count >= 3);
                     is_coded[i] = val;
                 }
50f97219
                 if (i == 4)
                     vc1_mc_4mv_chroma(v, 0);
b761659b
                 v->mb_type[0][s->block_index[i]] = is_intra[i];
50f97219
                 if (!coded_inter)
                     coded_inter = !is_intra[i] & is_coded[i];
b761659b
             }
             // if there are no coded blocks then don't do anything more
             dst_idx = 0;
50f97219
             if (!intra_count && !coded_inter)
c47d3835
                 goto end;
b761659b
             GET_MQUANT();
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
b761659b
             /* test if block is intra and has pred */
             {
                 int intrapred = 0;
50f97219
                 for (i = 0; i < 6; i++)
                     if (is_intra[i]) {
                         if (((!s->first_slice_line || (i == 2 || i == 3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
                             || ((s->mb_x || (i == 1 || i == 3)) && v->mb_type[0][s->block_index[i] - 1])) {
b761659b
                             intrapred = 1;
                             break;
                         }
                     }
50f97219
                 if (intrapred)
                     s->ac_pred = get_bits1(gb);
                 else
                     s->ac_pred = 0;
b761659b
             }
             if (!v->ttmbf && coded_inter)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
50f97219
             for (i = 0; i < 6; i++) {
                 dst_idx    += i >> 2;
                 off         = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
b761659b
                 s->mb_intra = is_intra[i];
                 if (is_intra[i]) {
                     /* check if prediction blocks A and C are available */
                     v->a_avail = v->c_avail = 0;
50f97219
                     if (i == 2 || i == 3 || !s->first_slice_line)
b761659b
                         v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
                     if (i == 1 || i == 3 || s->mb_x)
b761659b
                         v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
                     vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant,
                                            (i & 4) ? v->codingset2 : v->codingset);
                     if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
                         continue;
18b6a69c
                     v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
50f97219
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             s->block[i][j] <<= 1;
                     s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off,
                                                      (i & 4) ? s->uvlinesize : s->linesize);
                     if (v->pq >= 9 && v->overlap) {
                         if (v->c_avail)
12802ec0
                             v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
50f97219
                         if (v->a_avail)
12802ec0
                             v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
b761659b
                     }
50f97219
                     block_cbp   |= 0xF << (i << 2);
c47d3835
                     block_intra |= 1 << i;
50f97219
                 } else if (is_coded[i]) {
                     pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                              first_block, s->dest[dst_idx] + off,
                                              (i & 4) ? s->uvlinesize : s->linesize,
                                              (i & 4) && (s->flags & CODEC_FLAG_GRAY),
                                              &block_tt);
b761659b
                     block_cbp |= pat << (i << 2);
50f97219
                     if (!v->ttmbf && ttmb < 8)
                         ttmb = -1;
b761659b
                     first_block = 0;
                 }
             }
50f97219
         } else { // skipped MB
             s->mb_intra                               = 0;
759001c5
             s->current_picture.qscale_table[mb_pos] = 0;
50f97219
             for (i = 0; i < 6; i++) {
b761659b
                 v->mb_type[0][s->block_index[i]] = 0;
50f97219
                 s->dc_val[0][s->block_index[i]]  = 0;
b761659b
             }
50f97219
             for (i = 0; i < 4; i++) {
cad16562
                 vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
db8403d0
                 vc1_mc_4mv_luma(v, i, 0, 0);
b761659b
             }
cad16562
             vc1_mc_4mv_chroma(v, 0);
759001c5
             s->current_picture.qscale_table[mb_pos] = 0;
b761659b
         }
     }
c47d3835
 end:
50f97219
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
c47d3835
     v->is_intra[s->mb_x] = block_intra;
b761659b
 
c47d3835
     return 0;
b761659b
 }
 
cad16562
 /* Decode one macroblock in an interlaced frame p picture */
 
 static int vc1_decode_p_mb_intfr(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
     int i;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp = 0; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
 
     int mb_has_coeffs = 1; /* last_flag */
     int dmv_x, dmv_y; /* Differential MV components */
     int val; /* temp value */
     int first_block = 1;
     int dst_idx, off;
     int skipped, fourmv = 0, twomv = 0;
     int block_cbp = 0, pat, block_tt = 0;
     int idx_mbmode = 0, mvbp;
     int stride_y, fieldtx;
 
2d38081b
     mquant = v->pq; /* Lossy initialization */
cad16562
 
     if (v->skip_is_raw)
         skipped = get_bits1(gb);
     else
         skipped = v->s.mbskip_table[mb_pos];
     if (!skipped) {
         if (v->fourmvswitch)
             idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
         else
50f97219
             idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
cad16562
         switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
         /* store the motion vector type in a flag (useful later) */
         case MV_PMODE_INTFR_4MV:
             fourmv = 1;
             v->blk_mv_type[s->block_index[0]] = 0;
             v->blk_mv_type[s->block_index[1]] = 0;
             v->blk_mv_type[s->block_index[2]] = 0;
             v->blk_mv_type[s->block_index[3]] = 0;
             break;
         case MV_PMODE_INTFR_4MV_FIELD:
             fourmv = 1;
             v->blk_mv_type[s->block_index[0]] = 1;
             v->blk_mv_type[s->block_index[1]] = 1;
             v->blk_mv_type[s->block_index[2]] = 1;
             v->blk_mv_type[s->block_index[3]] = 1;
             break;
         case MV_PMODE_INTFR_2MV_FIELD:
             twomv = 1;
             v->blk_mv_type[s->block_index[0]] = 1;
             v->blk_mv_type[s->block_index[1]] = 1;
             v->blk_mv_type[s->block_index[2]] = 1;
             v->blk_mv_type[s->block_index[3]] = 1;
             break;
         case MV_PMODE_INTFR_1MV:
             v->blk_mv_type[s->block_index[0]] = 0;
             v->blk_mv_type[s->block_index[1]] = 0;
             v->blk_mv_type[s->block_index[2]] = 0;
             v->blk_mv_type[s->block_index[3]] = 0;
             break;
         }
         if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
db8403d0
             for (i = 0; i < 4; i++) {
                 s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
                 s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
             }
759001c5
             s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
cad16562
             s->mb_intra = v->is_intra[s->mb_x] = 1;
50f97219
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 1;
cad16562
             fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
             mb_has_coeffs = get_bits1(gb);
             if (mb_has_coeffs)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
             GET_MQUANT();
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
             /* Set DC scale - y and c use the same (not sure if necessary here) */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
             dst_idx = 0;
50f97219
             for (i = 0; i < 6; i++) {
cad16562
                 s->dc_val[0][s->block_index[i]] = 0;
                 dst_idx += i >> 2;
                 val = ((cbp >> (5 - i)) & 1);
                 v->mb_type[0][s->block_index[i]] = s->mb_intra;
                 v->a_avail = v->c_avail = 0;
50f97219
                 if (i == 2 || i == 3 || !s->first_slice_line)
cad16562
                     v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
                 if (i == 1 || i == 3 || s->mb_x)
cad16562
                     v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
                 vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                        (i & 4) ? v->codingset2 : v->codingset);
                 if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
cad16562
                 v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
                 if (i < 4) {
                     stride_y = s->linesize << fieldtx;
                     off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
                 } else {
                     stride_y = s->uvlinesize;
                     off = 0;
                 }
                 s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
                 //TODO: loop filter
             }
 
50f97219
         } else { // inter MB
cad16562
             mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
             if (mb_has_coeffs)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
                 v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
             } else {
                 if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
50f97219
                     || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
cad16562
                     v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
                 }
             }
             s->mb_intra = v->is_intra[s->mb_x] = 0;
50f97219
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 0;
cad16562
             fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
             /* for all motion vector read MVDATA and motion compensate each block */
             dst_idx = 0;
             if (fourmv) {
                 mvbp = v->fourmvbp;
50f97219
                 for (i = 0; i < 6; i++) {
cad16562
                     if (i < 4) {
                         dmv_x = dmv_y = 0;
50f97219
                         val   = ((mvbp >> (3 - i)) & 1);
                         if (val) {
cad16562
                             get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                         }
db8403d0
                         vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
                         vc1_mc_4mv_luma(v, i, 0, 0);
cad16562
                     } else if (i == 4) {
9b49d397
                         vc1_mc_4mv_chroma4(v, 0, 0, 0);
cad16562
                     }
                 }
             } else if (twomv) {
50f97219
                 mvbp  = v->twomvbp;
cad16562
                 dmv_x = dmv_y = 0;
                 if (mvbp & 2) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
db8403d0
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_4mv_luma(v, 0, 0, 0);
                 vc1_mc_4mv_luma(v, 1, 0, 0);
cad16562
                 dmv_x = dmv_y = 0;
                 if (mvbp & 1) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
db8403d0
                 vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_4mv_luma(v, 2, 0, 0);
                 vc1_mc_4mv_luma(v, 3, 0, 0);
9b49d397
                 vc1_mc_4mv_chroma4(v, 0, 0, 0);
cad16562
             } else {
                 mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
d51d6ae9
                 dmv_x = dmv_y = 0;
cad16562
                 if (mvbp) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
db8403d0
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
cad16562
                 vc1_mc_1mv(v, 0);
             }
             if (cbp)
                 GET_MQUANT();  // p. 227
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
             if (!v->ttmbf && cbp)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
50f97219
             for (i = 0; i < 6; i++) {
cad16562
                 s->dc_val[0][s->block_index[i]] = 0;
                 dst_idx += i >> 2;
                 val = ((cbp >> (5 - i)) & 1);
                 if (!fieldtx)
                     off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
                 else
                     off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
                 if (val) {
50f97219
                     pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                              first_block, s->dest[dst_idx] + off,
                                              (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
                                              (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
cad16562
                     block_cbp |= pat << (i << 2);
                     if (!v->ttmbf && ttmb < 8)
                         ttmb = -1;
                     first_block = 0;
                 }
             }
         }
     } else { // skipped
         s->mb_intra = v->is_intra[s->mb_x] = 0;
50f97219
         for (i = 0; i < 6; i++) {
cad16562
             v->mb_type[0][s->block_index[i]] = 0;
             s->dc_val[0][s->block_index[i]] = 0;
         }
759001c5
         s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
         s->current_picture.qscale_table[mb_pos] = 0;
cad16562
         v->blk_mv_type[s->block_index[0]] = 0;
         v->blk_mv_type[s->block_index[1]] = 0;
         v->blk_mv_type[s->block_index[2]] = 0;
         v->blk_mv_type[s->block_index[3]] = 0;
db8403d0
         vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
cad16562
         vc1_mc_1mv(v, 0);
     }
     if (s->mb_x == s->mb_width - 1)
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
     return 0;
 }
 
 static int vc1_decode_p_mb_intfi(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
     int i;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp = 0; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
 
     int mb_has_coeffs = 1; /* last_flag */
     int dmv_x, dmv_y; /* Differential MV components */
     int val; /* temp values */
     int first_block = 1;
     int dst_idx, off;
105cac34
     int pred_flag = 0;
cad16562
     int block_cbp = 0, pat, block_tt = 0;
     int idx_mbmode = 0;
 
2d38081b
     mquant = v->pq; /* Lossy initialization */
cad16562
 
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
759001c5
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
         s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
         s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
cad16562
         GET_MQUANT();
759001c5
         s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
50f97219
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
cad16562
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
             cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
         dst_idx = 0;
50f97219
         for (i = 0; i < 6; i++) {
             s->dc_val[0][s->block_index[i]]  = 0;
cad16562
             v->mb_type[0][s->block_index[i]] = 1;
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             v->a_avail = v->c_avail = 0;
50f97219
             if (i == 2 || i == 3 || !s->first_slice_line)
cad16562
                 v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
             if (i == 1 || i == 3 || s->mb_x)
cad16562
                 v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
             vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                    (i & 4) ? v->codingset2 : v->codingset);
             if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
                 continue;
cad16562
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
50f97219
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
cad16562
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
50f97219
             // TODO: loop filter
cad16562
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
759001c5
         s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
cad16562
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (idx_mbmode <= 5) { // 1-MV
08282952
             dmv_x = dmv_y = pred_flag = 0;
cad16562
             if (idx_mbmode & 1) {
                 get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
             }
             vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
             vc1_mc_1mv(v, 0);
             mb_has_coeffs = !(idx_mbmode & 2);
         } else { // 4-MV
             v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
50f97219
             for (i = 0; i < 6; i++) {
cad16562
                 if (i < 4) {
                     dmv_x = dmv_y = pred_flag = 0;
50f97219
                     val   = ((v->fourmvbp >> (3 - i)) & 1);
                     if (val) {
cad16562
                         get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
                     }
                     vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
db8403d0
                     vc1_mc_4mv_luma(v, i, 0, 0);
cad16562
                 } else if (i == 4)
                     vc1_mc_4mv_chroma(v, 0);
             }
             mb_has_coeffs = idx_mbmode & 1;
         }
         if (mb_has_coeffs)
             cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         if (cbp) {
             GET_MQUANT();
         }
759001c5
         s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
         dst_idx = 0;
50f97219
         for (i = 0; i < 6; i++) {
cad16562
             s->dc_val[0][s->block_index[i]] = 0;
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
50f97219
             if (val) {
                 pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                          first_block, s->dest[dst_idx] + off,
                                          (i & 4) ? s->uvlinesize : s->linesize,
                                          (i & 4) && (s->flags & CODEC_FLAG_GRAY),
                                          &block_tt);
cad16562
                 block_cbp |= pat << (i << 2);
50f97219
                 if (!v->ttmbf && ttmb < 8) ttmb = -1;
cad16562
                 first_block = 0;
             }
         }
     }
     if (s->mb_x == s->mb_width - 1)
50f97219
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
cad16562
     return 0;
 }
 
b761659b
 /** Decode one B-frame MB (in Main profile)
  */
 static void vc1_decode_b_mb(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
18b6a69c
     int i, j;
b761659b
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp = 0; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
     int mb_has_coeffs = 0; /* last_flag */
     int index, index1; /* LUT indexes */
     int val, sign; /* temp values */
     int first_block = 1;
     int dst_idx, off;
     int skipped, direct;
     int dmv_x[2], dmv_y[2];
     int bmvtype = BMV_TYPE_BACKWARD;
 
da9cea77
     mquant      = v->pq; /* lossy initialization */
b761659b
     s->mb_intra = 0;
 
     if (v->dmb_is_raw)
         direct = get_bits1(gb);
     else
         direct = v->direct_mb_plane[mb_pos];
     if (v->skip_is_raw)
         skipped = get_bits1(gb);
     else
         skipped = v->s.mbskip_table[mb_pos];
 
     dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
50f97219
     for (i = 0; i < 6; i++) {
b761659b
         v->mb_type[0][s->block_index[i]] = 0;
50f97219
         s->dc_val[0][s->block_index[i]]  = 0;
b761659b
     }
759001c5
     s->current_picture.qscale_table[mb_pos] = 0;
b761659b
 
     if (!direct) {
         if (!skipped) {
             GET_MVDATA(dmv_x[0], dmv_y[0]);
             dmv_x[1] = dmv_x[0];
             dmv_y[1] = dmv_y[0];
         }
50f97219
         if (skipped || !s->mb_intra) {
b761659b
             bmvtype = decode012(gb);
50f97219
             switch (bmvtype) {
b761659b
             case 0:
                 bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
                 break;
             case 1:
                 bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
                 break;
             case 2:
50f97219
                 bmvtype  = BMV_TYPE_INTERPOLATED;
b761659b
                 dmv_x[0] = dmv_y[0] = 0;
             }
         }
     }
50f97219
     for (i = 0; i < 6; i++)
b761659b
         v->mb_type[0][s->block_index[i]] = s->mb_intra;
 
     if (skipped) {
50f97219
         if (direct)
             bmvtype = BMV_TYPE_INTERPOLATED;
b761659b
         vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
         vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
         return;
     }
     if (direct) {
         cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         GET_MQUANT();
         s->mb_intra = 0;
759001c5
         s->current_picture.qscale_table[mb_pos] = mquant;
50f97219
         if (!v->ttmbf)
b761659b
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
         vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
         vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
     } else {
50f97219
         if (!mb_has_coeffs && !s->mb_intra) {
b761659b
             /* no coded blocks - effectively skipped */
             vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
             vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
             return;
         }
50f97219
         if (s->mb_intra && !mb_has_coeffs) {
b761659b
             GET_MQUANT();
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
b761659b
             s->ac_pred = get_bits1(gb);
             cbp = 0;
             vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
         } else {
50f97219
             if (bmvtype == BMV_TYPE_INTERPOLATED) {
b761659b
                 GET_MVDATA(dmv_x[0], dmv_y[0]);
50f97219
                 if (!mb_has_coeffs) {
b761659b
                     /* interpolated skipped block */
                     vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
                     vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
                     return;
                 }
             }
             vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
50f97219
             if (!s->mb_intra) {
b761659b
                 vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
             }
50f97219
             if (s->mb_intra)
b761659b
                 s->ac_pred = get_bits1(gb);
             cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             GET_MQUANT();
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
50f97219
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
b761659b
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
     }
     dst_idx = 0;
50f97219
     for (i = 0; i < 6; i++) {
b761659b
         s->dc_val[0][s->block_index[i]] = 0;
         dst_idx += i >> 2;
         val = ((cbp >> (5 - i)) & 1);
         off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
         v->mb_type[0][s->block_index[i]] = s->mb_intra;
50f97219
         if (s->mb_intra) {
b761659b
             /* check if prediction blocks A and C are available */
             v->a_avail = v->c_avail = 0;
50f97219
             if (i == 2 || i == 3 || !s->first_slice_line)
b761659b
                 v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
             if (i == 1 || i == 3 || s->mb_x)
b761659b
                 v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
             vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                    (i & 4) ? v->codingset2 : v->codingset);
             if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
                 continue;
18b6a69c
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
50f97219
             if (v->rangeredfrm)
                 for (j = 0; j < 64; j++)
                     s->block[i][j] <<= 1;
18b6a69c
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
50f97219
         } else if (val) {
             vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                first_block, s->dest[dst_idx] + off,
                                (i & 4) ? s->uvlinesize : s->linesize,
                                (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
             if (!v->ttmbf && ttmb < 8)
                 ttmb = -1;
b761659b
             first_block = 0;
         }
     }
 }
 
cad16562
 /** Decode one B-frame MB (in interlaced field B picture)
  */
 static void vc1_decode_b_mb_intfi(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
     int i, j;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp = 0; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
     int mb_has_coeffs = 0; /* last_flag */
     int val; /* temp value */
     int first_block = 1;
     int dst_idx, off;
     int fwd;
     int dmv_x[2], dmv_y[2], pred_flag[2];
     int bmvtype = BMV_TYPE_BACKWARD;
f4cc38e3
     int idx_mbmode;
cad16562
 
2d38081b
     mquant      = v->pq; /* Lossy initialization */
cad16562
     s->mb_intra = 0;
 
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
759001c5
         s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
         s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
         s->current_picture.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
cad16562
         GET_MQUANT();
759001c5
         s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
50f97219
         v->s.ac_pred  = v->acpred_plane[mb_pos] = get_bits1(gb);
cad16562
         mb_has_coeffs = idx_mbmode & 1;
         if (mb_has_coeffs)
             cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
         dst_idx = 0;
50f97219
         for (i = 0; i < 6; i++) {
cad16562
             s->dc_val[0][s->block_index[i]] = 0;
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             v->mb_type[0][s->block_index[i]] = s->mb_intra;
50f97219
             v->a_avail                       = v->c_avail = 0;
             if (i == 2 || i == 3 || !s->first_slice_line)
cad16562
                 v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
50f97219
             if (i == 1 || i == 3 || s->mb_x)
cad16562
                 v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
50f97219
             vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                    (i & 4) ? v->codingset2 : v->codingset);
             if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
                 continue;
cad16562
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
50f97219
             if (v->rangeredfrm)
                 for (j = 0; j < 64; j++)
                     s->block[i][j] <<= 1;
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
cad16562
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
50f97219
             // TODO: yet to perform loop filter
cad16562
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
759001c5
         s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
cad16562
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (v->fmb_is_raw)
             fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
         else
             fwd = v->forward_mb_plane[mb_pos];
         if (idx_mbmode <= 5) { // 1-MV
ebe8c7fe
             int interpmvp = 0;
50f97219
             dmv_x[0]     = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
cad16562
             pred_flag[0] = pred_flag[1] = 0;
             if (fwd)
                 bmvtype = BMV_TYPE_FORWARD;
             else {
                 bmvtype = decode012(gb);
50f97219
                 switch (bmvtype) {
cad16562
                 case 0:
                     bmvtype = BMV_TYPE_BACKWARD;
                     break;
                 case 1:
                     bmvtype = BMV_TYPE_DIRECT;
                     break;
                 case 2:
50f97219
                     bmvtype   = BMV_TYPE_INTERPOLATED;
cad16562
                     interpmvp = get_bits1(gb);
                 }
             }
             v->bmvtype = bmvtype;
             if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
                 get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
             }
ebe8c7fe
             if (interpmvp) {
cad16562
                 get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
             }
             if (bmvtype == BMV_TYPE_DIRECT) {
                 dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
                 dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
85d51d8e
                 if (!s->next_picture_ptr->field_picture) {
                     av_log(s->avctx, AV_LOG_ERROR, "Mixed field/frame direct mode not supported\n");
                     return;
                 }
cad16562
             }
             vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag);
             vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype);
             mb_has_coeffs = !(idx_mbmode & 2);
         } else { // 4-MV
             if (fwd)
                 bmvtype = BMV_TYPE_FORWARD;
50f97219
             v->bmvtype  = bmvtype;
cad16562
             v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
50f97219
             for (i = 0; i < 6; i++) {
cad16562
                 if (i < 4) {
                     dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
                     dmv_x[1] = dmv_y[1] = pred_flag[1] = 0;
                     val = ((v->fourmvbp >> (3 - i)) & 1);
50f97219
                     if (val) {
                         get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD],
                                                  &dmv_y[bmvtype == BMV_TYPE_BACKWARD],
                                              &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
cad16562
                     }
                     vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
db8403d0
                     vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0);
cad16562
                 } else if (i == 4)
                     vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
             }
             mb_has_coeffs = idx_mbmode & 1;
         }
         if (mb_has_coeffs)
             cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         if (cbp) {
             GET_MQUANT();
         }
759001c5
         s->current_picture.qscale_table[mb_pos] = mquant;
cad16562
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
         dst_idx = 0;
50f97219
         for (i = 0; i < 6; i++) {
cad16562
             s->dc_val[0][s->block_index[i]] = 0;
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
50f97219
             if (val) {
                 vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                    first_block, s->dest[dst_idx] + off,
                                    (i & 4) ? s->uvlinesize : s->linesize,
                                    (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
                 if (!v->ttmbf && ttmb < 8)
cad16562
                     ttmb = -1;
                 first_block = 0;
             }
         }
     }
 }
 
db8403d0
 /** Decode one B-frame MB (in interlaced frame B picture)
  */
 static int vc1_decode_b_mb_intfr(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
     int i, j;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp = 0; /* cbp decoding stuff */
     int mqdiff, mquant; /* MB quantization */
     int ttmb = v->ttfrm; /* MB Transform type */
     int mvsw = 0; /* motion vector switch */
     int mb_has_coeffs = 1; /* last_flag */
     int dmv_x, dmv_y; /* Differential MV components */
     int val; /* temp value */
     int first_block = 1;
     int dst_idx, off;
     int skipped, direct, twomv = 0;
     int block_cbp = 0, pat, block_tt = 0;
     int idx_mbmode = 0, mvbp;
     int stride_y, fieldtx;
     int bmvtype = BMV_TYPE_BACKWARD;
     int dir, dir2;
 
     mquant = v->pq; /* Lossy initialization */
     s->mb_intra = 0;
     if (v->skip_is_raw)
         skipped = get_bits1(gb);
     else
         skipped = v->s.mbskip_table[mb_pos];
 
     if (!skipped) {
         idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
1fb013a5
         if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
db8403d0
             twomv = 1;
             v->blk_mv_type[s->block_index[0]] = 1;
             v->blk_mv_type[s->block_index[1]] = 1;
             v->blk_mv_type[s->block_index[2]] = 1;
             v->blk_mv_type[s->block_index[3]] = 1;
         } else {
             v->blk_mv_type[s->block_index[0]] = 0;
             v->blk_mv_type[s->block_index[1]] = 0;
             v->blk_mv_type[s->block_index[2]] = 0;
             v->blk_mv_type[s->block_index[3]] = 0;
         }
     }
 
     if (v->dmb_is_raw)
         direct = get_bits1(gb);
     else
         direct = v->direct_mb_plane[mb_pos];
 
     if (direct) {
f4b288a6
         if (s->next_picture_ptr->field_picture)
             av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
db8403d0
         s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
         s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
         s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample);
         s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample);
 
         if (twomv) {
             s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample);
             s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample);
             s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
             s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
 
1fb013a5
             for (i = 1; i < 4; i += 2) {
db8403d0
                 s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
                 s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
                 s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
                 s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1];
             }
         } else {
             for (i = 1; i < 4; i++) {
                 s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0];
                 s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1];
                 s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0];
                 s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1];
             }
         }
     }
 
     if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
         for (i = 0; i < 4; i++) {
             s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
             s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
             s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
             s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
         }
1fb013a5
         s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
db8403d0
         s->mb_intra = v->is_intra[s->mb_x] = 1;
         for (i = 0; i < 6; i++)
             v->mb_type[0][s->block_index[i]] = 1;
         fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
         mb_has_coeffs = get_bits1(gb);
         if (mb_has_coeffs)
             cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
         GET_MQUANT();
         s->current_picture.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
         dst_idx = 0;
         for (i = 0; i < 6; i++) {
             s->dc_val[0][s->block_index[i]] = 0;
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             v->mb_type[0][s->block_index[i]] = s->mb_intra;
             v->a_avail = v->c_avail = 0;
             if (i == 2 || i == 3 || !s->first_slice_line)
                 v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
             if (i == 1 || i == 3 || s->mb_x)
                 v->c_avail = v->mb_type[0][s->block_index[i] - 1];
 
             vc1_decode_intra_block(v, s->block[i], i, val, mquant,
                                    (i & 4) ? v->codingset2 : v->codingset);
1fb013a5
             if (i > 3 && (s->flags & CODEC_FLAG_GRAY))
                 continue;
db8403d0
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
             if (i < 4) {
                 stride_y = s->linesize << fieldtx;
                 off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
             } else {
                 stride_y = s->uvlinesize;
                 off = 0;
             }
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
         if (!direct) {
             if (skipped || !s->mb_intra) {
                 bmvtype = decode012(gb);
                 switch (bmvtype) {
                 case 0:
                     bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
                     break;
                 case 1:
                     bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
                     break;
                 case 2:
                     bmvtype  = BMV_TYPE_INTERPOLATED;
                 }
             }
 
             if (twomv && bmvtype != BMV_TYPE_INTERPOLATED)
                 mvsw = get_bits1(gb);
         }
 
         if (!skipped) { // inter MB
             mb_has_coeffs = ff_vc1_mbmode_intfrp[0][idx_mbmode][3];
             if (mb_has_coeffs)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             if (!direct) {
1e2ab984
                 if (bmvtype == BMV_TYPE_INTERPOLATED && twomv) {
db8403d0
                     v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
1e2ab984
                 } else if (bmvtype == BMV_TYPE_INTERPOLATED || twomv) {
db8403d0
                     v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
                 }
             }
 
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 0;
             fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[0][idx_mbmode][1];
             /* for all motion vector read MVDATA and motion compensate each block */
             dst_idx = 0;
             if (direct) {
                 if (twomv) {
                     for (i = 0; i < 4; i++) {
                         vc1_mc_4mv_luma(v, i, 0, 0);
                         vc1_mc_4mv_luma(v, i, 1, 1);
                     }
9b49d397
                     vc1_mc_4mv_chroma4(v, 0, 0, 0);
688fc4ac
                     vc1_mc_4mv_chroma4(v, 1, 1, 1);
db8403d0
                 } else {
                     vc1_mc_1mv(v, 0);
                     vc1_interp_mc(v);
                 }
             } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) {
                 mvbp = v->fourmvbp;
                 for (i = 0; i < 4; i++) {
                     dir = i==1 || i==3;
                     dmv_x = dmv_y = 0;
                     val = ((mvbp >> (3 - i)) & 1);
1fb013a5
                     if (val)
db8403d0
                         get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                     j = i > 1 ? 2 : 0;
                     vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
                     vc1_mc_4mv_luma(v, j, dir, dir);
                     vc1_mc_4mv_luma(v, j+1, dir, dir);
                 }
 
9b49d397
                 vc1_mc_4mv_chroma4(v, 0, 0, 0);
688fc4ac
                 vc1_mc_4mv_chroma4(v, 1, 1, 1);
db8403d0
             } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
                 mvbp = v->twomvbp;
                 dmv_x = dmv_y = 0;
1fb013a5
                 if (mvbp & 2)
db8403d0
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_1mv(v, 0);
 
                 dmv_x = dmv_y = 0;
1fb013a5
                 if (mvbp & 1)
db8403d0
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1);
                 vc1_interp_mc(v);
             } else if (twomv) {
                 dir = bmvtype == BMV_TYPE_BACKWARD;
                 dir2 = dir;
                 if (mvsw)
                     dir2 = !dir;
                 mvbp = v->twomvbp;
                 dmv_x = dmv_y = 0;
1fb013a5
                 if (mvbp & 2)
db8403d0
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
 
                 dmv_x = dmv_y = 0;
1fb013a5
                 if (mvbp & 1)
db8403d0
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2);
 
                 if (mvsw) {
1fb013a5
                     for (i = 0; i < 2; i++) {
db8403d0
                         s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
                         s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
                         s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
                         s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
                     }
                 } else {
                     vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
                     vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
                 }
 
                 vc1_mc_4mv_luma(v, 0, dir, 0);
                 vc1_mc_4mv_luma(v, 1, dir, 0);
                 vc1_mc_4mv_luma(v, 2, dir2, 0);
                 vc1_mc_4mv_luma(v, 3, dir2, 0);
688fc4ac
                 vc1_mc_4mv_chroma4(v, dir, dir2, 0);
db8403d0
             } else {
                 dir = bmvtype == BMV_TYPE_BACKWARD;
 
                 mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
                 dmv_x = dmv_y = 0;
1fb013a5
                 if (mvbp)
db8403d0
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
 
                 vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir);
                 v->blk_mv_type[s->block_index[0]] = 1;
                 v->blk_mv_type[s->block_index[1]] = 1;
                 v->blk_mv_type[s->block_index[2]] = 1;
                 v->blk_mv_type[s->block_index[3]] = 1;
                 vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
1fb013a5
                 for (i = 0; i < 2; i++) {
db8403d0
                     s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
                     s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
                 }
                 vc1_mc_1mv(v, dir);
             }
 
             if (cbp)
                 GET_MQUANT();  // p. 227
             s->current_picture.qscale_table[mb_pos] = mquant;
             if (!v->ttmbf && cbp)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
             for (i = 0; i < 6; i++) {
                 s->dc_val[0][s->block_index[i]] = 0;
                 dst_idx += i >> 2;
                 val = ((cbp >> (5 - i)) & 1);
                 if (!fieldtx)
                     off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
                 else
                     off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
                 if (val) {
                     pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                              first_block, s->dest[dst_idx] + off,
                                              (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
                                              (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
                     block_cbp |= pat << (i << 2);
                     if (!v->ttmbf && ttmb < 8)
                         ttmb = -1;
                     first_block = 0;
                 }
             }
 
         } else { // skipped
             dir = 0;
             for (i = 0; i < 6; i++) {
                 v->mb_type[0][s->block_index[i]] = 0;
                 s->dc_val[0][s->block_index[i]] = 0;
             }
             s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
             s->current_picture.qscale_table[mb_pos] = 0;
             v->blk_mv_type[s->block_index[0]] = 0;
             v->blk_mv_type[s->block_index[1]] = 0;
             v->blk_mv_type[s->block_index[2]] = 0;
             v->blk_mv_type[s->block_index[3]] = 0;
 
             if (!direct) {
                 if (bmvtype == BMV_TYPE_INTERPOLATED) {
                     vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
                     vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1);
                 } else {
                     dir = bmvtype == BMV_TYPE_BACKWARD;
                     vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir);
                     if (mvsw) {
                         int dir2 = dir;
                         if (mvsw)
                             dir2 = !dir;
1fb013a5
                         for (i = 0; i < 2; i++) {
db8403d0
                             s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
                             s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
                             s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
                             s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
                         }
                     } else {
                         v->blk_mv_type[s->block_index[0]] = 1;
                         v->blk_mv_type[s->block_index[1]] = 1;
                         v->blk_mv_type[s->block_index[2]] = 1;
                         v->blk_mv_type[s->block_index[3]] = 1;
                         vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
1fb013a5
                         for (i = 0; i < 2; i++) {
db8403d0
                             s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
                             s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
                         }
                     }
                 }
             }
 
             vc1_mc_1mv(v, dir);
             if (direct || bmvtype == BMV_TYPE_INTERPOLATED) {
                 vc1_interp_mc(v);
             }
         }
     }
     if (s->mb_x == s->mb_width - 1)
1fb013a5
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
db8403d0
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
     return 0;
 }
 
b761659b
 /** Decode blocks of I-frame
  */
 static void vc1_decode_i_blocks(VC1Context *v)
 {
18b6a69c
     int k, j;
b761659b
     MpegEncContext *s = &v->s;
     int cbp, val;
     uint8_t *coded_val;
     int mb_pos;
 
     /* select codingmode used for VLC tables selection */
50f97219
     switch (v->y_ac_table_index) {
b761659b
     case 0:
         v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
         break;
     case 1:
         v->codingset = CS_HIGH_MOT_INTRA;
         break;
     case 2:
         v->codingset = CS_MID_RATE_INTRA;
         break;
     }
 
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
         break;
     case 1:
         v->codingset2 = CS_HIGH_MOT_INTER;
         break;
     case 2:
         v->codingset2 = CS_MID_RATE_INTER;
         break;
     }
 
     /* Set DC scale - y and c use the same */
     s->y_dc_scale = s->y_dc_scale_table[v->pq];
     s->c_dc_scale = s->c_dc_scale_table[v->pq];
 
     //do frame decode
     s->mb_x = s->mb_y = 0;
50f97219
     s->mb_intra         = 1;
b761659b
     s->first_slice_line = 1;
ee769c6a
     for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
351653a5
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
ee769c6a
         for (; s->mb_x < v->end_mb_x; s->mb_x++) {
bbfd2e7a
             uint8_t *dst[6];
b761659b
             ff_update_block_index(s);
bbfd2e7a
             dst[0] = s->dest[0];
             dst[1] = dst[0] + 8;
             dst[2] = s->dest[0] + s->linesize * 8;
             dst[3] = dst[2] + 8;
             dst[4] = s->dest[1];
             dst[5] = s->dest[2];
b761659b
             s->dsp.clear_blocks(s->block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_width;
759001c5
             s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
             s->current_picture.qscale_table[mb_pos]                = v->pq;
             s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
             s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
b761659b
 
             // do actual MB decoding and displaying
             cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
             v->s.ac_pred = get_bits1(&v->s.gb);
 
50f97219
             for (k = 0; k < 6; k++) {
b761659b
                 val = ((cbp >> (5 - k)) & 1);
 
                 if (k < 4) {
50f97219
                     int pred   = vc1_coded_block_pred(&v->s, k, &coded_val);
                     val        = val ^ pred;
b761659b
                     *coded_val = val;
                 }
                 cbp |= val << (5 - k);
 
50f97219
                 vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2);
b761659b
 
50f97219
                 if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
                     continue;
18b6a69c
                 v->vc1dsp.vc1_inv_trans_8x8(s->block[k]);
50f97219
                 if (v->pq >= 9 && v->overlap) {
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             s->block[k][j] <<= 1;
18b6a69c
                     s->dsp.put_signed_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
                 } else {
50f97219
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             s->block[k][j] = (s->block[k][j] - 64) << 1;
18b6a69c
                     s->dsp.put_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
                 }
b761659b
             }
 
50f97219
             if (v->pq >= 9 && v->overlap) {
                 if (s->mb_x) {
12802ec0
                     v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize);
                     v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
50f97219
                     if (!(s->flags & CODEC_FLAG_GRAY)) {
12802ec0
                         v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
                         v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
b761659b
                     }
                 }
12802ec0
                 v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
                 v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
50f97219
                 if (!s->first_slice_line) {
12802ec0
                     v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize);
                     v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
50f97219
                     if (!(s->flags & CODEC_FLAG_GRAY)) {
12802ec0
                         v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
                         v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
b761659b
                     }
                 }
12802ec0
                 v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
                 v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
b761659b
             }
50f97219
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
b761659b
 
50f97219
             if (get_bits_count(&s->gb) > v->bits) {
54974c62
                 ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
50f97219
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
b761659b
                 return;
             }
         }
3683b7e5
         if (!v->s.loop_filter)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
3683b7e5
         else if (s->mb_y)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
3683b7e5
 
b761659b
         s->first_slice_line = 0;
     }
3683b7e5
     if (v->s.loop_filter)
1d0feb5d
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
ee769c6a
 
     /* This is intentionally mb_height and not end_mb_y - unlike in advanced
      * profile, these only differ are when decoding MSS2 rectangles. */
54974c62
     ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
b761659b
 }
 
 /** Decode blocks of I-frame for advanced profile
  */
5c9f147e
 static void vc1_decode_i_blocks_adv(VC1Context *v)
b761659b
 {
70aa916e
     int k;
b761659b
     MpegEncContext *s = &v->s;
     int cbp, val;
     uint8_t *coded_val;
     int mb_pos;
     int mquant = v->pq;
     int mqdiff;
     GetBitContext *gb = &s->gb;
 
     /* select codingmode used for VLC tables selection */
50f97219
     switch (v->y_ac_table_index) {
b761659b
     case 0:
         v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
         break;
     case 1:
         v->codingset = CS_HIGH_MOT_INTRA;
         break;
     case 2:
         v->codingset = CS_MID_RATE_INTRA;
         break;
     }
 
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
         break;
     case 1:
         v->codingset2 = CS_HIGH_MOT_INTER;
         break;
     case 2:
         v->codingset2 = CS_MID_RATE_INTER;
         break;
     }
 
50f97219
     // do frame decode
     s->mb_x             = s->mb_y = 0;
     s->mb_intra         = 1;
b761659b
     s->first_slice_line = 1;
50f97219
     s->mb_y             = s->start_mb_y;
5c9f147e
     if (s->start_mb_y) {
f44d6445
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
50f97219
         memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
d4b99744
                (1 + s->b8_stride) * sizeof(*s->coded_block));
f44d6445
     }
50f97219
     for (; s->mb_y < s->end_mb_y; s->mb_y++) {
351653a5
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
50f97219
         for (;s->mb_x < s->mb_width; s->mb_x++) {
88bd7fdc
             int16_t (*block)[64] = v->block[v->cur_blk_idx];
b761659b
             ff_update_block_index(s);
7d2e03af
             s->dsp.clear_blocks(block[0]);
b761659b
             mb_pos = s->mb_x + s->mb_y * s->mb_stride;
759001c5
             s->current_picture.mb_type[mb_pos + v->mb_off]                         = MB_TYPE_INTRA;
             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
b761659b
 
             // do actual MB decoding and displaying
cad16562
             if (v->fieldtx_is_raw)
                 v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb);
b761659b
             cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
50f97219
             if ( v->acpred_is_raw)
b761659b
                 v->s.ac_pred = get_bits1(&v->s.gb);
             else
                 v->s.ac_pred = v->acpred_plane[mb_pos];
 
7d2e03af
             if (v->condover == CONDOVER_SELECT && v->overflg_is_raw)
                 v->over_flags_plane[mb_pos] = get_bits1(&v->s.gb);
b761659b
 
             GET_MQUANT();
 
759001c5
             s->current_picture.qscale_table[mb_pos] = mquant;
b761659b
             /* Set DC scale - y and c use the same */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
 
50f97219
             for (k = 0; k < 6; k++) {
b761659b
                 val = ((cbp >> (5 - k)) & 1);
 
                 if (k < 4) {
50f97219
                     int pred   = vc1_coded_block_pred(&v->s, k, &coded_val);
                     val        = val ^ pred;
b761659b
                     *coded_val = val;
                 }
                 cbp |= val << (5 - k);
 
50f97219
                 v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
                 v->c_avail = !!s->mb_x || (k == 1 || k == 3);
b761659b
 
50f97219
                 vc1_decode_i_block_adv(v, block[k], k, val,
                                        (k < 4) ? v->codingset : v->codingset2, mquant);
b761659b
 
50f97219
                 if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
                     continue;
7d2e03af
                 v->vc1dsp.vc1_inv_trans_8x8(block[k]);
b761659b
             }
 
7d2e03af
             vc1_smooth_overlap_filter_iblk(v);
             vc1_put_signed_blocks_clamped(v);
50f97219
             if (v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
b761659b
 
50f97219
             if (get_bits_count(&s->gb) > v->bits) {
cad16562
                 // TODO: may need modification to handle slice coding
54974c62
                 ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
50f97219
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
b761659b
                 return;
             }
         }
3683b7e5
         if (!v->s.loop_filter)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
3683b7e5
         else if (s->mb_y)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
b761659b
         s->first_slice_line = 0;
     }
7d2e03af
 
     /* raw bottom MB row */
     s->mb_x = 0;
0d194ee5
     init_block_index(v);
 
50f97219
     for (;s->mb_x < s->mb_width; s->mb_x++) {
7d2e03af
         ff_update_block_index(s);
         vc1_put_signed_blocks_clamped(v);
50f97219
         if (v->s.loop_filter)
             vc1_loop_filter_iblk_delayed(v, v->pq);
7d2e03af
     }
3683b7e5
     if (v->s.loop_filter)
1d0feb5d
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
54974c62
     ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
63ccd466
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
b761659b
 }
 
5c9f147e
 static void vc1_decode_p_blocks(VC1Context *v)
b761659b
 {
     MpegEncContext *s = &v->s;
c47d3835
     int apply_loop_filter;
b761659b
 
     /* select codingmode used for VLC tables selection */
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
         break;
     case 1:
         v->codingset = CS_HIGH_MOT_INTRA;
         break;
     case 2:
         v->codingset = CS_MID_RATE_INTRA;
         break;
     }
 
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
         break;
     case 1:
         v->codingset2 = CS_HIGH_MOT_INTER;
         break;
     case 2:
         v->codingset2 = CS_MID_RATE_INTER;
         break;
     }
 
5d9d8461
     apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
                           v->fcm == PROGRESSIVE;
b761659b
     s->first_slice_line = 1;
     memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
50f97219
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
351653a5
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
50f97219
         for (; s->mb_x < s->mb_width; s->mb_x++) {
b761659b
             ff_update_block_index(s);
 
1f948745
             if (v->fcm == ILACE_FIELD)
cad16562
                 vc1_decode_p_mb_intfi(v);
1f948745
             else if (v->fcm == ILACE_FRAME)
cad16562
                 vc1_decode_p_mb_intfr(v);
             else vc1_decode_p_mb(v);
5d9d8461
             if (s->mb_y != s->start_mb_y && apply_loop_filter)
c47d3835
                 vc1_apply_p_loop_filter(v);
50f97219
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
cad16562
                 // TODO: may need modification to handle slice coding
54974c62
                 ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
50f97219
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
b761659b
                 return;
             }
         }
50f97219
         memmove(v->cbp_base,      v->cbp,      sizeof(v->cbp_base[0])      * s->mb_stride);
         memmove(v->ttblk_base,    v->ttblk,    sizeof(v->ttblk_base[0])    * s->mb_stride);
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
         memmove(v->luma_mv_base,  v->luma_mv,  sizeof(v->luma_mv_base[0])  * s->mb_stride);
1d0feb5d
         if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
b761659b
         s->first_slice_line = 0;
     }
c47d3835
     if (apply_loop_filter) {
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
c47d3835
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
             vc1_apply_p_loop_filter(v);
         }
     }
5c9f147e
     if (s->end_mb_y >= s->start_mb_y)
1d0feb5d
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
54974c62
     ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
63ccd466
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
b761659b
 }
 
5c9f147e
 static void vc1_decode_b_blocks(VC1Context *v)
b761659b
 {
     MpegEncContext *s = &v->s;
 
     /* select codingmode used for VLC tables selection */
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
         break;
     case 1:
         v->codingset = CS_HIGH_MOT_INTRA;
         break;
     case 2:
         v->codingset = CS_MID_RATE_INTRA;
         break;
     }
 
50f97219
     switch (v->c_ac_table_index) {
b761659b
     case 0:
         v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
         break;
     case 1:
         v->codingset2 = CS_HIGH_MOT_INTER;
         break;
     case 2:
         v->codingset2 = CS_MID_RATE_INTER;
         break;
     }
 
     s->first_slice_line = 1;
50f97219
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
351653a5
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
50f97219
         for (; s->mb_x < s->mb_width; s->mb_x++) {
b761659b
             ff_update_block_index(s);
 
1f948745
             if (v->fcm == ILACE_FIELD)
cad16562
                 vc1_decode_b_mb_intfi(v);
db8403d0
             else if (v->fcm == ILACE_FRAME)
                 vc1_decode_b_mb_intfr(v);
cad16562
             else
                 vc1_decode_b_mb(v);
50f97219
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
cad16562
                 // TODO: may need modification to handle slice coding
54974c62
                 ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
50f97219
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
b761659b
                 return;
             }
50f97219
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
b761659b
         }
3683b7e5
         if (!v->s.loop_filter)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
3683b7e5
         else if (s->mb_y)
1d0feb5d
             ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
b761659b
         s->first_slice_line = 0;
     }
3683b7e5
     if (v->s.loop_filter)
1d0feb5d
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
54974c62
     ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
63ccd466
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
b761659b
 }
 
 static void vc1_decode_skip_blocks(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
 
5e25fdbf
     if (!v->s.last_picture.f.data[0])
         return;
 
54974c62
     ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
b761659b
     s->first_slice_line = 1;
50f97219
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
b761659b
         s->mb_x = 0;
0d194ee5
         init_block_index(v);
b761659b
         ff_update_block_index(s);
657ccb5a
         memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize,   s->linesize   * 16);
         memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
         memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
1d0feb5d
         ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
b761659b
         s->first_slice_line = 0;
     }
ce5e49b0
     s->pict_type = AV_PICTURE_TYPE_P;
b761659b
 }
 
7627c35a
 void ff_vc1_decode_blocks(VC1Context *v)
b761659b
 {
 
     v->s.esc3_level_length = 0;
50f97219
     if (v->x8_type) {
         ff_intrax8_decode_picture(&v->x8, 2*v->pq + v->halfpq, v->pq * !v->pquantizer);
     } else {
         v->cur_blk_idx     =  0;
         v->left_blk_idx    = -1;
         v->topleft_blk_idx =  1;
         v->top_blk_idx     =  2;
         switch (v->s.pict_type) {
ce5e49b0
         case AV_PICTURE_TYPE_I:
50f97219
             if (v->profile == PROFILE_ADVANCED)
5c9f147e
                 vc1_decode_i_blocks_adv(v);
b761659b
             else
                 vc1_decode_i_blocks(v);
             break;
ce5e49b0
         case AV_PICTURE_TYPE_P:
50f97219
             if (v->p_frame_skipped)
b761659b
                 vc1_decode_skip_blocks(v);
             else
5c9f147e
                 vc1_decode_p_blocks(v);
b761659b
             break;
ce5e49b0
         case AV_PICTURE_TYPE_B:
50f97219
             if (v->bi_type) {
                 if (v->profile == PROFILE_ADVANCED)
5c9f147e
                     vc1_decode_i_blocks_adv(v);
b761659b
                 else
                     vc1_decode_i_blocks(v);
50f97219
             } else
5c9f147e
                 vc1_decode_b_blocks(v);
b761659b
             break;
         }
     }
 }
 
45ecda85
 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
 
 typedef struct {
     /**
      * Transform coefficients for both sprites in 16.16 fixed point format,
      * in the order they appear in the bitstream:
      *  x scale
      *  rotation 1 (unused)
      *  x offset
      *  rotation 2 (unused)
      *  y scale
      *  y offset
      *  alpha
      */
     int coefs[2][7];
 
     int effect_type, effect_flag;
     int effect_pcount1, effect_pcount2;   ///< amount of effect parameters stored in effect_params
     int effect_params1[15], effect_params2[10]; ///< effect parameters in 16.16 fixed point format
 } SpriteData;
 
 static inline int get_fp_val(GetBitContext* gb)
768c5251
 {
50f97219
     return (get_bits_long(gb, 30) - (1 << 29)) << 1;
768c5251
 }
 
45ecda85
 static void vc1_sprite_parse_transform(GetBitContext* gb, int c[7])
768c5251
 {
45ecda85
     c[1] = c[3] = 0;
768c5251
 
     switch (get_bits(gb, 2)) {
     case 0:
50f97219
         c[0] = 1 << 16;
45ecda85
         c[2] = get_fp_val(gb);
50f97219
         c[4] = 1 << 16;
768c5251
         break;
     case 1:
45ecda85
         c[0] = c[4] = get_fp_val(gb);
         c[2] = get_fp_val(gb);
768c5251
         break;
     case 2:
45ecda85
         c[0] = get_fp_val(gb);
         c[2] = get_fp_val(gb);
         c[4] = get_fp_val(gb);
768c5251
         break;
     case 3:
45ecda85
         c[0] = get_fp_val(gb);
         c[1] = get_fp_val(gb);
         c[2] = get_fp_val(gb);
         c[3] = get_fp_val(gb);
         c[4] = get_fp_val(gb);
768c5251
         break;
     }
45ecda85
     c[5] = get_fp_val(gb);
768c5251
     if (get_bits1(gb))
45ecda85
         c[6] = get_fp_val(gb);
768c5251
     else
50f97219
         c[6] = 1 << 16;
768c5251
 }
 
48016f8f
 static int vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd)
768c5251
 {
45ecda85
     AVCodecContext *avctx = v->s.avctx;
     int sprite, i;
 
     for (sprite = 0; sprite <= v->two_sprites; sprite++) {
         vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
         if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
6d97484d
             avpriv_request_sample(avctx, "Non-zero rotation coefficients");
45ecda85
         av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
768c5251
         for (i = 0; i < 7; i++)
45ecda85
             av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
                    sd->coefs[sprite][i] / (1<<16),
50f97219
                    (abs(sd->coefs[sprite][i]) & 0xFFFF) * 1000 / (1 << 16));
45ecda85
         av_log(avctx, AV_LOG_DEBUG, "\n");
768c5251
     }
45ecda85
 
768c5251
     skip_bits(gb, 2);
45ecda85
     if (sd->effect_type = get_bits_long(gb, 30)) {
         switch (sd->effect_pcount1 = get_bits(gb, 4)) {
768c5251
         case 7:
45ecda85
             vc1_sprite_parse_transform(gb, sd->effect_params1);
768c5251
             break;
         case 14:
45ecda85
             vc1_sprite_parse_transform(gb, sd->effect_params1);
             vc1_sprite_parse_transform(gb, sd->effect_params1 + 7);
768c5251
             break;
         default:
45ecda85
             for (i = 0; i < sd->effect_pcount1; i++)
                 sd->effect_params1[i] = get_fp_val(gb);
768c5251
         }
45ecda85
         if (sd->effect_type != 13 || sd->effect_params1[0] != sd->coefs[0][6]) {
768c5251
             // effect 13 is simple alpha blending and matches the opacity above
45ecda85
             av_log(avctx, AV_LOG_DEBUG, "Effect: %d; params: ", sd->effect_type);
             for (i = 0; i < sd->effect_pcount1; i++)
                 av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
50f97219
                        sd->effect_params1[i] / (1 << 16),
                        (abs(sd->effect_params1[i]) & 0xFFFF) * 1000 / (1 << 16));
45ecda85
             av_log(avctx, AV_LOG_DEBUG, "\n");
768c5251
         }
 
45ecda85
         sd->effect_pcount2 = get_bits(gb, 16);
         if (sd->effect_pcount2 > 10) {
             av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n");
48016f8f
             return AVERROR_INVALIDDATA;
45ecda85
         } else if (sd->effect_pcount2) {
             i = -1;
             av_log(avctx, AV_LOG_DEBUG, "Effect params 2: ");
50f97219
             while (++i < sd->effect_pcount2) {
45ecda85
                 sd->effect_params2[i] = get_fp_val(gb);
                 av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
50f97219
                        sd->effect_params2[i] / (1 << 16),
                        (abs(sd->effect_params2[i]) & 0xFFFF) * 1000 / (1 << 16));
768c5251
             }
45ecda85
             av_log(avctx, AV_LOG_DEBUG, "\n");
768c5251
         }
     }
45ecda85
     if (sd->effect_flag = get_bits1(gb))
         av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n");
768c5251
 
     if (get_bits_count(gb) >= gb->size_in_bits +
48016f8f
        (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0)) {
45ecda85
         av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n");
48016f8f
         return AVERROR_INVALIDDATA;
     }
768c5251
     if (get_bits_count(gb) < gb->size_in_bits - 8)
45ecda85
         av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n");
48016f8f
 
     return 0;
45ecda85
 }
 
 static void vc1_draw_sprites(VC1Context *v, SpriteData* sd)
 {
     int i, plane, row, sprite;
     int sr_cache[2][2] = { { -1, -1 }, { -1, -1 } };
     uint8_t* src_h[2][2];
     int xoff[2], xadv[2], yoff[2], yadv[2], alpha;
     int ysub[2];
     MpegEncContext *s = &v->s;
 
cf95dee3
     for (i = 0; i <= v->two_sprites; i++) {
45ecda85
         xoff[i] = av_clip(sd->coefs[i][2], 0, v->sprite_width-1 << 16);
         xadv[i] = sd->coefs[i][0];
50f97219
         if (xadv[i] != 1<<16 || (v->sprite_width << 16) - (v->output_width << 16) - xoff[i])
45ecda85
             xadv[i] = av_clip(xadv[i], 0, ((v->sprite_width<<16) - xoff[i] - 1) / v->output_width);
 
         yoff[i] = av_clip(sd->coefs[i][5], 0, v->sprite_height-1 << 16);
50f97219
         yadv[i] = av_clip(sd->coefs[i][4], 0, ((v->sprite_height << 16) - yoff[i]) / v->output_height);
45ecda85
     }
     alpha = av_clip(sd->coefs[1][6], 0, (1<<16) - 1);
 
     for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++) {
         int width = v->output_width>>!!plane;
 
         for (row = 0; row < v->output_height>>!!plane; row++) {
6792559f
             uint8_t *dst = v->sprite_output_frame->data[plane] +
                            v->sprite_output_frame->linesize[plane] * row;
45ecda85
 
             for (sprite = 0; sprite <= v->two_sprites; sprite++) {
                 uint8_t *iplane = s->current_picture.f.data[plane];
                 int      iline  = s->current_picture.f.linesize[plane];
50f97219
                 int      ycoord = yoff[sprite] + yadv[sprite] * row;
                 int      yline  = ycoord >> 16;
2bf369b6
                 int      next_line;
50f97219
                 ysub[sprite] = ycoord & 0xFFFF;
45ecda85
                 if (sprite) {
                     iplane = s->last_picture.f.data[plane];
                     iline  = s->last_picture.f.linesize[plane];
                 }
2bf369b6
                 next_line = FFMIN(yline + 1, (v->sprite_height >> !!plane) - 1) * iline;
50f97219
                 if (!(xoff[sprite] & 0xFFFF) && xadv[sprite] == 1 << 16) {
                         src_h[sprite][0] = iplane + (xoff[sprite] >> 16) +  yline      * iline;
45ecda85
                     if (ysub[sprite])
2bf369b6
                         src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + next_line;
45ecda85
                 } else {
                     if (sr_cache[sprite][0] != yline) {
                         if (sr_cache[sprite][1] == yline) {
                             FFSWAP(uint8_t*, v->sr_rows[sprite][0], v->sr_rows[sprite][1]);
                             FFSWAP(int,        sr_cache[sprite][0],   sr_cache[sprite][1]);
                         } else {
50f97219
                             v->vc1dsp.sprite_h(v->sr_rows[sprite][0], iplane + yline * iline, xoff[sprite], xadv[sprite], width);
45ecda85
                             sr_cache[sprite][0] = yline;
                         }
                     }
                     if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) {
2bf369b6
                         v->vc1dsp.sprite_h(v->sr_rows[sprite][1],
                                            iplane + next_line, xoff[sprite],
                                            xadv[sprite], width);
45ecda85
                         sr_cache[sprite][1] = yline + 1;
                     }
                     src_h[sprite][0] = v->sr_rows[sprite][0];
                     src_h[sprite][1] = v->sr_rows[sprite][1];
                 }
             }
 
             if (!v->two_sprites) {
                 if (ysub[0]) {
                     v->vc1dsp.sprite_v_single(dst, src_h[0][0], src_h[0][1], ysub[0], width);
                 } else {
                     memcpy(dst, src_h[0][0], width);
                 }
             } else {
                 if (ysub[0] && ysub[1]) {
                     v->vc1dsp.sprite_v_double_twoscale(dst, src_h[0][0], src_h[0][1], ysub[0],
                                                        src_h[1][0], src_h[1][1], ysub[1], alpha, width);
                 } else if (ysub[0]) {
                     v->vc1dsp.sprite_v_double_onescale(dst, src_h[0][0], src_h[0][1], ysub[0],
                                                        src_h[1][0], alpha, width);
                 } else if (ysub[1]) {
                     v->vc1dsp.sprite_v_double_onescale(dst, src_h[1][0], src_h[1][1], ysub[1],
                                                        src_h[0][0], (1<<16)-1-alpha, width);
                 } else {
                     v->vc1dsp.sprite_v_double_noscale(dst, src_h[0][0], src_h[1][0], alpha, width);
                 }
             }
         }
 
         if (!plane) {
cf95dee3
             for (i = 0; i <= v->two_sprites; i++) {
45ecda85
                 xoff[i] >>= 1;
                 yoff[i] >>= 1;
             }
         }
 
     }
 }
 
 
 static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
 {
1ec94b0f
     int ret;
50f97219
     MpegEncContext *s     = &v->s;
45ecda85
     AVCodecContext *avctx = s->avctx;
     SpriteData sd;
 
5f00b333
     memset(&sd, 0, sizeof(sd));
 
48016f8f
     ret = vc1_parse_sprites(v, gb, &sd);
     if (ret < 0)
         return ret;
45ecda85
 
     if (!s->current_picture.f.data[0]) {
         av_log(avctx, AV_LOG_ERROR, "Got no sprites\n");
         return -1;
     }
 
     if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f.data[0])) {
         av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");
         v->two_sprites = 0;
     }
 
6792559f
     av_frame_unref(v->sprite_output_frame);
92cbd775
     if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0)
1ec94b0f
         return ret;
45ecda85
 
     vc1_draw_sprites(v, &sd);
 
     return 0;
 }
 
 static void vc1_sprite_flush(AVCodecContext *avctx)
 {
50f97219
     VC1Context *v     = avctx->priv_data;
45ecda85
     MpegEncContext *s = &v->s;
     AVFrame *f = &s->current_picture.f;
     int plane, i;
 
     /* Windows Media Image codecs have a convergence interval of two keyframes.
        Since we can't enforce it, clear to black the missing sprite. This is
        wrong but it looks better than doing nothing. */
 
     if (f->data[0])
         for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++)
             for (i = 0; i < v->sprite_height>>!!plane; i++)
50f97219
                 memset(f->data[plane] + i * f->linesize[plane],
45ecda85
                        plane ? 128 : 0, f->linesize[plane]);
768c5251
 }
 
45ecda85
 #endif
 
7627c35a
 av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
d2f119a1
 {
     MpegEncContext *s = &v->s;
     int i;
017e234c
     int mb_height = FFALIGN(s->mb_height, 2);
d2f119a1
 
     /* Allocate mb bitplanes */
017e234c
     v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height);
     v->direct_mb_plane  = av_malloc (s->mb_stride * mb_height);
     v->forward_mb_plane = av_malloc (s->mb_stride * mb_height);
     v->fieldtx_plane    = av_mallocz(s->mb_stride * mb_height);
     v->acpred_plane     = av_malloc (s->mb_stride * mb_height);
     v->over_flags_plane = av_malloc (s->mb_stride * mb_height);
d2f119a1
 
     v->n_allocated_blks = s->mb_width + 2;
50f97219
     v->block            = av_malloc(sizeof(*v->block) * v->n_allocated_blks);
     v->cbp_base         = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride);
     v->cbp              = v->cbp_base + s->mb_stride;
     v->ttblk_base       = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride);
     v->ttblk            = v->ttblk_base + s->mb_stride;
     v->is_intra_base    = av_mallocz(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);
     v->is_intra         = v->is_intra_base + s->mb_stride;
3e626548
     v->luma_mv_base     = av_mallocz(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride);
50f97219
     v->luma_mv          = v->luma_mv_base + s->mb_stride;
d2f119a1
 
     /* allocate block type info in that way so it could be used with s->block_index[] */
017e234c
     v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
50f97219
     v->mb_type[0]   = v->mb_type_base + s->b8_stride + 1;
017e234c
     v->mb_type[1]   = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1;
     v->mb_type[2]   = v->mb_type[1] + s->mb_stride * (mb_height + 1);
d2f119a1
 
cad16562
     /* allocate memory to store block level MV info */
017e234c
     v->blk_mv_type_base = av_mallocz(     s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
50f97219
     v->blk_mv_type      = v->blk_mv_type_base + s->b8_stride + 1;
017e234c
     v->mv_f_base        = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));
50f97219
     v->mv_f[0]          = v->mv_f_base + s->b8_stride + 1;
017e234c
     v->mv_f[1]          = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
     v->mv_f_next_base   = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));
50f97219
     v->mv_f_next[0]     = v->mv_f_next_base + s->b8_stride + 1;
017e234c
     v->mv_f_next[1]     = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
cad16562
 
d2f119a1
     /* Init coded blocks info */
50f97219
     if (v->profile == PROFILE_ADVANCED) {
d2f119a1
 //        if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
 //            return -1;
 //        if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
 //            return -1;
     }
 
     ff_intrax8_common_init(&v->x8,s);
 
36ef5369
     if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
d2f119a1
         for (i = 0; i < 4; i++)
a51f3b53
             if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width)))
                 return AVERROR(ENOMEM);
d2f119a1
     }
 
     if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane ||
         !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base ||
ede50844
         !v->mb_type_base) {
         av_freep(&v->mv_type_mb_plane);
         av_freep(&v->direct_mb_plane);
         av_freep(&v->acpred_plane);
         av_freep(&v->over_flags_plane);
         av_freep(&v->block);
         av_freep(&v->cbp_base);
         av_freep(&v->ttblk_base);
         av_freep(&v->is_intra_base);
         av_freep(&v->luma_mv_base);
         av_freep(&v->mb_type_base);
         return AVERROR(ENOMEM);
     }
d2f119a1
 
     return 0;
 }
 
7627c35a
 av_cold void ff_vc1_init_transposed_scantables(VC1Context *v)
 {
     int i;
     for (i = 0; i < 64; i++) {
 #define transpose(x) ((x >> 3) | ((x & 7) << 3))
         v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]);
         v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]);
         v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]);
         v->zz_8x8[3][i] = transpose(ff_wmv1_scantable[3][i]);
         v->zzi_8x8[i]   = transpose(ff_vc1_adv_interlaced_8x8_zz[i]);
     }
     v->left_blk_sh = 0;
     v->top_blk_sh  = 3;
 }
 
b761659b
 /** Initialize a VC1/WMV3 decoder
  * @todo TODO: Handle VC-1 IDUs (Transport level?)
  * @todo TODO: Decypher remaining bits in extra_data
  */
 static av_cold int vc1_decode_init(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
     GetBitContext gb;
35603134
     int ret;
b761659b
 
45ecda85
     /* save the container output size for WMImage */
     v->output_width  = avctx->width;
     v->output_height = avctx->height;
 
50f97219
     if (!avctx->extradata_size || !avctx->extradata)
         return -1;
b761659b
     if (!(avctx->flags & CODEC_FLAG_GRAY))
         avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
     else
716d413c
         avctx->pix_fmt = AV_PIX_FMT_GRAY8;
08303d77
     avctx->hwaccel = ff_find_hwaccel(avctx);
b761659b
     v->s.avctx = avctx;
 
35603134
     if ((ret = ff_vc1_init_common(v)) < 0)
         return ret;
16af29a7
     // ensure static VLC tables are initialized
35603134
     if ((ret = ff_msmpeg4_decode_init(avctx)) < 0)
         return ret;
     if ((ret = ff_vc1_decode_init_alloc_tables(v)) < 0)
         return ret;
16af29a7
     // Hack to ensure the above functions will be called
     // again once we know all necessary settings.
     // That this is necessary might indicate a bug.
     ff_vc1_decode_end(avctx);
c4e394e4
 
79dad2a9
     ff_h264chroma_init(&v->h264chroma, 8);
12802ec0
     ff_vc1dsp_init(&v->vc1dsp);
b761659b
 
36ef5369
     if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
b761659b
         int count = 0;
 
         // looks like WMV3 has a sequence header stored in the extradata
         // advanced sequence header may be before the first frame
         // the last byte of the extradata is a version number, 1 for the
         // samples we can decode
 
         init_get_bits(&gb, avctx->extradata, avctx->extradata_size*8);
 
35603134
         if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0)
           return ret;
b761659b
 
         count = avctx->extradata_size*8 - get_bits_count(&gb);
50f97219
         if (count > 0) {
b761659b
             av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n",
                    count, get_bits(&gb, count));
50f97219
         } else if (count < 0) {
b761659b
             av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count);
         }
768c5251
     } else { // VC1/WVC1/WVP2
b761659b
         const uint8_t *start = avctx->extradata;
         uint8_t *end = avctx->extradata + avctx->extradata_size;
         const uint8_t *next;
         int size, buf2_size;
         uint8_t *buf2 = NULL;
         int seq_initialized = 0, ep_initialized = 0;
 
50f97219
         if (avctx->extradata_size < 16) {
b761659b
             av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size);
             return -1;
         }
 
50f97219
         buf2  = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
95ce961d
         start = find_next_marker(start, end); // in WVC1 extradata first byte is its size, but can be 0 in mkv
50f97219
         next  = start;
         for (; next < end; start = next) {
b761659b
             next = find_next_marker(start + 4, end);
             size = next - start - 4;
50f97219
             if (size <= 0)
                 continue;
b761659b
             buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
             init_get_bits(&gb, buf2, buf2_size * 8);
50f97219
             switch (AV_RB32(start)) {
b761659b
             case VC1_CODE_SEQHDR:
35603134
                 if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) {
b761659b
                     av_free(buf2);
35603134
                     return ret;
b761659b
                 }
                 seq_initialized = 1;
                 break;
             case VC1_CODE_ENTRYPOINT:
35603134
                 if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0) {
b761659b
                     av_free(buf2);
35603134
                     return ret;
b761659b
                 }
                 ep_initialized = 1;
                 break;
             }
         }
         av_free(buf2);
50f97219
         if (!seq_initialized || !ep_initialized) {
b761659b
             av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
             return -1;
         }
77bcb896
         v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
b761659b
     }
7b20d35a
 
6792559f
     v->sprite_output_frame = av_frame_alloc();
     if (!v->sprite_output_frame)
         return AVERROR(ENOMEM);
 
0215006a
     avctx->profile = v->profile;
     if (v->profile == PROFILE_ADVANCED)
         avctx->level = v->level;
 
3dc99a18
     avctx->has_b_frames = !!avctx->max_b_frames;
b761659b
 
50f97219
     s->mb_width  = (avctx->coded_width  + 15) >> 4;
     s->mb_height = (avctx->coded_height + 15) >> 4;
b761659b
 
0b05864e
     if (v->profile == PROFILE_ADVANCED || v->res_fasttx) {
7627c35a
         ff_vc1_init_transposed_scantables(v);
58bb6b7d
     } else {
1fec0550
         memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64);
58bb6b7d
         v->left_blk_sh = 3;
         v->top_blk_sh  = 0;
     }
 
36ef5369
     if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
45ecda85
         v->sprite_width  = avctx->coded_width;
         v->sprite_height = avctx->coded_height;
 
         avctx->coded_width  = avctx->width  = v->output_width;
         avctx->coded_height = avctx->height = v->output_height;
 
         // prevent 16.16 overflows
50f97219
         if (v->sprite_width  > 1 << 14 ||
             v->sprite_height > 1 << 14 ||
             v->output_width  > 1 << 14 ||
             v->output_height > 1 << 14) return -1;
058e1f8d
 
         if ((v->sprite_width&1) || (v->sprite_height&1)) {
a9b42487
             avpriv_request_sample(avctx, "odd sprites support");
058e1f8d
             return AVERROR_PATCHWELCOME;
         }
45ecda85
     }
b761659b
     return 0;
 }
 
d2f119a1
 /** Close a VC1/WMV3 decoder
  * @warning Initial try at using MpegEncContext stuff
  */
7627c35a
 av_cold int ff_vc1_decode_end(AVCodecContext *avctx)
d2f119a1
 {
     VC1Context *v = avctx->priv_data;
     int i;
 
6792559f
     av_frame_free(&v->sprite_output_frame);
759001c5
 
d2f119a1
     for (i = 0; i < 4; i++)
50f97219
         av_freep(&v->sr_rows[i >> 1][i & 1]);
d2f119a1
     av_freep(&v->hrd_rate);
     av_freep(&v->hrd_buffer);
efd29844
     ff_MPV_common_end(&v->s);
d2f119a1
     av_freep(&v->mv_type_mb_plane);
     av_freep(&v->direct_mb_plane);
cad16562
     av_freep(&v->forward_mb_plane);
     av_freep(&v->fieldtx_plane);
d2f119a1
     av_freep(&v->acpred_plane);
     av_freep(&v->over_flags_plane);
     av_freep(&v->mb_type_base);
cad16562
     av_freep(&v->blk_mv_type_base);
     av_freep(&v->mv_f_base);
     av_freep(&v->mv_f_next_base);
d2f119a1
     av_freep(&v->block);
     av_freep(&v->cbp_base);
     av_freep(&v->ttblk_base);
     av_freep(&v->is_intra_base); // FIXME use v->mb_type[]
     av_freep(&v->luma_mv_base);
     ff_intrax8_common_end(&v->x8);
     return 0;
 }
 
b761659b
 
 /** Decode a VC1/WMV3 frame
  * @todo TODO: Handle VC-1 IDUs (Transport level?)
  */
50f97219
 static int vc1_decode_frame(AVCodecContext *avctx, void *data,
df9b9567
                             int *got_frame, AVPacket *avpkt)
b761659b
 {
     const uint8_t *buf = avpkt->data;
759001c5
     int buf_size = avpkt->size, n_slices = 0, i, ret;
b761659b
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *pict = data;
     uint8_t *buf2 = NULL;
b87ff344
     const uint8_t *buf_start = buf, *buf_start_second_field = NULL;
41f55277
     int mb_height, n_slices1=-1;
f44d6445
     struct {
         uint8_t *buf;
         GetBitContext gb;
         int mby_start;
b797f735
     } *slices = NULL, *tmp;
b761659b
 
b87ff344
     v->second_field = 0;
 
d1590a0a
     if(s->flags & CODEC_FLAG_LOW_DELAY)
         s->low_delay = 1;
 
b761659b
     /* no supplementary picture */
fb985071
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
b761659b
         /* special case for last picture */
50f97219
         if (s->low_delay == 0 && s->next_picture_ptr) {
759001c5
             if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
                 return ret;
50f97219
             s->next_picture_ptr = NULL;
b761659b
 
df9b9567
             *got_frame = 1;
b761659b
         }
 
cc7eff1f
         return buf_size;
b761659b
     }
 
a0c6c8e5
     if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
         if (v->profile < PROFILE_ADVANCED)
             avctx->pix_fmt = AV_PIX_FMT_VDPAU_WMV3;
         else
             avctx->pix_fmt = AV_PIX_FMT_VDPAU_VC1;
     }
 
b761659b
     //for advanced profile we may need to parse and unescape data
36ef5369
     if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
b761659b
         int buf_size2 = 0;
         buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
ac83d621
         if (!buf2)
             return AVERROR(ENOMEM);
b761659b
 
50f97219
         if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */
b761659b
             const uint8_t *start, *end, *next;
             int size;
 
             next = buf;
50f97219
             for (start = buf, end = buf + buf_size; next < end; start = next) {
b761659b
                 next = find_next_marker(start + 4, end);
                 size = next - start - 4;
50f97219
                 if (size <= 0) continue;
                 switch (AV_RB32(start)) {
b761659b
                 case VC1_CODE_FRAME:
a0c6c8e5
                     if (avctx->hwaccel ||
                         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
b761659b
                         buf_start = start;
                     buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
                     break;
cad16562
                 case VC1_CODE_FIELD: {
                     int buf_size3;
b87ff344
                     if (avctx->hwaccel ||
                         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
                         buf_start_second_field = start;
714f5ab5
                     tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
                     if (!tmp)
50f97219
                         goto err;
714f5ab5
                     slices = tmp;
cad16562
                     slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
50f97219
                     if (!slices[n_slices].buf)
                         goto err;
cad16562
                     buf_size3 = vc1_unescape_buffer(start + 4, size,
                                                     slices[n_slices].buf);
                     init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
                                   buf_size3 << 3);
                     /* assuming that the field marker is at the exact middle,
                        hope it's correct */
c9f72e4b
                     slices[n_slices].mby_start = s->mb_height + 1 >> 1;
cad16562
                     n_slices1 = n_slices - 1; // index of the last slice of the first field
                     n_slices++;
                     break;
                 }
b761659b
                 case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
                     buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
50f97219
                     init_get_bits(&s->gb, buf2, buf_size2 * 8);
5f2c159c
                     ff_vc1_decode_entry_point(avctx, v, &s->gb);
b761659b
                     break;
f44d6445
                 case VC1_CODE_SLICE: {
                     int buf_size3;
714f5ab5
                     tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
                     if (!tmp)
50f97219
                         goto err;
714f5ab5
                     slices = tmp;
f44d6445
                     slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
50f97219
                     if (!slices[n_slices].buf)
                         goto err;
f44d6445
                     buf_size3 = vc1_unescape_buffer(start + 4, size,
                                                     slices[n_slices].buf);
                     init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
                                   buf_size3 << 3);
                     slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);
                     n_slices++;
                     break;
                 }
b761659b
                 }
             }
50f97219
         } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */
b761659b
             const uint8_t *divider;
0a6aff69
             int buf_size3;
b761659b
 
             divider = find_next_marker(buf, buf + buf_size);
50f97219
             if ((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD) {
b761659b
                 av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");
b81a935b
                 goto err;
cad16562
             } else { // found field marker, unescape second field
b87ff344
                 if (avctx->hwaccel ||
                     s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
                     buf_start_second_field = divider;
0a6aff69
                 tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
                 if (!tmp)
                     goto err;
                 slices = tmp;
                 slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
                 if (!slices[n_slices].buf)
                     goto err;
                 buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf);
                 init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
                               buf_size3 << 3);
c9f72e4b
                 slices[n_slices].mby_start = s->mb_height + 1 >> 1;
0a6aff69
                 n_slices1 = n_slices - 1;
                 n_slices++;
b761659b
             }
             buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);
50f97219
         } else {
b761659b
             buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);
         }
         init_get_bits(&s->gb, buf2, buf_size2*8);
     } else
         init_get_bits(&s->gb, buf, buf_size*8);
768c5251
 
     if (v->res_sprite) {
50f97219
         v->new_sprite  = !get_bits1(&s->gb);
         v->two_sprites =  get_bits1(&s->gb);
36ef5369
         /* res_sprite means a Windows Media Image stream, AV_CODEC_ID_*IMAGE means
45ecda85
            we're using the sprite compositor. These are intentionally kept separate
            so you can get the raw sprites by using the wmv3 decoder for WMVP or
            the vc1 one for WVP2 */
36ef5369
         if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
45ecda85
             if (v->new_sprite) {
                 // switch AVCodecContext parameters to those of the sprites
                 avctx->width  = avctx->coded_width  = v->sprite_width;
                 avctx->height = avctx->coded_height = v->sprite_height;
             } else {
                 goto image;
             }
         }
768c5251
     }
 
d2f119a1
     if (s->context_initialized &&
         (s->width  != avctx->coded_width ||
          s->height != avctx->coded_height)) {
7627c35a
         ff_vc1_decode_end(avctx);
d2f119a1
     }
 
     if (!s->context_initialized) {
b772b0e2
         if (ff_msmpeg4_decode_init(avctx) < 0)
6f8ef532
             goto err;
b772b0e2
         if (ff_vc1_decode_init_alloc_tables(v) < 0) {
             ff_MPV_common_end(s);
             goto err;
         }
d2f119a1
 
         s->low_delay = !avctx->has_b_frames || v->res_sprite;
 
         if (v->profile == PROFILE_ADVANCED) {
ab8517b8
             if(avctx->coded_width<=1 || avctx->coded_height<=1)
                 goto err;
d2f119a1
             s->h_edge_pos = avctx->coded_width;
             s->v_edge_pos = avctx->coded_height;
         }
     }
 
b761659b
     // do parse frame header
cad16562
     v->pic_header_flag = 0;
7845f8d2
     v->first_pic_header_flag = 1;
50f97219
     if (v->profile < PROFILE_ADVANCED) {
e3bd6124
         if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
b81a935b
             goto err;
b761659b
         }
     } else {
e3bd6124
         if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
b81a935b
             goto err;
b761659b
         }
     }
7845f8d2
     v->first_pic_header_flag = 0;
b761659b
 
15e4bd65
     if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(v->s.avctx, AV_LOG_DEBUG, "pict_type: %c\n", av_get_picture_type_char(s->pict_type));
 
36ef5369
     if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
50f97219
         && s->pict_type != AV_PICTURE_TYPE_I) {
45ecda85
         av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
         goto err;
cba322d7
     }
 
b5f4836f
     if ((s->mb_height >> v->field_mode) == 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "image too short\n");
         goto err;
     }
 
8ed2ae09
     // for skipping the frame
657ccb5a
     s->current_picture.f.pict_type = s->pict_type;
     s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
b761659b
 
     /* skip B-frames if we don't have reference frames */
ba0c8981
     if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) {
4ddac719
         goto end;
b761659b
     }
50f97219
     if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||
         (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) ||
          avctx->skip_frame >= AVDISCARD_ALL) {
b81a935b
         goto end;
b761659b
     }
 
50f97219
     if (s->next_p_frame_damaged) {
         if (s->pict_type == AV_PICTURE_TYPE_B)
b81a935b
             goto end;
b761659b
         else
50f97219
             s->next_p_frame_damaged = 0;
b761659b
     }
 
efd29844
     if (ff_MPV_frame_start(s, avctx) < 0) {
b81a935b
         goto err;
b761659b
     }
 
85d51d8e
     v->s.current_picture_ptr->field_picture = v->field_mode;
14ac47fc
     v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE);
     v->s.current_picture_ptr->f.top_field_first  = v->tff;
 
ac1fc92e
     // process pulldown flags
     s->current_picture_ptr->f.repeat_pict = 0;
     // Pulldown flags are only valid when 'broadcast' has been set.
     // So ticks_per_frame will be 2
     if (v->rff) {
         // repeat field
         s->current_picture_ptr->f.repeat_pict = 1;
     } else if (v->rptfrm) {
         // repeat frames
         s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2;
     }
 
50f97219
     s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
     s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
b761659b
 
a0c6c8e5
     if ((CONFIG_VC1_VDPAU_DECODER)
         &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
         if (v->field_mode && buf_start_second_field) {
             ff_vdpau_vc1_decode_picture(s, buf_start, buf_start_second_field - buf_start);
             ff_vdpau_vc1_decode_picture(s, buf_start_second_field, (buf + buf_size) - buf_start_second_field);
         } else {
             ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
         }
     } else if (avctx->hwaccel) {
b87ff344
         if (v->field_mode && buf_start_second_field) {
             // decode first field
             s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
             if (avctx->hwaccel->start_frame(avctx, buf_start, buf_start_second_field - buf_start) < 0)
                 goto err;
             if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start) < 0)
                 goto err;
             if (avctx->hwaccel->end_frame(avctx) < 0)
                 goto err;
 
             // decode second field
             s->gb = slices[n_slices1 + 1].gb;
             s->picture_structure = PICT_TOP_FIELD + v->tff;
             v->second_field = 1;
             v->pic_header_flag = 0;
             if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "parsing header for second field failed");
                 goto err;
             }
             v->s.current_picture_ptr->f.pict_type = v->s.pict_type;
 
             if (avctx->hwaccel->start_frame(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field) < 0)
                 goto err;
             if (avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field) < 0)
                 goto err;
             if (avctx->hwaccel->end_frame(avctx) < 0)
                 goto err;
         } else {
             s->picture_structure = PICT_FRAME;
             if (avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
                 goto err;
             if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
                 goto err;
             if (avctx->hwaccel->end_frame(avctx) < 0)
                 goto err;
         }
b761659b
     } else {
ce153eef
         int header_ret = 0;
 
54974c62
         ff_mpeg_er_frame_start(s);
b761659b
 
         v->bits = buf_size * 8;
ee769c6a
         v->end_mb_x = s->mb_width;
cad16562
         if (v->field_mode) {
             s->current_picture.f.linesize[0] <<= 1;
             s->current_picture.f.linesize[1] <<= 1;
             s->current_picture.f.linesize[2] <<= 1;
50f97219
             s->linesize                      <<= 1;
             s->uvlinesize                    <<= 1;
cad16562
         }
         mb_height = s->mb_height >> v->field_mode;
43bacd5b
 
91062dde
         av_assert0 (mb_height > 0);
43bacd5b
 
f44d6445
         for (i = 0; i <= n_slices; i++) {
cad16562
             if (i > 0 &&  slices[i - 1].mby_start >= mb_height) {
1100acba
                 if (v->field_mode <= 0) {
                     av_log(v->s.avctx, AV_LOG_ERROR, "Slice %d starts beyond "
                            "picture boundary (%d >= %d)\n", i,
                            slices[i - 1].mby_start, mb_height);
5e59a77c
                     continue;
                 }
cad16562
                 v->second_field = 1;
017e234c
                 av_assert0((s->mb_height & 1) == 0);
131fac1c
                 v->blocks_off   = s->b8_stride * (s->mb_height&~1);
cad16562
                 v->mb_off       = s->mb_stride * s->mb_height >> 1;
             } else {
                 v->second_field = 0;
                 v->blocks_off   = 0;
                 v->mb_off       = 0;
             }
             if (i) {
                 v->pic_header_flag = 0;
1acc553e
                 if (v->field_mode && i == n_slices1 + 2) {
ce153eef
                     if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
0aa907cf
                         av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n");
23d6ba2c
                         if (avctx->err_recognition & AV_EF_EXPLODE)
                             goto err;
1acc553e
                         continue;
                     }
                 } else if (get_bits1(&s->gb)) {
cad16562
                     v->pic_header_flag = 1;
ce153eef
                     if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
0aa907cf
                         av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");
23d6ba2c
                         if (avctx->err_recognition & AV_EF_EXPLODE)
                             goto err;
1acc553e
                         continue;
                     }
cad16562
                 }
             }
ce153eef
             if (header_ret < 0)
                 continue;
cad16562
             s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height);
             if (!v->field_mode || v->second_field)
                 s->end_mb_y = (i == n_slices     ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
ccce723c
             else {
                 if (i >= n_slices) {
                     av_log(v->s.avctx, AV_LOG_ERROR, "first field slice count too large\n");
                     continue;
                 }
510ef04a
                 s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
ccce723c
             }
e985cfd1
             if (s->end_mb_y <= s->start_mb_y) {
                 av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y);
                 continue;
             }
cc548ea7
             if (!v->p_frame_skipped && s->pict_type != AV_PICTURE_TYPE_I && !v->cbpcy_vlc) {
                 av_log(v->s.avctx, AV_LOG_ERROR, "missing cbpcy_vlc\n");
                 continue;
             }
7627c35a
             ff_vc1_decode_blocks(v);
cad16562
             if (i != n_slices)
                 s->gb = slices[i].gb;
         }
         if (v->field_mode) {
             v->second_field = 0;
             s->current_picture.f.linesize[0] >>= 1;
             s->current_picture.f.linesize[1] >>= 1;
             s->current_picture.f.linesize[2] >>= 1;
50f97219
             s->linesize                      >>= 1;
             s->uvlinesize                    >>= 1;
3fdd0979
             if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) {
32a6dfeb
                 FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]);
                 FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]);
3fdd0979
             }
f44d6445
         }
1218777f
         av_dlog(s->avctx, "Consumed %i/%i bits\n",
                 get_bits_count(&s->gb), s->gb.size_in_bits);
50f97219
 //  if (get_bits_count(&s->gb) > buf_size * 8)
b761659b
 //      return -1;
1fad547c
         if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
9e794d10
             goto err;
46430fd4
         if (!v->field_mode)
1fad547c
             ff_er_frame_end(&s->er);
b761659b
     }
 
efd29844
     ff_MPV_frame_end(s);
b761659b
 
36ef5369
     if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
45ecda85
 image:
         avctx->width  = avctx->coded_width  = v->output_width;
         avctx->height = avctx->coded_height = v->output_height;
50f97219
         if (avctx->skip_frame >= AVDISCARD_NONREF)
             goto end;
45ecda85
 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
50f97219
         if (vc1_decode_sprites(v, &s->gb))
             goto err;
45ecda85
 #endif
6792559f
         if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)
759001c5
             goto err;
df9b9567
         *got_frame = 1;
45ecda85
     } else {
50f97219
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
759001c5
             if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
                 goto err;
53fd4f55
             ff_print_debug_info(s, s->current_picture_ptr, pict);
de4ec972
             *got_frame = 1;
50f97219
         } else if (s->last_picture_ptr != NULL) {
759001c5
             if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
                 goto err;
53fd4f55
             ff_print_debug_info(s, s->last_picture_ptr, pict);
df9b9567
             *got_frame = 1;
50f97219
         }
45ecda85
     }
 
b81a935b
 end:
b761659b
     av_free(buf2);
f44d6445
     for (i = 0; i < n_slices; i++)
         av_free(slices[i].buf);
     av_free(slices);
b761659b
     return buf_size;
b81a935b
 
 err:
     av_free(buf2);
f44d6445
     for (i = 0; i < n_slices; i++)
         av_free(slices[i].buf);
     av_free(slices);
b81a935b
     return -1;
b761659b
 }
 
 
0215006a
 static const AVProfile profiles[] = {
     { FF_PROFILE_VC1_SIMPLE,   "Simple"   },
     { FF_PROFILE_VC1_MAIN,     "Main"     },
     { FF_PROFILE_VC1_COMPLEX,  "Complex"  },
     { FF_PROFILE_VC1_ADVANCED, "Advanced" },
     { FF_PROFILE_UNKNOWN },
 };
b761659b
 
e2789d3e
 static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
 #if CONFIG_DXVA2
     AV_PIX_FMT_DXVA2_VLD,
 #endif
 #if CONFIG_VAAPI
     AV_PIX_FMT_VAAPI_VLD,
 #endif
 #if CONFIG_VDPAU
     AV_PIX_FMT_VDPAU,
 #endif
     AV_PIX_FMT_YUV420P,
     AV_PIX_FMT_NONE
 };
 
d36beb3f
 AVCodec ff_vc1_decoder = {
ec6402b7
     .name           = "vc1",
b2bed932
     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
ec6402b7
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_VC1,
ec6402b7
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
7627c35a
     .close          = ff_vc1_decode_end,
ec6402b7
     .decode         = vc1_decode_frame,
4dc8c838
     .flush          = ff_mpeg_flush,
ec6402b7
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
e2789d3e
     .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
50f97219
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
b761659b
 };
 
700363af
 #if CONFIG_WMV3_DECODER
d36beb3f
 AVCodec ff_wmv3_decoder = {
ec6402b7
     .name           = "wmv3",
b2bed932
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
ec6402b7
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_WMV3,
ec6402b7
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
7627c35a
     .close          = ff_vc1_decode_end,
ec6402b7
     .decode         = vc1_decode_frame,
4dc8c838
     .flush          = ff_mpeg_flush,
ec6402b7
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
e2789d3e
     .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
50f97219
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
b761659b
 };
700363af
 #endif
b761659b
 
a0c6c8e5
 #if CONFIG_WMV3_VDPAU_DECODER
 AVCodec ff_wmv3_vdpau_decoder = {
     .name           = "wmv3_vdpau",
b46f1910
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
a0c6c8e5
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV3,
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_WMV3, AV_PIX_FMT_NONE },
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 #endif
 
 #if CONFIG_VC1_VDPAU_DECODER
 AVCodec ff_vc1_vdpau_decoder = {
     .name           = "vc1_vdpau",
b46f1910
     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
a0c6c8e5
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VC1,
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_VC1, AV_PIX_FMT_NONE },
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 #endif
 
45ecda85
 #if CONFIG_WMV3IMAGE_DECODER
 AVCodec ff_wmv3image_decoder = {
     .name           = "wmv3image",
b2bed932
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
45ecda85
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_WMV3IMAGE,
45ecda85
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
7627c35a
     .close          = ff_vc1_decode_end,
45ecda85
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = vc1_sprite_flush,
     .pix_fmts       = ff_pixfmt_list_420
 };
 #endif
 
 #if CONFIG_VC1IMAGE_DECODER
 AVCodec ff_vc1image_decoder = {
     .name           = "vc1image",
b2bed932
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
45ecda85
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_VC1IMAGE,
45ecda85
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
7627c35a
     .close          = ff_vc1_decode_end,
45ecda85
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = vc1_sprite_flush,
     .pix_fmts       = ff_pixfmt_list_420
 };
 #endif