All pastes #978672 Raw Edit

Combing Detection

public diff v1 · immutable
·published 2008-04-09 19:00 UTC
rendered paste body
Index: libhb/deinterlace.c===================================================================--- libhb/deinterlace.c	(revision 1397)+++ libhb/deinterlace.c	(working copy)@@ -42,6 +42,14 @@     int              yadif_parity;     int              yadif_ready; +    int              comb;+    int              comb_detect;+    int              color_equal;+    int              color_diff;+    int              threshold;+    int              deinterlaced_frames;+    int              passed_frames;+     uint8_t        * yadif_ref[4][3];     int              yadif_ref_stride[3]; @@ -115,6 +123,26 @@     } } +static void yadif_get_ref( uint8_t ** pic, hb_filter_private_t * pv, int frm )+{+    int i;+    for( i = 0; i < 3; i++ )+    {+        uint8_t * dst = pic[i];+        const uint8_t * ref = pv->yadif_ref[frm][i];+        int w = pv->width[i];+        int ref_stride = pv->yadif_ref_stride[i];+        +        int y;+        for( y = 0; y < pv->height[i]; y++ )+        {+            memcpy(dst, ref, w);+            dst += w;+            ref += ref_stride;+        }+    }+}+ static void yadif_filter_line( uint8_t *dst,                                uint8_t *prev,                                uint8_t *cur,@@ -356,6 +384,13 @@     pv->buf_out[1] = hb_buffer_init( buf_size );     pv->buf_settings = hb_buffer_init( 0 ); +    pv->deinterlaced_frames = 0;+    pv->passed_frames = 0;+    pv->comb_detect = 0;+    pv->color_equal = 10;+    pv->color_diff = 30;+    pv->threshold = 9;+     pv->yadif_ready    = 0;     pv->yadif_mode     = YADIF_MODE_DEFAULT;     pv->yadif_parity   = YADIF_PARITY_DEFAULT;@@ -365,11 +400,15 @@      if( settings )     {-        sscanf( settings, "%d:%d:%d:%d",+        sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d",                 &pv->yadif_mode,                 &pv->yadif_parity,                 &pv->mcdeint_mode,-                &pv->mcdeint_qp );+                &pv->mcdeint_qp,+                &pv->comb_detect,+                &pv->color_equal,+                &pv->color_diff,+                &pv->threshold );     }      /* Allocate yadif specific buffers */@@ -451,6 +490,8 @@         return;     } +    hb_log("deinterlacer: filtered %i | unfiltered %i | total %i", pv->deinterlaced_frames, pv->passed_frames, pv->deinterlaced_frames + pv->passed_frames);+     /* Cleanup frame buffers */     if( pv->buf_out[0] )     {@@ -521,13 +562,31 @@         avpicture_fill( &pv->pic_out, pv->buf_out[0]->data,                         pix_fmt, width, height ); -        avpicture_deinterlace( &pv->pic_out, &pv->pic_in,-                               pix_fmt, width, height );+        /* Check for combing on the input frame */+        int interlaced = pv->comb_detect ? ( hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold)) : 1;+        +        if(interlaced)+        {+            avpicture_deinterlace( &pv->pic_out, &pv->pic_in,+                                   pix_fmt, width, height ); -        hb_buffer_copy_settings( pv->buf_out[0], buf_in );+            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 );+            *buf_out = pv->buf_out[0];            +        }+        else+        {+            /* No combing detected, pass input frame through unmolested.*/+            +            pv->passed_frames++;+            +            hb_buffer_copy_settings( pv->buf_out[0], buf_in );+            *buf_out = buf_in;+            +        } -        *buf_out = pv->buf_out[0];-         return FILTER_OK;     } @@ -545,6 +604,9 @@     /* Store current frame in yadif cache */     yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv ); +    /* Note down if the input frame is combed */+    pv->comb = (pv->comb << 1) | ( pv->comb_detect? hb_detect_comb(buf_in, width, height, pv->color_equal, pv->color_diff, pv->threshold) : 1);+     /* If yadif is not ready, store another ref and return FILTER_DELAY */     if( pv->yadif_ready == 0 )     {@@ -560,30 +622,47 @@         return FILTER_DELAY;     } -    /* Perform yadif and mcdeint filtering */-    int frame;-    for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )+    /* yadif & mcdeint work one frame behind so if the previous frame+     * had combing, deinterlace it otherwise just output it. */+    if(  (pv->comb & 2 ) == 0 )     {-        int parity = frame ^ tff ^ 1;+        /* previous frame not interlaced - copy cached input frame to buf_out */+        +        pv->passed_frames++;+        +        avpicture_fill( &pv->pic_out,  pv->buf_out[0]->data, pix_fmt, width, height );+        yadif_get_ref( (uint8_t**)pv->pic_out.data, pv, 1 );+        *buf_out = pv->buf_out[0];+    }+    else+    {+        /* Perform yadif and mcdeint filtering */+        +        pv->deinterlaced_frames++;+        int frame;+        for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )+        {+            int parity = frame ^ tff ^ 1; -        avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,-                        pix_fmt, width, height );--        yadif_filter( pv->pic_out.data, parity, tff, pv );--        if( pv->mcdeint_mode >= 0 )-        {-            avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data,+            avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,                             pix_fmt, width, height ); -            mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );+            yadif_filter( pv->pic_out.data, parity, tff, pv ); -            *buf_out = pv->buf_out[ (frame^1)];+            if( pv->mcdeint_mode >= 0 )+            {+                avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data,+                                pix_fmt, width, height );+    +                mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );+    +                *buf_out = pv->buf_out[ (frame^1)];+            }+            else+            {+                *buf_out = pv->buf_out[!(frame^1)];+            }         }-        else-        {-            *buf_out = pv->buf_out[!(frame^1)];-        }     }      /* Copy buffered settings to output buffer settings */Index: libhb/hb.c===================================================================--- libhb/hb.c	(revision 1397)+++ libhb/hb.c	(working copy)@@ -518,22 +518,29 @@         flag[k] = 0;         if ( cc[k] > threshold )         {+//            hb_log("Threhold %i: %i/%i | PTS: %lld (%fs)", k, cc[k], threshold, buf->start, (float)buf->start / 90000 );             flag[k] = 1;         }     }  #if 0 /* Debugging info */-//    if(flag)+    if(flag[0] || flag[1] || flag[2])         hb_log("flags: %i/%i/%i | cc0: %i | cc1: %i | cc2: %i", flag[0], flag[1], flag[2], cc[0], cc[1], cc[2]); #endif -    /* When more than one plane shows combing, tell the caller. */-    if (flag[0] || flag[1] || flag[2] )+    /* For progressive frames, require the luma and one chroma plane to show combing. */+    if( (buf->flags & 16) && flag[0] && ( flag[1] || flag[2] ) )     {         return 1;     } +    /* For video frames, when more than one plane shows combing, tell the caller. */+    if ( !(buf->flags & 16) && (flag[0] || flag[1] || flag[2]) )+    {+        return 1;+    }+     return 0; }