rendered paste bodyIndex: libhb/deinterlace.c===================================================================--- libhb/deinterlace.c (revision 1487)+++ libhb/deinterlace.c (working copy)@@ -34,6 +34,7 @@ struct hb_filter_private_s {+ int cpu_count; int pix_fmt; int width[3]; int height[3];@@ -45,6 +46,10 @@ uint8_t * yadif_ref[4][3]; int yadif_ref_stride[3]; + hb_thread_t ** yadif_threads;+ hb_fifo_t * yadif_fifo;+ hb_lock_t ** yadif_locks;+ int mcdeint_mode; int mcdeint_qp; @@ -84,6 +89,14 @@ hb_deinterlace_close, }; +typedef struct yadif_arguments_s {+ uint8_t **dst;+ int parity;+ int tff;+ int plane;+ int y;+} yadif_arguments_t;+ static void yadif_store_ref( const uint8_t ** pic, hb_filter_private_t * pv ) {@@ -102,7 +115,6 @@ uint8_t * ref = pv->yadif_ref[2][i]; int w = pv->width[i];- int h = pv->height[i]; int ref_stride = pv->yadif_ref_stride[i]; int y;@@ -185,40 +197,115 @@ } } -static void yadif_filter( uint8_t ** dst,- int parity,- int tff,- hb_filter_private_t * pv )+void yadif_filter_segment( void *pv_v ) {- int i;- for( i = 0; i < 3; i++ )+ hb_buffer_t *yadif_job;+ yadif_arguments_t *segment_data = NULL;+ hb_filter_private_t * pv = pv_v;+ int run = 1;++ while( run ) {- int w = pv->width[i];- int h = pv->height[i];- int ref_stride = pv->yadif_ref_stride[i];+ yadif_job = hb_fifo_see( pv->yadif_fifo ); - int y;- for( y = 0; y < h; y++ )+ if( yadif_job == NULL ) {- if( (y ^ parity) & 1 )+ /*+ * No work to do - try again in a moment+ */+ hb_snooze( 5 );+ continue;+ } else {+ + if( yadif_job->size == 0 ) {- uint8_t *prev = &pv->yadif_ref[0][i][y*ref_stride];- uint8_t *cur = &pv->yadif_ref[1][i][y*ref_stride];- uint8_t *next = &pv->yadif_ref[2][i][y*ref_stride];- uint8_t *dst2 = &dst[i][y*w];+ run = 0;+ continue;+ } - yadif_filter_line( dst2, prev, cur, next, i, parity ^ tff, pv );- }- else+ yadif_job = hb_fifo_get( pv->yadif_fifo );+ segment_data = (yadif_arguments_t*)yadif_job->data;+ uint8_t **dst = segment_data->dst;+ int parity = segment_data->parity;+ int tff = segment_data->tff;+ int i = segment_data->plane;+ hb_filter_private_t * pv = pv_v;+ int y;+ + int w = pv->width[i];+ int h = pv->height[i];+ int ref_stride = pv->yadif_ref_stride[i];++ for( y = 0 ; y < h; y++ ) {- memcpy( &dst[i][y*w],- &pv->yadif_ref[1][i][y*ref_stride],- w * sizeof(uint8_t) );+ if( (y ^ parity) & 1 )+ {+ uint8_t *prev = &pv->yadif_ref[0][i][y*ref_stride];+ uint8_t *cur = &pv->yadif_ref[1][i][y*ref_stride];+ uint8_t *next = &pv->yadif_ref[2][i][y*ref_stride];+ uint8_t *dst2 = &dst[i][y*w];+ + yadif_filter_line( dst2, + prev, + cur, + next, + i, + parity ^ tff, + pv );+ + }+ else+ {+ memcpy( &dst[i][y*w],+ &pv->yadif_ref[1][i][y*ref_stride],+ w * sizeof(uint8_t) );+ } }+ hb_buffer_close( &yadif_job );+ hb_unlock( pv->yadif_locks[i] ); } } } ++static void yadif_filter( uint8_t ** dst,+ int parity,+ int tff,+ hb_filter_private_t * pv )+{++ int thread_count = 3;+ hb_buffer_t * yadif_job;+ yadif_arguments_t * arguments;++ int i;+ for( i = 0; i < thread_count; i++)+ { + yadif_job = hb_buffer_init( sizeof( yadif_arguments_t ) );+ arguments = (yadif_arguments_t*)yadif_job->data;++ arguments->parity = parity;+ arguments->tff = tff;+ arguments->dst = dst;+ arguments->plane = i;++ hb_lock( pv->yadif_locks[i] );+ hb_fifo_push( pv->yadif_fifo, yadif_job );+ }++ /*+ * wait until all threads have completed by trying to get the same+ * lock as we locked earlier for each thread, which will block until+ * that thread has completed the work on that segment.+ */+ for( i = 0; i < thread_count; i++ )+ {+ hb_lock( pv->yadif_locks[i] );+ hb_unlock( pv->yadif_locks[i] );+ }++}+ static void mcdeint_filter( uint8_t ** dst, uint8_t ** src, int parity,@@ -344,6 +431,8 @@ hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) ); + pv->cpu_count = hb_get_cpu_count();+ pv->pix_fmt = pix_fmt; pv->width[0] = width;@@ -389,6 +478,23 @@ pv->yadif_ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w; } }++ pv->yadif_fifo = hb_fifo_init( 5 );++ /*+ * Create threads.+ */+ pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * 3 );+ pv->yadif_locks = malloc( sizeof(hb_lock_t* ) * 3 );++ for( i = 0; i < 3; i++ )+ {+ pv->yadif_threads[i] = hb_thread_init( "yadif_segment",+ yadif_filter_segment,+ pv,+ HB_NORMAL_PRIORITY );+ pv->yadif_locks[i] = hb_lock_init();+ } } /* Allocate mcdeint specific buffers */@@ -478,6 +584,24 @@ *p = NULL; } }++ for( i = 0; i < 3; i++)+ {+ /*+ * Send an empty buffer into the fifo to release the threads+ * from their loops.+ */+ hb_buffer_t *kill_em;+ kill_em = hb_buffer_init( 0 );+ hb_fifo_push( pv->yadif_fifo, kill_em );+ hb_thread_close( &pv->yadif_threads[i] );+ hb_lock_close( &pv->yadif_locks[i] );+ }++ /*+ * TODO Need to free fifo as well.+ */+ free(pv->yadif_threads); } /* Cleanup mcdeint specific buffers */