diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index f2f5c7f88b..7d6d5c781c 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -1328,16 +1328,6 @@ static int vc1_decode_p_mb(VC1Context *v)
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             v->block[v->cur_blk_idx][i][j] <<= 1;
-                    s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i],
-                                                      s->dest[dst_idx] + off,
-                                                      i & 4 ? s->uvlinesize
-                                                            : s->linesize);
-                    if (v->pq >= 9 && v->overlap) {
-                        if (v->c_avail)
-                            v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
-                        if (v->a_avail)
-                            v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
-                    }
                     block_cbp   |= 0xF << (i << 2);
                     block_intra |= 1 << i;
                 } else if (val) {
@@ -1439,16 +1429,6 @@ static int vc1_decode_p_mb(VC1Context *v)
                     if (v->rangeredfrm)
                         for (j = 0; j < 64; j++)
                             v->block[v->cur_blk_idx][i][j] <<= 1;
-                    s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i],
-                                                      s->dest[dst_idx] + off,
-                                                      (i & 4) ? s->uvlinesize
-                                                              : s->linesize);
-                    if (v->pq >= 9 && v->overlap) {
-                        if (v->c_avail)
-                            v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
-                        if (v->a_avail)
-                            v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
-                    }
                     block_cbp   |= 0xF << (i << 2);
                     block_intra |= 1 << i;
                 } else if (is_coded[i]) {
@@ -1479,6 +1459,10 @@ static int vc1_decode_p_mb(VC1Context *v)
         }
     }
 end:
+    if (v->overlap && v->pq >= 9)
+        ff_vc1_p_overlap_filter(v);
+    vc1_put_signed_blocks_clamped(v);
+
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
     v->is_intra[s->mb_x] = block_intra;
@@ -1506,7 +1490,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
     int skipped, fourmv = 0, twomv = 0;
     int block_cbp = 0, pat, block_tt = 0;
     int idx_mbmode = 0, mvbp;
-    int stride_y, fieldtx;
+    int fieldtx;
 
     mquant = v->pq; /* Lossy initialization */
 
@@ -1584,17 +1568,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
                 if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
                     continue;
                 v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]);
-                if (i < 4) {
-                    stride_y = s->linesize << fieldtx;
+                if (i < 4)
                     off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
-                } else {
-                    stride_y = s->uvlinesize;
+                else
                     off = 0;
-                }
-                s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i],
-                                                  s->dest[dst_idx] + off,
-                                                  stride_y);
-                //TODO: loop filter
                 block_cbp |= 0xf << (i << 2);
             }
 
@@ -1693,6 +1670,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
         ff_vc1_mc_1mv(v, 0);
         v->fieldtx_plane[mb_pos] = 0;
     }
+    if (v->overlap && v->pq >= 9)
+        ff_vc1_p_overlap_filter(v);
+    vc1_put_signed_blocks_clamped(v);
+
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
 
@@ -1754,11 +1735,6 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
                 continue;
             v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]);
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
-            s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i],
-                                              s->dest[dst_idx] + off,
-                                              (i & 4) ? s->uvlinesize
-                                                      : s->linesize);
-            // TODO: loop filter
             block_cbp |= 0xf << (i << 2);
         }
     } else {
@@ -1814,6 +1790,10 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
             }
         }
     }
+    if (v->overlap && v->pq >= 9)
+        ff_vc1_p_overlap_filter(v);
+    vc1_put_signed_blocks_clamped(v);
+
     v->cbp[s->mb_x]      = block_cbp;
     v->ttblk[s->mb_x]    = block_tt;
 
@@ -2040,7 +2020,6 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
                                               s->dest[dst_idx] + off,
                                               (i & 4) ? s->uvlinesize
                                                       : s->linesize);
-            // TODO: yet to perform loop filter
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
@@ -2734,10 +2713,11 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
                 v->vc1dsp.vc1_inv_trans_8x8(block[k]);
             }
 
-            ff_vc1_smooth_overlap_filter_iblk(v);
+            if (v->overlap && v->condover != CONDOVER_NONE)
+                ff_vc1_i_overlap_filter(v);
             vc1_put_signed_blocks_clamped(v);
             if (v->s.loop_filter)
-                ff_vc1_loop_filter_iblk_delayed(v, v->pq);
+                ff_vc1_i_loop_filter(v);
 
             if (get_bits_count(&s->gb) > v->bits) {
                 // TODO: may need modification to handle slice coding
@@ -2758,19 +2738,6 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
         s->first_slice_line = 0;
     }
 
