OSDN Git Service

Added buffer management and changed fifo sizes. Changed job->subtitle_scan to job...
authoreddyg <eddyg@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 11 Sep 2007 06:02:07 +0000 (06:02 +0000)
committereddyg <eddyg@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 11 Sep 2007 06:02:07 +0000 (06:02 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@945 b64f7644-9d1e-0410-96f1-a4d463321fa5

12 files changed:
libhb/common.h
libhb/decsub.c
libhb/denoise.c
libhb/fifo.c
libhb/hb.c
libhb/internal.h
libhb/reader.c
libhb/render.c
libhb/stream.c
libhb/work.c
macosx/Controller.mm
test/test.c

index f32c620..e719591 100644 (file)
@@ -258,7 +258,7 @@ struct hb_job_s
     int             largeFileSize;
     
 
-    int subtitle_scan;
+    int indepth_scan;
     hb_subtitle_t ** select_subtitle;
     int subtitle_force;
     char * native_language;
index eb3b35a..2b76ecf 100644 (file)
@@ -177,7 +177,7 @@ static void ParseControls( hb_work_object_t * w )
                     /*
                      * If we are doing a subtitle scan then note down
                      */
-                    if( job->subtitle_scan )
+                    if( job->indepth_scan )
                     {
                         for( n=0; n < hb_list_count(title->list_subtitle); n++ ) 
                         {
@@ -198,8 +198,8 @@ static void ParseControls( hb_work_object_t * w )
                     break;
 
                 case 0x02: // 0x02 - STP_DSP - Stop Display, no arguments
-                                       if(!pv->pts_stop)
-                                               pv->pts_stop = pv->pts + date * 900;
+                    if(!pv->pts_stop)
+                        pv->pts_stop = pv->pts + date * 900;
                     break;
 
                 case 0x03: // 0x03 - SET_COLOR - Set Colour indices
@@ -463,7 +463,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
     /* Get infos about the subtitle */
     ParseControls( w );
 
-    if( job->subtitle_scan || ( job->subtitle_force && pv->pts_forced == 0 ) )
+    if( job->indepth_scan || ( job->subtitle_force && pv->pts_forced == 0 ) )
     {
         /*
          * Don't encode subtitles when doing a scan.
index 5022d47..70902a6 100644 (file)
@@ -304,6 +304,11 @@ hb_filter_private_t * hb_denoise_init( int pix_fmt,
     }
     
     hb_filter_private_t * pv = malloc( sizeof(struct hb_filter_private_s) );
+
+    /*
+     * Clear the memory to avoid freeing uninitialised memory later.
+     */
+    memset( pv, 0, sizeof( struct hb_filter_private_s ) );
     
     pv->pix_fmt  = pix_fmt;    
     pv->width[0]  = width;
index 44c64d9..a36bb77 100644 (file)
 #include <malloc.h>
 #endif
 
-hb_buffer_t * hb_buffer_init( int size )
+/* Fifo */
+struct hb_fifo_s
 {
-    hb_buffer_t * b;
+    hb_lock_t    * lock;
+    int            capacity;
+    int            size;
+    int            buffer_size;
+    hb_buffer_t  * first;
+    hb_buffer_t  * last;
+};
+
+#define MAX_BUFFER_POOLS  15
+#define BUFFER_POOL_MAX_ELEMENTS 2048
+
+struct hb_buffer_pools_s
+{
+    int entries;
+    int allocated;
+    hb_fifo_t *pool[MAX_BUFFER_POOLS];
+    hb_lock_t *lock;
+};
+
+struct hb_buffer_pools_s buffers;
+
+void hb_buffer_pool_init( void )
+{
+    hb_fifo_t *buffer_pool;
+    int size = 512;
+    int max_size = 32768;;
+
+    buffers.entries = 0;
+    buffers.lock = hb_lock_init();
+    buffers.allocated = 0;
     
+    while(size <= max_size) {
+        buffer_pool = buffers.pool[buffers.entries++] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS);
+        buffer_pool->buffer_size = size;
+        size *= 2;
+    }
+}
+
+void hb_buffer_pool_free( void )
+{
+    int i;
+    int count;
+    int freed = 0;
+    hb_buffer_t *b;
+
+    hb_lock(buffers.lock);
+
+    for( i = 0; i < buffers.entries; i++) 
+    {
+        count = 0;
+        while( ( b = hb_fifo_get(buffers.pool[i]) ) )
+        {
+            freed += b->alloc;
+            if( b->data )
+            {
+                free( b->data );
+                b->data = NULL;
+            }
+            free( b );
+            count++;
+        }
+        hb_log("Freed %d buffers of size %d", count, buffers.pool[i]->buffer_size);
+    }
+
+    hb_log("Allocated %d bytes of buffers on this pass and Freed %d bytes, %d bytes leaked",
+           buffers.allocated, freed, buffers.allocated - freed);
+    buffers.allocated = 0;
+    hb_unlock(buffers.lock);
+}
+
+
+hb_buffer_t * hb_buffer_init( int size )
+{ 
+    hb_buffer_t * b;
+    int i;
+    hb_fifo_t *buffer_pool = NULL;
+    uint8_t *data;
+    int b_alloc;
+    int resize = 0;
+
+    /*
+     * The buffer pools are allocated in increasing size
+     */
+    for( i = 0; i < buffers.entries; i++ )
+    {
+        if( buffers.pool[i]->buffer_size >= size )
+        {
+            /*
+             * This pool is big enough, but are there any buffers in it?
+             */
+            if( hb_fifo_size( buffers.pool[i] ) ) 
+            {
+                /*
+                 * We've found a matching buffer pool, with buffers.
+                 */
+                buffer_pool = buffers.pool[i];
+                resize =  buffers.pool[i]->buffer_size;
+            } else {
+                /*
+                 * Buffer pool is empty, 
+                 */
+                if( resize ) {
+                    /*
+                     * This is the second time through, so break out of here to avoid
+                     * using too large a buffer for a small job.
+                     */
+                    break;
+                }
+                resize =  buffers.pool[i]->buffer_size;
+            }
+        }
+    }
+
+    /*
+     * Don't reuse the 0 size buffers, not much gain.
+     */
+    if( size != 0 && buffer_pool )
+    {
+        b = hb_fifo_get( buffer_pool );    
+
+        if( b )
+        {
+            /*
+             * Zero the contents of the buffer, would be nice if we
+             * didn't have to do this.
+             *
+            hb_log("Reused buffer size %d for size %d from pool %d depth %d", 
+                   b->alloc, size, smallest_pool->buffer_size, 
+                   hb_fifo_size(smallest_pool));
+            */
+            data = b->data;
+            b_alloc = b->alloc;
+            memset( b, 0, sizeof(hb_buffer_t) );
+            b->alloc = b_alloc;
+            b->size = size;
+            b->data = data;
+            return( b );
+        } 
+    }
+
+    /*
+     * No existing buffers, create a new one
+     */
     if( !( b = calloc( sizeof( hb_buffer_t ), 1 ) ) )
     {
         hb_log( "out of memory" );
         return NULL;
     }
 
-    b->alloc = size;
     b->size  = size;
+
+    if( resize )
+    {
+        size = resize;
+    } 
+    b->alloc  = size;  
+
+    /*
+    hb_log("Allocating new buffer of size %d for size %d", 
+           b->alloc, 
+           b->size);
+    */
+
     if (!size)
         return b;
 #if defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
-    b->data  = malloc( size );
+    b->data  = malloc( b->alloc );
 #elif defined( SYS_CYGWIN )
     /* FIXME */
-    b->data  = malloc( size + 17 );
+    b->data  = malloc( b->alloc + 17 );
 #else
-    b->data  = memalign( 16, size );
+    b->data  = memalign( 16, b->alloc );
 #endif
 
     if( !b->data )
@@ -39,27 +193,122 @@ hb_buffer_t * hb_buffer_init( int size )
         free( b );
         return NULL;
     }
+
+    buffers.allocated += b->alloc;
+
     return b;
 }
 
 void hb_buffer_realloc( hb_buffer_t * b, int size )
 {
     /* No more alignment, but we don't care */
+    if( size < 2048 ) {
+        size = 2048;
+    }
     b->data  = realloc( b->data, size );
+    buffers.allocated -= b->alloc;
     b->alloc = size;
+    buffers.allocated += b->alloc;
 }
 
 void hb_buffer_close( hb_buffer_t ** _b )
 {
     hb_buffer_t * b = *_b;
+    hb_fifo_t *buffer_pool = NULL;
+    int i;
+
+    /*
+     * Put the buffer into our free list in the matching buffer pool, if there is one.
+     */
+    if( b->alloc != 0 )
+    {
+        for( i = 0; i < buffers.entries; i++ )
+        {
+            if( b->alloc == buffers.pool[i]->buffer_size )
+            { 
+                buffer_pool = buffers.pool[i];
+                break;
+            }
+        }
+    }
 
-    if( b->data )
+    if( buffer_pool ) 
     {
-        free( b->data );
+        if( !hb_fifo_is_full( buffer_pool ) ) 
+        {
+            if(b->data)
+            {
+                /*
+                hb_log("Putting a buffer of size %d on pool %d, depth %d",
+                       b->alloc, 
+                       buffer_pool->buffer_size, 
+                       hb_fifo_size(buffer_pool));
+                */
+                hb_fifo_push( buffer_pool, b );
+            } else {
+                free(b);
+            }
+        } else {
+            /*
+             * Got a load of these size ones already, free this buffer.
+             *
+            hb_log("Buffer pool for size %d full, freeing buffer", b->alloc);
+            */
+            if( b->data )
+            {
+                free( b->data );
+            }
+            buffers.allocated -= b->alloc;
+            free( b );
+        }
+    } else {
+        /*
+         * Need a new buffer pool for this size.
+         */
+        hb_lock(buffers.lock);
+        if ( b->alloc != 0 && buffers.entries < MAX_BUFFER_POOLS)
+        {
+            buffer_pool = buffers.pool[buffers.entries++] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS);
+            buffer_pool->buffer_size = b->alloc;
+            hb_fifo_push( buffer_pool, b );
+            /*
+            hb_log("*** Allocated a new buffer pool for size %d [%d]", b->alloc,
+                   buffers.entries );
+            */
+        } else {
+            if( b->alloc != 0 )
+            {
+                for( i = buffers.entries-1; i >= 0; i-- )
+                {
+                    if( hb_fifo_size(buffers.pool[i]) == 0 )
+                    {
+                        /*
+                         * Reuse this pool as it is empty.
+                         */
+                        buffers.pool[i]->buffer_size = b->alloc;
+                        hb_fifo_push( buffers.pool[i], b );
+                        b = NULL;
+                        break;
+                    }
+                }
+            }
+
+            if( b )
+            {
+                if( b->data )
+                {
+                    free( b->data );
+                    b->data = NULL;
+                    buffers.allocated -= b->alloc;
+                }
+                free( b );
+            }
+        }
+        hb_unlock(buffers.lock);
     }
-    free( b );
 
     *_b = NULL;
+
 }
 
 void hb_buffer_copy_settings( hb_buffer_t * dst, const hb_buffer_t * src )
@@ -71,22 +320,13 @@ void hb_buffer_copy_settings( hb_buffer_t * dst, const hb_buffer_t * src )
     dst->flags     = src->flags;
 }
 
