All pastes #1037592 Raw Edit

Yadif threading with fifo

public diff v1 · immutable
#1037592 ·published 2008-06-03 07:39 UTC
rendered paste body
Index: 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 */