-    /* raw bottom MB row */
-    s->mb_x = 0;
-    init_block_index(v);
-    for (; s->mb_x < s->mb_width; s->mb_x++) {
-        ff_update_block_index(s);
-        vc1_put_signed_blocks_clamped(v);
-        if (v->s.loop_filter)
-            ff_vc1_loop_filter_iblk_delayed(v, v->pq);
-        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);
-    }
     if (v->s.loop_filter)
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
     ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
@@ -2807,8 +2774,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
         break;
     }
 
-    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
-                          v->fcm == PROGRESSIVE;
+    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
     s->first_slice_line = 1;
     memset(v->cbp_base, 0, sizeof(v->cbp_base[0]) * 3 * s->mb_stride);
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
@@ -2817,13 +2783,19 @@ static void vc1_decode_p_blocks(VC1Context *v)
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
-            if (v->fcm == ILACE_FIELD)
+            if (v->fcm == ILACE_FIELD) {
                 vc1_decode_p_mb_intfi(v);
-            else if (v->fcm == ILACE_FRAME)
+                if (apply_loop_filter)
+                    ff_vc1_p_loop_filter(v);
+            } else if (v->fcm == ILACE_FRAME) {
                 vc1_decode_p_mb_intfr(v);
-            else vc1_decode_p_mb(v);
-            if (s->mb_y != s->start_mb_y && apply_loop_filter)
-                ff_vc1_apply_p_loop_filter(v);
+                if (apply_loop_filter)
+                    ff_vc1_p_intfr_loop_filter(v);
+            } else {
+                vc1_decode_p_mb(v);
+                if (apply_loop_filter)
+                    ff_vc1_p_loop_filter(v);
+            }
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
                 ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
@@ -2852,14 +2824,6 @@ static void vc1_decode_p_blocks(VC1Context *v)
             ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
-    if (apply_loop_filter) {
-        s->mb_x = 0;
-        init_block_index(v);
-        for (; s->mb_x < s->mb_width; s->mb_x++) {
-            ff_update_block_index(s);
-            ff_vc1_apply_p_loop_filter(v);
-        }
-    }
     if (s->end_mb_y >= s->start_mb_y)
         ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
     ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
@@ -2902,12 +2866,19 @@ static void vc1_decode_b_blocks(VC1Context *v)
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
-            if (v->fcm == ILACE_FIELD)
+            if (v->fcm == ILACE_FIELD) {
                 vc1_decode_b_mb_intfi(v);
-            else if (v->fcm == ILACE_FRAME)
+                if (v->s.loop_filter)
+                    ff_vc1_b_intfi_loop_filter(v);
+            } else if (v->fcm == ILACE_FRAME) {
                 vc1_decode_b_mb_intfr(v);
-            else
+                if (v->s.loop_filter)
+                    ff_vc1_p_intfr_loop_filter(v);
+            } else {
                 vc1_decode_b_mb(v);
+                if (v->s.loop_filter)
+                    ff_vc1_i_loop_filter(v);
+            }
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
                 ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
@@ -2915,8 +2886,6 @@ static void vc1_decode_b_blocks(VC1Context *v)
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
                 return;
             }