-/* Fifo */
-struct hb_fifo_s
-{
-    hb_lock_t    * lock;
-    int            capacity;
-    int            size;
-    hb_buffer_t  * first;
-    hb_buffer_t  * last;
-};
-
 hb_fifo_t * hb_fifo_init( int capacity )
 {
     hb_fifo_t * f;
     f           = calloc( sizeof( hb_fifo_t ), 1 );
     f->lock     = hb_lock_init();
     f->capacity = capacity;
+    f->buffer_size = 0;
     return f;
 }
 
index fbcd810..7a15a11 100644 (file)
@@ -104,6 +104,11 @@ hb_handle_t * hb_init_real( int verbose, int update_check )
         }
     }
 
+    /*
+     * Initialise buffer pool
+     */
+    hb_buffer_pool_init();
+
     /* CPU count detection */
     hb_log( "hb_init: checking cpu count" );
     h->cpu_count = hb_get_cpu_count();
@@ -607,7 +612,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
      */
     memset( audio_lang, 0, sizeof( audio_lang ) );
 
-    if ( job->subtitle_scan || job->native_language ) {
+    if ( job->indepth_scan || job->native_language ) {
       
         /*
          * Find the first audio language that is being encoded
@@ -659,7 +664,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
      * If doing a subtitle scan then add all the matching subtitles for this
      * language.
      */
-    if ( job->subtitle_scan ) 
+    if ( job->indepth_scan ) 
     {
         for( i=0; i < hb_list_count( title->list_subtitle ); i++ ) 
         {
@@ -926,6 +931,7 @@ void hb_close( hb_handle_t ** _h )
     hb_lock_close( &h->pause_lock );
     free( h );
     *_h = NULL;
+
 }
 
 /**
index 0b46059..d3bbb63 100644 (file)
@@ -64,6 +64,9 @@ struct hb_buffer_s
     hb_buffer_t * next;
 };
 
+void hb_buffer_pool_init( void );
+void hb_buffer_pool_free( void );
+
 hb_buffer_t * hb_buffer_init( int size );
 void          hb_buffer_realloc( hb_buffer_t *, int size );
 void          hb_buffer_close( hb_buffer_t ** );
index 5067745..2fd39eb 100644 (file)
@@ -118,7 +118,7 @@ static void ReaderFunc( void * _r )
           }
         }
 
-        if( r->job->subtitle_scan )
+        if( r->job->indepth_scan )
         {
             /*
              * Need to update the progress during a subtitle scan
@@ -139,7 +139,7 @@ static void ReaderFunc( void * _r )
             p.seconds  = -1;
             hb_set_state( r->job->h, &state );
         }
-        
+
         hb_demux_ps( r->ps, list );
 
         while( ( buf = hb_list_item( list, 0 ) ) )
@@ -194,18 +194,21 @@ static hb_fifo_t * GetFifoForId( hb_job_t * job, int id )
 
     if( id == 0xE0 )
     {
-        if( !job->subtitle_scan )
+        if( job->indepth_scan ) 
         {
-            return job->fifo_mpeg2;
-        } else {
             /*
-             * Ditch the mpeg2 video when doing a subtitle scan.
+             * Ditch the video here during the indepth scan until
+             * we can improve the MPEG2 decode performance.
              */
             return NULL;
+        } 
+        else 
+        {
+            return job->fifo_mpeg2;
         }
     }
 
-    if (job->subtitle_scan) {
+    if( job->indepth_scan ) {
         /*
          * Count the occurances of the subtitles, don't actually
          * return any to encode unless we are looking fro forced
@@ -233,12 +236,15 @@ static hb_fifo_t * GetFifoForId( hb_job_t * job, int id )
             return subtitle->fifo_in;
         }
     }
-    for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+    if( !job->indepth_scan ) 
     {
-        audio = hb_list_item( title->list_audio, i );
-        if( id == audio->id )
+        for( i = 0; i < hb_list_count( title->list_audio ); i++ )
         {
-            return audio->fifo_in;
+            audio = hb_list_item( title->list_audio, i );
+            if( id == audio->id )
+            {
+                return audio->fifo_in;
+            }
         }
     }
 
index 5577c2f..05dcdbb 100644 (file)
@@ -160,6 +160,16 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
        *buf_out = hb_buffer_init(0);
        return HB_WORK_OK;
     }
+
+    /*
+     * During the indepth_scan ditch the buffers here before applying filters or attempting to
+     * use the subtitles.
+     */
+    if( job->indepth_scan )
+    {      
+        *buf_out = NULL;
+        return HB_WORK_OK;
+    }
     
     /* Push subtitles onto queue just in case we need to delay a frame */
     if( in->sub )
index ab8963c..b168308 100755 (executable)
@@ -676,7 +676,7 @@ static void hb_stream_put_back(hb_stream_t *stream, int i)
                        stream->ps_decode_buffer[read_buffer_index].read_pos -= i;
                }
                else
-                 fprintf(stderr, "hb_stream_put_back - trying to step beyond the start of the buffer, read_pos = %d amt to put back = %d\n", stream->ps_decode_buffer[read_buffer_index].read_pos, i);
+                 hb_error("hb_stream_put_back - trying to step beyond the start of the buffer, read_pos = %d amt to put back = %d\n", stream->ps_decode_buffer[read_buffer_index].read_pos, i);
        }
 }
 
