rendered paste bodyIndex: 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; }