rendered paste bodyIndex: libhb/deinterlace.c===================================================================--- libhb/deinterlace.c (revision 1252)+++ 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, @@ -520,13 +541,28 @@ { avpicture_fill( &pv->pic_out, pv->buf_out[0]->data, pix_fmt, width, height );- - avpicture_deinterlace( &pv->pic_out, &pv->pic_in, ++ int interlaced = ( hb_detect_comb(buf_in, width, height) );++ if( interlaced )+ {+// hb_log("found combing! %i", interlaced);+ + 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+ {+ + hb_buffer_copy_settings( pv->buf_out[0], buf_in );++ *buf_out = buf_in;+ } return FILTER_OK; }@@ -544,6 +580,7 @@ /* Store current frame in yadif cache */ yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );+ 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 )@@ -551,50 +588,63 @@ 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;+ /* 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 */+// hb_log("combing detected, passing to yadif"); - 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 )+ 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/hb.c===================================================================--- libhb/hb.c (revision 1252)+++ libhb/hb.c (working copy)@@ -427,6 +427,88 @@ } /**+ * 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)+{+ /* See if frame shows interlacing */+ 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;+ + int thres = THRESHOLD;+ int eq = COLOR_EQUAL;+ int diff = COLOR_DIFF;+ + int offset = 0;+ + flag = 0;++ for(k=0; k < 3; k++)+ {+ if( k == 1 )+ {+ offset = width * height;+ width >>= 1;+ height >>= 1;+ thres >>= 1;+ eq >>= 1;+ diff >>= 1;+ }+ else if (k == 2 )+ {+ offset *= 5/4;+ }+ + block = width;+ + for(j=0; j<block; ++j)+ {+ off=0;+ + for(n=0; n<(height-4); n=n+2)+ {+ 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);+ + if((abs(s1 - s3) < eq) &&+ (abs(s1 - s2) > diff)) ++cc_1;+ + if((abs(s2 - s4) < eq) &&+ (abs(s2 - s3) > diff)) ++cc_2;+ + off +=2*block;+ }+ }+ + // compare results+ + cc = (int)((cc_1 + cc_2)*1000.0/(width*height));++ flag += (cc > thres) ? 1:0;+ }+ + 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);+ + if (flag > 1) + return 1;+ else+ return 0;+}+++/** * Calculates job width and height for anamorphic content, * * @param job Handle to hb_job_tIndex: libhb/hb.h===================================================================--- libhb/hb.h (revision 1252)+++ 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+#define COLOR_DIFF 30+#define THRESHOLD 2+ void hb_get_preview( hb_handle_t *, hb_title_t *, int, uint8_t * ); void hb_set_size( hb_job_t *, int ratio, int pixels );