index e73bf16..5b3f914 100644 (file)
@@ -22,6 +22,8 @@ static void work_func();
 static void do_job( hb_job_t *, int cpu_count );
 static void work_loop( void * );
 
+#define FIFO_SIZE 32
+
 /**
  * Allocates work object and launches work thread with work_func.
  * @param jobs Handle to hb_list_t.
@@ -174,10 +176,10 @@ static void do_job( hb_job_t * job, int cpu_count )
     }
        hb_log (" + PixelRatio: %d, width:%d, height: %d",job->pixel_ratio,job->width, job->height);
     job->fifo_mpeg2  = hb_fifo_init( 2048 );
-    job->fifo_raw    = hb_fifo_init( 8 );
-    job->fifo_sync   = hb_fifo_init( 8 );
-    job->fifo_render = hb_fifo_init( 8 );
-    job->fifo_mpeg4  = hb_fifo_init( 8 );
+    job->fifo_raw    = hb_fifo_init( FIFO_SIZE );
+    job->fifo_sync   = hb_fifo_init( FIFO_SIZE );
+    job->fifo_render = hb_fifo_init( FIFO_SIZE );
+    job->fifo_mpeg4  = hb_fifo_init( FIFO_SIZE );
 
     /* Synchronization */
     hb_list_add( job->list_work, ( w = getWork( WORK_SYNC ) ) );
