]> granicus.if.org Git - handbrake/commitdiff
decomb: fix color distortion in last row of image
authorjstebbins <jstebbins.hb@gmail.com>
Mon, 1 Jun 2015 21:11:37 +0000 (21:11 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Mon, 1 Jun 2015 21:11:37 +0000 (21:11 +0000)
Prevent blending uninitialized lines of data into last row.

git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.10.x@7262 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/decomb.c

index ac1e533f33ed7fd77e8746cf6c9740692f9f5fda..c2852812b81e400386fedbc2330d9d30f1c2fe44 100644 (file)
@@ -2025,7 +2025,9 @@ static int hb_decomb_init( hb_filter_object_t * filter,
 
     // Make segment sizes an even number of lines
     int height = hb_image_height(init->pix_fmt, init->height, 0);
-    pv->segment_height[0] = (height / pv->cpu_count) & ~1;
+    // Each segment must begin on the even "parity" row.
+    // I.e. each segment of each plane must begin on an even row.
+    pv->segment_height[0] = (height / pv->cpu_count) & ~3;
     pv->segment_height[1] = hb_image_height(init->pix_fmt, pv->segment_height[0], 1);
     pv->segment_height[2] = hb_image_height(init->pix_fmt, pv->segment_height[0], 2);
 
@@ -2090,8 +2092,8 @@ static int hb_decomb_init( hb_filter_object_t * filter,
                  * Final segment
                  */
                 thread_args->segment_height[pp] =
-                    (hb_image_height(init->pix_fmt, init->height, pp) -
-                    thread_args->segment_start[pp] + 3) & ~3;
+                    ((hb_image_height(init->pix_fmt, init->height, pp)
+                     + 3) & ~3) - thread_args->segment_start[pp];
             } else {
                 thread_args->segment_height[pp] = pv->segment_height[pp];
             }
@@ -2509,6 +2511,28 @@ static void hb_decomb_close( hb_filter_object_t * filter )
     filter->private_data = NULL;
 }
 
+// Fill rows above height with copy of last row to prevent color distortion
+// during blending
+static void fill_stride(hb_buffer_t * buf)
+{
+    int pp, ii;
+
+    for (pp = 0; pp < 3; pp++)
+    {
+        uint8_t * src, * dst;
+
+        src = buf->plane[pp].data + (buf->plane[pp].height - 1) *
+              buf->plane[pp].stride;
+        dst = buf->plane[pp].data + buf->plane[pp].height *
+              buf->plane[pp].stride;
+        for (ii = 0; ii < 3; ii++)
+        {
+            memcpy(dst, src, buf->plane[pp].stride);
+            dst += buf->plane[pp].stride;
+        }
+    }
+}
+
 static int hb_decomb_work( hb_filter_object_t * filter,
                            hb_buffer_t ** buf_in,
                            hb_buffer_t ** buf_out )
@@ -2526,6 +2550,7 @@ static int hb_decomb_work( hb_filter_object_t * filter,
 
     /* Store current frame in yadif cache */
     *buf_in = NULL;
+    fill_stride(in);
     store_ref(pv, in);
 
     // yadif requires 3 buffers, prev, cur, and next.  For the first