All pastes #911473 Raw Edit

Unnamed

public diff v1 · immutable
·published 2008-02-20 18:54 UTC
rendered paste body
Index: test/test.c===================================================================--- test/test.c	(revision 1306)+++ test/test.c	(working copy)@@ -300,6 +300,12 @@         fprintf( stderr, "    + %d, %s (iso639-2: %s)\n", i + 1, subtitle->lang,             subtitle->iso639_2);     }+    +    if(title->detected_interlacing)+    {+        /* Interlacing was found in 6 or more preview frames */+        fprintf( stderr, "  + interlacing artifacts detected\n");+    } }  static int HandleEvents( hb_handle_t * h )Index: libhb/hb.c===================================================================--- libhb/hb.c	(revision 1306)+++ libhb/hb.c	(working copy)@@ -427,6 +427,109 @@ }  /**+ * Analyzes a frame to detect interlacing artifacts+ * and returns true if interlacing (combing) is found.+ *+ * Code taken from Thomas Oestreich's 32detect filter+ * in the Transcode project, with minor formatting changes.+ *+ * @param buf An hb_buffer structure holding valid frame data.+ * @param width The frame's width in pixels.+ * @param height The frame's height in pixels.+ */+int hb_detect_comb( hb_buffer_t * buf, int width, int height)+{+    int j, k, n, off, block, cc_1, cc_2, cc, flag;+    uint16_t s1, s2, s3, s4;+    cc = 0; cc_1 = 0; cc_2 = 0;+    +    /* These values are defined in hb.h */+    int thres = THRESHOLD;+    int eq = COLOR_EQUAL;+    int diff = COLOR_DIFF;+    +    int offset = 0;+    +    flag = 0;++    for(k=0; k < 3; k++)+    {+        /* One pas for Y, one pass for Cb, one pass for Cr */+        if( k == 1 )+        {+            /* Y has already been checked, now offset by Y's dimensions+               and divide all the other values by 2, since Cr and Cb+               are half-size compared to Y.                               */+            offset = width * height;+            width >>= 1;+            height >>= 1;+            thres >>= 1;+            eq >>= 1;+            diff >>= 1;+        }+        else if (k == 2 )+        {+            /* Y and Cb are done, so the offset needs to be bumped+               so it's width*height + (width / 2) * (height / 2)  */+            offset *= 5/4;+        }+        +        /* Look at one horizontal line at a time */+        block = width;+        +        for(j=0; j<block; ++j)+        {+            off=0;+            +            for(n=0; n<(height-4); n=n+2)+            {+                /* Look at groups of 4 sequential horizontal lines */+                s1 = ((buf->data+offset)[off+j        ] & 0xff);+                s2 = ((buf->data+offset)[off+j+  block] & 0xff);+                s3 = ((buf->data+offset)[off+j+2*block] & 0xff);+                s4 = ((buf->data+offset)[off+j+3*block] & 0xff);+                +                /* Note if the 1st and 2nd lines are more different in+                   color than the 1st and 3rd lines are similar in color.*/+                if((abs(s1 - s3) < eq) &&+                    (abs(s1 - s2) > diff)) ++cc_1;+    +                /* Note if the 2nd and 3rd lines are more different in+                   color than the 2nd and 4th lines are similar in color.*/+                if((abs(s2 - s4) < eq) &&+                    (abs(s2 - s3) > diff)) ++cc_2;+                +                /* Now move down 2 horizontal lines before starting over.*/+                off +=2*block;+            }+        }+        +        // compare results+        /* The final metric seems to be doing some kind of bits per pixel style calculation+           to decide whether or not enough lines showed alternating colors for the frame size. */+        cc = (int)((cc_1 + cc_2)*1000.0/(width*height));+        +        /* But only really flag the plane as showing interlacing when it exceeds a threshold parameter.*/+        flag += (cc > thres) ? 1:0;+    }++#if 0+/* Debugging info */+    if(flag)+        hb_log("flag: %i | cc: %f | cc1: %i | cc2: %i", flag, (float)((cc_1 + cc_2)*1000.0/(width*height)), cc_1, cc_2);+#endif+    +    /* When more than one plane shows combing, tell the caller. */+    if (flag > 1)+    {+        return 1;+    }++    return 0;+}+++/**  * Calculates job width and height for anamorphic content,  *  * @param job Handle to hb_job_tIndex: libhb/hb.h===================================================================--- libhb/hb.h	(revision 1306)+++ libhb/hb.h	(working copy)@@ -75,6 +75,14 @@    Returns the list of valid titles detected by the latest scan. */ hb_list_t   * hb_get_titles( hb_handle_t * ); +/* hb_detect_comb()+   Analyze a frame for interlacing artifacts, returns true if they're found.+   Taken from Thomas Oestreich's 32detect filter in the Transcode project.  */+int hb_detect_comb( hb_buffer_t * buf, int width, int height);+#define COLOR_EQUAL  10 // Sensitivity for detecting similar colors.+#define COLOR_DIFF   30 // Sensitivity for detecting different colors+#define THRESHOLD     2 // Sensitivity for flagging planes as combed+ void          hb_get_preview( hb_handle_t *, hb_title_t *, int,                               uint8_t * ); void          hb_set_size( hb_job_t *, int ratio, int pixels );Index: libhb/deinterlace.c===================================================================--- libhb/deinterlace.c	(revision 1306)+++ libhb/deinterlace.c	(working copy)@@ -41,6 +41,7 @@     int              yadif_mode;     int              yadif_parity;     int              yadif_ready;+    int              comb;          uint8_t        * yadif_ref[4][3];             int              yadif_ref_stride[3];@@ -115,6 +116,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, @@ -521,12 +542,30 @@         avpicture_fill( &pv->pic_out, pv->buf_out[0]->data,                          pix_fmt, width, height );         -        avpicture_deinterlace( &pv->pic_out, &pv->pic_in, +        /* Check for coming on the input frame */+        int interlaced = ( hb_detect_comb(buf_in, width, height) );++        if( interlaced )+        {+            /* Combing detected, deinterlace this frame. */+#if 0+            hb_log("found combing! %i", interlaced);+#endif            +            avpicture_deinterlace( &pv->pic_out, &pv->pic_in,                                 pix_fmt, width, height );-        -        hb_buffer_copy_settings( pv->buf_out[0], buf_in );+            +            hb_buffer_copy_settings( pv->buf_out[0], buf_in );+            +            *buf_out = pv->buf_out[0]; -        *buf_out = pv->buf_out[0];+        }+        else+        {+            /* No combing detected, pass input frame through unmolested.*/+            hb_buffer_copy_settings( pv->buf_out[0], buf_in );++            *buf_out = buf_in;+        }                  return FILTER_OK;     }@@ -545,56 +584,73 @@     /* 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) | hb_detect_comb(buf_in, width, height);+         /* If yadif is not ready, store another ref and return FILTER_DELAY */     if( pv->yadif_ready == 0 )     {         yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );                  hb_buffer_copy_settings( pv->buf_settings, buf_in );--        /* don't let 'work_loop' send a chapter mark upstream */-        buf_in->new_chap  = 0; +        /* don't let 'work_loop' send a chapter mark upstream */+        buf_in->new_chap  = 0;+         pv->yadif_ready = 1;                  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;-        -        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 )+        /* previous frame not interlaced - copy cached input frame to buf_out */+        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 */+#if 0+        hb_log("combing detected, passing to yadif");+#endif        +        int frame;+        for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )         {-            avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data, +            int parity = frame ^ tff ^ 1;+            +            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 );-            -            *buf_out = pv->buf_out[ (frame^1)];+    +            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, +                                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 */     hb_buffer_copy_settings( *buf_out, pv->buf_settings );          /* Replace buffered settings with input buffer settings */     hb_buffer_copy_settings( pv->buf_settings, buf_in );    --    /* don't let 'work_loop' send a chapter mark upstream */-    buf_in->new_chap  = 0; +    /* don't let 'work_loop' send a chapter mark upstream */+    buf_in->new_chap  = 0;+     return FILTER_OK; } Index: libhb/scan.c===================================================================--- libhb/scan.c	(revision 1306)+++ libhb/scan.c	(working copy)@@ -286,6 +286,7 @@     hb_list_t     * list_es, * list_raw;     hb_libmpeg2_t * mpeg2;     int progressive_count = 0;+    int interlacing[10];          buf_ps   = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );     list_es  = hb_list_init();@@ -407,7 +408,7 @@                 */                 if( progressive_count == 6 )                 {-                    hb_log("Title's mostly progressive NTSC, setting fps to 23.976");+                    hb_log("Title's mostly NTSC Film, setting fps to 23.976");                 }                 title->rate_base = 1126125;                            }@@ -440,7 +441,18 @@         }          buf_raw = hb_list_item( list_raw, 0 );-+        +        /* Check preview for interlacing artifacts */+        if( hb_detect_comb(buf_raw, title->width, title->height))+        {+            hb_log("Interlacing detected in preview frame %i", i);+            interlacing[i] = 1;+        }+        else+        {+            interlacing[i] = 0;+        }+                 hb_get_tempory_filename( data->h, filename, "%x%d",                                  (intptr_t)title, i ); @@ -493,7 +505,7 @@                     break;                 }         }-+         skip_preview:         while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )         {@@ -506,12 +518,32 @@     title->crop[1] = EVEN( title->crop[1] );     title->crop[2] = EVEN( title->crop[2] );     title->crop[3] = EVEN( title->crop[3] );-+         hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",             title->width, title->height, (float) title->rate /             (float) title->rate_base, title->crop[0], title->crop[1],             title->crop[2], title->crop[3] );+            +    /* Add up how many previews were interlaced.*/+    int interlacing_sum, t;+    for(t = 0; t < 10; t++ )+    {+        if( interlacing[t] == 1 )+        {+            interlacing_sum++;+        }+    } +    if( interlacing_sum >= 6)+    {+        hb_log("Title is mostly interlaced or telecined (%i out of 10 previews). You should do something about that.", interlacing_sum);+        title->detected_interlacing = 1;+    }+    else+    {+        title->detected_interlacing = 0;+    }+         ret = 1;     goto cleanup; Index: libhb/common.h===================================================================--- libhb/common.h	(revision 1306)+++ libhb/common.h	(working copy)@@ -435,6 +435,8 @@      /* Job template for this title */     hb_job_t  * job;+    +    int         detected_interlacing; };