shithub: dav1d

Download patch

ref: 9d1fcef36abdfae1fb8d9dc1b5e7f8b8cbb5b600
parent: aec3d25c6be14b06c6fc6de3eb70dc92faaac0fc
author: David Michael Barr <b@rr-dav.id.au>
date: Sat Oct 6 15:18:38 EDT 2018

Loop filter: mask with exact image width in MI

This resolves a mismatch for libaom test vectors:
av1-1-b8-01-size-$SIZE.ivf
Where SIZE is in:
 18x64  196x196 196x198 196x200 196x202 196x210 196x224 196x226 202x196
202x198 202x200 202x208 202x210 202x224 202x226 210x196 210x198 210x200
210x202 210x208 210x210 210x224 210x226 226x196 226x198 226x200 226x202
226x210 226x224 226x226  66x18   66x32

Helped-by: Ronald S. Bultje <rsbultje@gmail.com>

--- a/src/decode.c
+++ b/src/decode.c
@@ -1099,7 +1099,8 @@
         dav1d_create_lf_mask_intra(t->lf_mask, f->lf.level, f->b4_stride,
                                    &f->frame_hdr, (const uint8_t (*)[8][2])
                                    &ts->lflvl[b->seg_id][0][0][0],
-                                   t->bx, t->by, f->bw, f->bh, bs,
+                                   t->bx, t->by, (f->cur.p.p.w + 3) >> 2,
+                                   (f->cur.p.p.h + 3) >> 2, bs,
                                    b->tx, b->uvtx, f->cur.p.p.layout,
                                    &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
                                    has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
@@ -1694,7 +1695,9 @@
             &ts->lflvl[b->seg_id][0][b->ref[0] + 1][!is_globalmv];
         dav1d_create_lf_mask_inter(t->lf_mask, f->lf.level, f->b4_stride,
                                    &f->frame_hdr, lf_lvls, t->bx, t->by,
-                                   f->bw, f->bh, b->skip, bs, b->tx_split,
+                                   (f->cur.p.p.w + 3) >> 2,
+                                   (f->cur.p.p.h + 3) >> 2,
+                                   b->skip, bs, b->tx_split,
                                    b->uvtx, f->cur.p.p.layout,
                                    &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
                                    has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
--- a/src/lf_mask.c
+++ b/src/lf_mask.c
@@ -245,27 +245,32 @@
     const int bx4 = bx & 31;
     const int by4 = by & 31;
 
-    uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
-    for (int y = 0; y < bh4; y++) {
-        for (int x = 0; x < bw4; x++) {
-            level_cache_ptr[x][0] = filter_level[0][0][0];
-            level_cache_ptr[x][1] = filter_level[1][0][0];
+    if (bw4 && bh4) {
+        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
+        for (int y = 0; y < bh4; y++) {
+            for (int x = 0; x < bw4; x++) {
+                level_cache_ptr[x][0] = filter_level[0][0][0];
+                level_cache_ptr[x][1] = filter_level[1][0][0];
+            }
+            level_cache_ptr += b4_stride;
         }
-        level_cache_ptr += b4_stride;
+
+        mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
     }
 
-    mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
-
     if (!auv) return;
 
     const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
     const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
-    const int cbw4 = (bw4 + ss_hor) >> ss_hor;
-    const int cbh4 = (bh4 + ss_ver) >> ss_ver;
+    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
+                          (b_dim[0] + ss_hor) >> ss_hor);
+    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
+                          (b_dim[1] + ss_ver) >> ss_ver);
     const int cbx4 = bx4 >> ss_hor;
     const int cby4 = by4 >> ss_ver;
 
-    level_cache_ptr = level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
+    uint8_t (*level_cache_ptr)[4] =
+        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
     for (int y = 0; y < cbh4; y++) {
         for (int x = 0; x < cbw4; x++) {
             level_cache_ptr[x][2] = filter_level[2][0][0];
@@ -300,28 +305,33 @@
     const int bx4 = bx & 31;
     const int by4 = by & 31;
 
-    uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
-    for (int y = 0; y < bh4; y++) {
-        for (int x = 0; x < bw4; x++) {
-            level_cache_ptr[x][0] = filter_level[0][0][0];
-            level_cache_ptr[x][1] = filter_level[1][0][0];
+    if (bw4 && bh4) {
+        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
+        for (int y = 0; y < bh4; y++) {
+            for (int x = 0; x < bw4; x++) {
+                level_cache_ptr[x][0] = filter_level[0][0][0];
+                level_cache_ptr[x][1] = filter_level[1][0][0];
+            }
+            level_cache_ptr += b4_stride;
         }
-        level_cache_ptr += b4_stride;
+
+        mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
+                         dav1d_max_txfm_size_for_bs[bs][0], tx_masks, ay, ly);
     }
 
-    mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
-                     dav1d_max_txfm_size_for_bs[bs][0], tx_masks, ay, ly);
-
     if (!auv) return;
 
     const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
     const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
-    const int cbw4 = (bw4 + ss_hor) >> ss_hor;
-    const int cbh4 = (bh4 + ss_ver) >> ss_ver;
+    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
+                          (b_dim[0] + ss_hor) >> ss_hor);
+    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
+                          (b_dim[1] + ss_ver) >> ss_ver);
     const int cbx4 = bx4 >> ss_hor;
     const int cby4 = by4 >> ss_ver;
 
-    level_cache_ptr = level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
+    uint8_t (*level_cache_ptr)[4] =
+        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
     for (int y = 0; y < cbh4; y++) {
         for (int x = 0; x < cbw4; x++) {
             level_cache_ptr[x][2] = filter_level[2][0][0];