@@ -216,7 +218,7 @@ static void do_job( hb_job_t * job, int cpu_count )
     
     hb_list_add( job->list_work, w );
 
-    if( job->select_subtitle && !job->subtitle_scan ) 
+    if( job->select_subtitle && !job->indepth_scan ) 
     {
         /*
          * Must be second pass of a two pass with subtitle scan enabled, so
@@ -237,8 +239,8 @@ static void do_job( hb_job_t * job, int cpu_count )
         {
             hb_log( " + subtitle %x, %s", subtitle->id, subtitle->lang );
             
-            subtitle->fifo_in  = hb_fifo_init( 8 );
-            subtitle->fifo_raw = hb_fifo_init( 8 );
+            subtitle->fifo_in  = hb_fifo_init( FIFO_SIZE );
+            subtitle->fifo_raw = hb_fifo_init( FIFO_SIZE );
             
             /*
              * Disable forced subtitles if we didn't find any in the scan
@@ -246,7 +248,7 @@ static void do_job( hb_job_t * job, int cpu_count )
              *
              * select_subtitle implies that we did a scan.
              */
-            if( !job->subtitle_scan && job->subtitle_force && 
+            if( !job->indepth_scan && job->subtitle_force && 
                 job->select_subtitle ) 
             {
                 if( subtitle->forced_hits == 0 )
@@ -255,7 +257,7 @@ static void do_job( hb_job_t * job, int cpu_count )
                 }
             }
 
-            if (!job->subtitle_scan || job->subtitle_force) {
+            if (!job->indepth_scan || job->subtitle_force) {
                 /*
                  * Don't add threads for subtitles when we are scanning, unless
                  * looking for forced subtitles.
@@ -437,9 +439,9 @@ static void do_job( hb_job_t * job, int cpu_count )
 
                /* set up the audio work structures */
         audio->fifo_in   = hb_fifo_init( 2048 );
-        audio->fifo_raw  = hb_fifo_init( 8 );
-        audio->fifo_sync = hb_fifo_init( 8 );
-        audio->fifo_out  = hb_fifo_init( 8 );
+        audio->fifo_raw  = hb_fifo_init( FIFO_SIZE );
+        audio->fifo_sync = hb_fifo_init( FIFO_SIZE );
+        audio->fifo_out  = hb_fifo_init( FIFO_SIZE );
 
         switch( audio->codec )
         {
@@ -512,7 +514,7 @@ static void do_job( hb_job_t * job, int cpu_count )
     {
         w = hb_list_item( job->list_work, i );
         w->done = &job->done;
-               w->thread_sleep_interval = 10;
+        w->thread_sleep_interval = 10;
         w->init( w, job );
         w->thread = hb_thread_init( w->name, work_loop, w,
                                     HB_LOW_PRIORITY );
@@ -520,7 +522,7 @@ static void do_job( hb_job_t * job, int cpu_count )
 
     done = 0;
     w = hb_list_item( job->list_work, 0 );
-       w->thread_sleep_interval = 50;
+    w->thread_sleep_interval = 50;
     w->init( w, job );
     while( !*job->die )
     {
@@ -573,6 +575,9 @@ static void do_job( hb_job_t * job, int cpu_count )
     hb_fifo_close( &job->fifo_sync );
     hb_fifo_close( &job->fifo_render );
     hb_fifo_close( &job->fifo_mpeg4 );
+
+    hb_buffer_pool_free();
+
     for (i=0; i < hb_list_count(title->list_subtitle); i++) {
         subtitle =  hb_list_item( title->list_subtitle, i);
         if( subtitle )
@@ -590,7 +595,7 @@ static void do_job( hb_job_t * job, int cpu_count )
         hb_fifo_close( &audio->fifo_out );
     }
 
-    if( job->subtitle_scan )
+    if( job->indepth_scan )
     {
         /*
          * Before closing the title print out our subtitle stats if we need to
@@ -661,7 +666,7 @@ static void do_job( hb_job_t * job, int cpu_count )
 
     if( job->select_subtitle ) 
     {
-        if( job->subtitle_scan ) 
+        if( job->indepth_scan ) 
         {
             for( i=0; i < hb_list_count( title->list_subtitle ); i++ ) 
             {
index b2fb41f..297eaf7 100644 (file)
@@ -1590,7 +1590,7 @@ static int hb_group_count(hb_handle_t * h)
 
                     job->x264opts = NULL;
                     
-                    job->subtitle_scan = 1;  
+                    job->indepth_scan = 1;  
 
                     job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*));
                     *(job->select_subtitle) = NULL;
@@ -1617,8 +1617,7 @@ static int hb_group_count(hb_handle_t * h)
                if( [fVidTwoPassCheck state] == NSOnState )
                {
             hb_subtitle_t **subtitle_tmp = job->select_subtitle;
-            job->select_subtitle = NULL;
-            job->subtitle_scan = 0;
+                        job->indepth_scan = 0;
 
                        job->pass = 1;
                        job->sequence_id++; // for job grouping
@@ -1636,7 +1635,7 @@ static int hb_group_count(hb_handle_t * h)
                }
                else
                {
-                        job->subtitle_scan = 0;
+                        job->indepth_scan = 0;
                        job->pass = 0;
                        job->sequence_id++; // for job grouping
                        hb_add( fHandle, job );
index cddcadf..a5ddddf 100644 (file)
@@ -632,7 +632,7 @@ static int HandleEvents( hb_handle_t * h )
 
                 job->x264opts = NULL;
 
-                job->subtitle_scan = subtitle_scan;  
+                job->indepth_scan = subtitle_scan;  
                 fprintf( stderr, "Subtitle Scan Enabled - enabling "
                          "subtitles if found for foreign language segments\n");
                 job->select_subtitle = malloc(sizeof(hb_subtitle_t*));
@@ -659,7 +659,7 @@ static int HandleEvents( hb_handle_t * h )
 
                 job->pass = 1;
 
-                job->subtitle_scan = 0;
+                job->indepth_scan = 0;
 
                 /*
                  * If turbo options have been selected then append them
@@ -702,7 +702,7 @@ static int HandleEvents( hb_handle_t * h )
                  * selected in the first pass (using the whacky select-subtitle
                  * attribute of the job).
                  */
-                job->subtitle_scan = 0;
+                job->indepth_scan = 0;
 
                 job->x264opts = x264opts2;
                 
@@ -715,7 +715,7 @@ static int HandleEvents( hb_handle_t * h )
                  * precludes encoding of any actual subtitles.
                  */ 
 
-                job->subtitle_scan = 0;
+                job->indepth_scan = 0;
                 job->pass = 0;
                 hb_add( h, job );
             }