-            if (v->s.loop_filter)
-                ff_vc1_loop_filter_iblk(v, v->pq);
         }
         memmove(v->cbp_base,
                 v->cbp - s->mb_stride,
diff --git a/tests/ref/fate/vc1_ilaced_twomv b/tests/ref/fate/vc1_ilaced_twomv
index 4dd5a40d74..096e5fc87b 100644
--- a/tests/ref/fate/vc1_ilaced_twomv
+++ b/tests/ref/fate/vc1_ilaced_twomv
@@ -3,16 +3,16 @@
 #codec_id 0: rawvideo
 #dimensions 0: 1920x1080
 #sar 0: 1/1
-0,          0,          0,        1,  3110400, 0x764f8856
-0,          2,          2,        1,  3110400, 0x3b615b79
-0,          3,          3,        1,  3110400, 0x4fbb6f84
-0,          4,          4,        1,  3110400, 0xc1ca8532
-0,          5,          5,        1,  3110400, 0xbdabd2a8
-0,          6,          6,        1,  3110400, 0x66e60c5a
-0,          7,          7,        1,  3110400, 0x8044891c
-0,          8,          8,        1,  3110400, 0x3a4e8992
-0,          9,          9,        1,  3110400, 0xe49fcb23
-0,         10,         10,        1,  3110400, 0xe8e165b6
-0,         11,         11,        1,  3110400, 0x046321b5
-0,         12,         12,        1,  3110400, 0x3cbe5125
-0,         13,         13,        1,  3110400, 0xcb4328e7
+0,          0,          0,        1,  3110400, 0xc95e8861
+0,          2,          2,        1,  3110400, 0xf58b5cbf
+0,          3,          3,        1,  3110400, 0x2f866f33
+0,          4,          4,        1,  3110400, 0x05c18415
+0,          5,          5,        1,  3110400, 0x4077ca93
+0,          6,          6,        1,  3110400, 0x44d105fc
+0,          7,          7,        1,  3110400, 0xa0608374
+0,          8,          8,        1,  3110400, 0x407689dc
+0,          9,          9,        1,  3110400, 0x4707d00a
+0,         10,         10,        1,  3110400, 0x74986831
+0,         11,         11,        1,  3110400, 0xa5912619
+0,         12,         12,        1,  3110400, 0x44aa5565
+0,         13,         13,        1,  3110400, 0xb9752774
diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143
index d6904819d0..db89cc9e41 100644
--- a/tests/ref/fate/vc1_sa10143
+++ b/tests/ref/fate/vc1_sa10143
@@ -3,33 +3,33 @@
 #codec_id 0: rawvideo
 #dimensions 0: 720x480
 #sar 0: 1/1
-0,          0,          0,        1,   518400, 0x89407f55
-0,          2,          2,        1,   518400, 0xaa896afd
-0,          3,          3,        1,   518400, 0x0e69ff59
-0,          4,          4,        1,   518400, 0x0c30bfa0
-0,          5,          5,        1,   518400, 0x1a5b6a69
-0,          6,          6,        1,   518400, 0x23470858
-0,          7,          7,        1,   518400, 0x9a4e3c54
-0,          8,          8,        1,   518400, 0xad63160b
-0,          9,          9,        1,   518400, 0x0fcfeebc
-0,         10,         10,        1,   518400, 0x20b31777
-0,         11,         11,        1,   518400, 0x9d79df09
-0,         12,         12,        1,   518400, 0x3e86766f
-0,         13,         13,        1,   518400, 0x638a8746
-0,         14,         14,        1,   518400, 0x7a6c1a0e
-0,         15,         15,        1,   518400, 0x306f6cef
-0,         16,         16,        1,   518400, 0x81f81281
-0,         17,         17,        1,   518400, 0x49ab5bf5
-0,         18,         18,        1,   518400, 0x8f316e44
-0,         19,         19,        1,   518400, 0x95ae00c9
-0,         20,         20,        1,   518400, 0xf71bb7f5
-0,         21,         21,        1,   518400, 0x5205ea68
-0,         22,         22,        1,   518400, 0x74a1d8b9
-0,         23,         23,        1,   518400, 0xa3217616
-0,         24,         24,        1,   518400, 0x2b28bbf8
-0,         25,         25,        1,   518400, 0xf024872a
-0,         26,         26,        1,   518400, 0x2fdbaaf3
-0,         27,         27,        1,   518400, 0xa3a2418e
-0,         28,         28,        1,   518400, 0x55bfe435
-0,         29,         29,        1,   518400, 0x50fb6c94
-0,         30,         30,        1,   518400, 0x5584bb40
+0,          0,          0,        1,   518400, 0x34fa7f55
+0,          2,          2,        1,   518400, 0x60466bc1
+0,          3,          3,        1,   518400, 0xe68dff1e
+0,          4,          4,        1,   518400, 0x790ac06a
+0,          5,          5,        1,   518400, 0xb3b26b27
+0,          6,          6,        1,   518400, 0x8840096c
+0,          7,          7,        1,   518400, 0xf75c3d61
+0,          8,          8,        1,   518400, 0xca071781
+0,          9,          9,        1,   518400, 0xa8e6edf9
+0,         10,         10,        1,   518400, 0xabb61984
+0,         11,         11,        1,   518400, 0x0b31dedd
+0,         12,         12,        1,   518400, 0xf44378ef
+0,         13,         13,        1,   518400, 0xf7268996
+0,         14,         14,        1,   518400, 0x8c5b1ff4
+0,         15,         15,        1,   518400, 0xda356fd2
+0,         16,         16,        1,   518400, 0x0e091c57
+0,         17,         17,        1,   518400, 0x17645e68
+0,         18,         18,        1,   518400, 0xf47a71ef
+0,         19,         19,        1,   518400, 0x6c440498
+0,         20,         20,        1,   518400, 0xd705bd32
+0,         21,         21,        1,   518400, 0x0800edd0
+0,         22,         22,        1,   518400, 0x902be119
+0,         23,         23,        1,   518400, 0x0f7d7bc4
+0,         24,         24,        1,   518400, 0x9f4dc421
+0,         25,         25,        1,   518400, 0x3b8c8d5a
+0,         26,         26,        1,   518400, 0xbcdfb2b9
+0,         27,         27,        1,   518400, 0xa02a46c3
+0,         28,         28,        1,   518400, 0x8ecde915
+0,         29,         29,        1,   518400, 0x20576bfd
+0,         30,         30,        1,   518400, 0xac40bc36
