All pastes #1035209 Raw Edit

tritical comb detection

public diff v1 · immutable
#1035209 ·published 2008-05-31 19:54 UTC
rendered paste body
Index: libhb/decomb.c===================================================================--- libhb/decomb.c	(revision 1474)+++ libhb/decomb.c	(working copy)@@ -230,6 +230,205 @@     } } +int tritical_detect_comb( hb_filter_private_t * pv )+{+    int x, y, i, j, k;+    +    /* Motion threshold */+    int mthresh = 6;+    /* Spatial threshold */+    int athresh = 15;+    /* Block mask threshold -- The number of pixels+       in a 4x8 block of the mask that need to show+       combing for the whole frame to be seen as such. */+    int threshold = 15;+    +    int color_equal = 10;+    int color_diff = 15;+    +    /* Make a buffer to store a comb mask. */+    uint8_t        * mask[3];+    for( i = 0; i < 3; i++ )+    {+        int is_chroma = !!i;+        int w = ((pv->width[0]   + 31) & (~31))>>is_chroma;+        int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;++        mask[i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;+    }+    +    /* One pas for Y, one pass for Cb, one pass for Cr */    +    for( k = 0; k < 1; k++ )+    {+        int ref_stride = pv->ref_stride[k];+        int width = pv->width[k];+        int height = pv->height[k];++        for( y = 2; y < (height-2); y++ )+        {+            /* These are just to make the buffer locations easier to read. */+            int back_2 = y - 2;+            int back_1 = y - 1;+            int forward_1 = y + 1;+            int forward_2 = y + 2;+            +            /* We need to examine a column of 5 pixels+               in the prev, cur, and next frames.      */+            uint8_t frame_a[5];+            uint8_t frame_b[5];+            uint8_t frame_c[5];+            +            for( x = 0; x < width; x++ )+            {+                /* Fill up the frame arrays with the current pixel values.*/+                frame_a[0] = pv->ref[0][k][back_2*ref_stride + x];+                frame_a[1] = pv->ref[0][k][back_1*ref_stride + x];+                frame_a[2] = pv->ref[0][k][y*ref_stride + x];+                frame_a[3] = pv->ref[0][k][forward_1*ref_stride + x];+                frame_a[4] = pv->ref[0][k][forward_2*ref_stride + x];+                frame_b[0] = pv->ref[1][k][back_2*ref_stride + x];+                frame_b[1] = pv->ref[1][k][back_1*ref_stride + x];+                frame_b[2] = pv->ref[1][k][y*ref_stride + x];+                frame_b[3] = pv->ref[1][k][forward_1*ref_stride + x];+                frame_b[4] = pv->ref[1][k][forward_2*ref_stride + x];+                frame_c[0] = pv->ref[2][k][back_2*ref_stride + x];+                frame_c[1] = pv->ref[2][k][back_1*ref_stride + x];+                frame_c[2] = pv->ref[2][k][y*ref_stride + x];+                frame_c[3] = pv->ref[2][k][forward_1*ref_stride + x];+                frame_c[4] = pv->ref[2][k][forward_2*ref_stride + x];+                +                /* Make sure there's sufficient motion between frame t-1 to frame t+1. */+                int motion = 0;+                if( abs(frame_a[2] - frame_b[2] ) > mthresh && abs(frame_b[1] - frame_c[1] ) > mthresh && abs(frame_b[3] - frame_c[3] ) > mthresh )+                    motion++;+                if( abs(frame_c[2] - frame_b[2] ) > mthresh && abs(frame_a[1] - frame_b[1] ) > mthresh && abs(frame_a[3] - frame_b[3] ) > mthresh )+                    motion++;++#if 0+                /* Visualizes the pixel values being examined. */+                hb_log("\n PLANE: %i X: %i Y: %i \n %i %i %i \n %i %i %i \n %i %i %i \n %i %i %i \n %i %i %i", k, x, y,+                frame_a[0], frame_b[0], frame_c[0],+                frame_a[1], frame_b[1], frame_c[1],+                frame_a[2], frame_b[2], frame_c[2],+                frame_a[3], frame_b[3], frame_c[3],+                frame_a[4], frame_b[4], frame_c[4] );+#endif+                if( motion )+                {+                    /* There is movement in this pixel location. */+                    if( ( frame_b[1] - frame_b[2] ) * ( frame_b[3] - frame_b[2] ) > 0 )+                    {+                        /* The pixel above and below are different,+                           and are so in the same "direction" too.+                           That means it's time for the spatial check. */+                        +                        /* Simple 32detect style comb detection */+                        if( ( abs( frame_b[2] - frame_b[4] ) < color_equal  ) &&+                            ( abs( frame_b[2] - frame_b[3] ) > color_diff ) )+                        {+                            mask[k][y*ref_stride + x] = 255;+                        }+                        else+                        {+                            mask[k][y*ref_stride + x] = 0;+                        }+                        +#if 0+                        /* The combing check is done on a bob+blur convolution. */+                        int combing = abs(  frame_b[0] + (4 * frame_b[2] ) + frame_b[4] - (3 * ( frame_b[1] + frame_b[3] ) ) );++                        /* If the frame is sufficiently combed,+                           then mark it down on the mask as 255. */+                       if( combing > 6*athresh )+                            mask[k][y*ref_stride + x] = 255; +                        else+                            mask[k][y*ref_stride + x] = 0;+#endif++#if 0+                        /* This, for comparison, is what IsCombed uses.+                           It's simpler, but more noise senstive.      */+                           int combing = (frame_b[1] - frame_b[2]) * (frame_b[3] - frame_b[2]);+                           if( combing > 20 )+                               mask[k][y*ref_stride + x] = 255; +                           else+                               mask[k][y*ref_stride + x] = 0;+#endif+                    }+                    else+                    {+                        mask[k][y*ref_stride + x] = 0;+                    }+                }+                else+                {+                    mask[k][y*ref_stride + x] = 0;+                }+            }+        }+    }+    +    /* Go through the mask in 4x8 blocks. If any of these windows+       have threshold or more combed pixels, consider the whole+       frame to be combed and send it on to be deinterlaced.     */+    int block_score = 0;+    for(k = 0; k < 1; k++ )+    {+        int ref_stride = pv->ref_stride[k];        +        for( y = 0; y < ( pv->height[k] - 8 ); y = y + 8 )+        {+            for( x = 0; x < ( pv->width[k] - 4 ); x = x + 4 )+            {+                int block_x;+                int block_y;+                block_score = 0;+                for(block_y = 0; block_y < 8; block_y++ )+                {+                    for(block_x = 0; block_x < 4; block_x++ )+                    {+                        int mask_y = y + block_y;+                        int mask_x = x + block_x;+                        +                        if( mask[k][mask_y*ref_stride+mask_x] == 255 )+                        {+                            block_score++;+                        }+                    }+                }+                +                if( block_score >= threshold )+                {+                    /* Consider this frame to be combed.+                       Clear the mask buffer and return 1. */+                    for( i = 0; i<3*3; i++ )+                    {+                        uint8_t **p = &mask[i/3];+                        if (*p)+                        {+                            free( *p - 3*pv->ref_stride[i/3] );+                            *p = NULL;+                        }+                    }+                    return 1;+                }+            }+        } +    }+    +    /* Consider this frame to be uncombed.+       Clear the mask buffer and return 0. */+    for( i = 0; i<3*3; i++ )+    {+        uint8_t **p = &mask[i/3];+        if (*p)+        {+            free( *p - 3*pv->ref_stride[i/3] );+            *p = NULL;+        }+    }+    return 0;+}+ static void yadif_filter_line( uint8_t *dst,                                uint8_t *prev,                                uint8_t *cur,@@ -376,7 +575,17 @@                           int tff,                           hb_filter_private_t * pv ) {-+    +    int is_combed = tritical_detect_comb( pv );+    +    if(is_combed)+    {+        pv->deinterlaced_frames++;+    }+    else+    {+        pv->passed_frames++;+    } #if 0     /* Buggy, experimental code for macroblock-by-macroblock decombing.*/     if( pv->mode == 7 )@@ -499,7 +708,7 @@                  blend_filter_line( dst2, cur, i, y, pv );             }-            else if( (y ^ parity) &  1 )+            else if( (y ^ parity) &  1 && is_combed )             {                 uint8_t *prev = &pv->ref[0][i][y*ref_stride];                 uint8_t *cur  = &pv->ref[1][i][y*ref_stride];@@ -850,14 +1059,14 @@                         pix_fmt, width, height );          /* Check for combing on the input frame */-        int interlaced =  hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold, pv->prog_equal, pv->prog_diff, pv->prog_threshold);+                    int interlaced = 1; // hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold, pv->prog_equal, pv->prog_diff, pv->prog_threshold);                  if(interlaced)         {             avpicture_deinterlace( &pv->pic_out, &pv->pic_in,                                    pix_fmt, width, height ); -            pv->deinterlaced_frames++;+//            pv->deinterlaced_frames++;             //hb_log("Frame %i is combed (Progressive: %s )", pv->deinterlaced_frames + pv->passed_frames, (buf_in->flags & 16) ? "Y" : "N");                          hb_buffer_copy_settings( pv->buf_out[0], buf_in );@@ -867,7 +1076,7 @@         {             /* No combing detected, pass input frame through unmolested.*/             -            pv->passed_frames++;+ //           pv->passed_frames++;                          hb_buffer_copy_settings( pv->buf_out[0], buf_in );             *buf_out = buf_in;@@ -894,7 +1103,7 @@     if( pv->mode < 7 )     {         /* Note down if the input frame is combed */-        pv->comb = (pv->comb << 1) | hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold, pv->prog_equal, pv->prog_diff, pv->prog_threshold);+        pv->comb = (pv->comb << 1) | 1; //hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold, pv->prog_equal, pv->prog_diff, pv->prog_threshold);     }      /* If yadif is not ready, store another ref and return FILTER_DELAY */@@ -918,7 +1127,7 @@     {         /* Perform yadif filtering */         -        pv->deinterlaced_frames++;+//        pv->deinterlaced_frames++;         int frame;         for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 5 )? 1 : 0 ) ; frame++ )         {@@ -955,7 +1164,7 @@     {         /* Perform yadif filtering */         -        pv->deinterlaced_frames++;+//        pv->deinterlaced_frames++;         int frame;         for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 5 )? 1 : 0 ) ; frame++ )         {