OSDN Git Service

Don't discard titles during scan just because of a read failure on one or more of...
[handbrake-jp/handbrake-jp-git.git] / libhb / hb.c
index 2b8748e..a53bd1f 100644 (file)
@@ -23,6 +23,7 @@ struct hb_handle_s
     /* The thread which processes the jobs. Others threads are launched
        from this one (see work.c) */
     hb_list_t    * jobs;
+    hb_job_t     * current_job;
     int            job_count;
     int            job_count_permanent;
     volatile int   work_die;
@@ -103,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();
@@ -186,6 +192,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
 
     h->list_title = hb_list_init();
     h->jobs       = hb_list_init();
+    h->current_job = NULL;
 
     h->state_lock  = hb_lock_init();
     h->state.state = HB_STATE_IDLE;
@@ -309,14 +316,26 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
     hb_job_t           * job = title->job;
     char                 filename[1024];
     FILE               * file;
-    uint8_t            * pen;
+    uint8_t            * buf1, * buf2, * buf3, * buf4, * pen;
     uint32_t           * p32;
     AVPicture            pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
     struct SwsContext  * context;
     int                  i;
 
+    buf1 = malloc( title->width * title->height * 3 / 2 );
+    buf2 = malloc( title->width * title->height * 3 / 2 );
+    buf3 = malloc( title->width * title->height * 3 / 2 );
+    buf4 = malloc( title->width * title->height * 4 );
+    avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
+                    title->width, title->height );
+    avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
+                    title->width, title->height );
+    avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
+                    job->width, job->height );
+    avpicture_fill( &pic_preview, buf4, PIX_FMT_RGBA32,
+                    job->width, job->height );
+
     // Allocate the AVPicture frames and fill in
-    avpicture_alloc( &pic_in, PIX_FMT_YUV420P, title->width, title->height );
 
     memset( filename, 0, 1024 );
 
@@ -330,44 +349,51 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
         return;
     }
 
-    fread( pic_in.data[0], title->width * title->height * 3 / 2, 1, file );
+    fread( buf1, title->width * title->height * 3 / 2, 1, file );
     fclose( file );
 
     if( job->deinterlace )
     {
-        // Allocate picture to deinterlace into and deinterlace
-        avpicture_alloc( &pic_deint, PIX_FMT_YUV420P, title->width, title->height );
+        // Deinterlace and crop
         avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
-
         av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
     }
     else
     {
+        // Crop
         av_picture_crop( &pic_crop, &pic_in, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
     }
 
-    // Allocate picture to scale into, get scaling context and scale
-    avpicture_alloc( &pic_scale, PIX_FMT_YUV420P, job->width, job->height );
+    // Get scaling context
     context = sws_getContext(title->width  - (job->crop[2] + job->crop[3]),
                              title->height - (job->crop[0] + job->crop[1]),
                              PIX_FMT_YUV420P,
                              job->width, job->height, PIX_FMT_YUV420P,
-                             SWS_LANCZOS, NULL, NULL, NULL);
+                             (uint16_t)(SWS_LANCZOS|SWS_ACCURATE_RND), NULL, NULL, NULL);
+
+    // Scale
     sws_scale(context,
               pic_crop.data, pic_crop.linesize,
               0, title->height - (job->crop[0] + job->crop[1]),
               pic_scale.data, pic_scale.linesize);
 
-    // Allocate RGBA32 preview picture and create preview
-    avpicture_alloc( &pic_preview, PIX_FMT_RGBA32, job->width, job->height );
+    // Free context
+    sws_freeContext( context );
+
+    // Get preview context
     context = sws_getContext(job->width, job->height, PIX_FMT_YUV420P,
                              job->width, job->height, PIX_FMT_RGBA32,
-                             SWS_LANCZOS, NULL, NULL, NULL);
+                             (uint16_t)(SWS_LANCZOS|SWS_ACCURATE_RND), NULL, NULL, NULL);
+
+    // Create preview
     sws_scale(context,
               pic_scale.data, pic_scale.linesize,
               0, job->height,
               pic_preview.data, pic_preview.linesize);
 
+    // Free context
+    sws_freeContext( context );
+
     /* Gray background */
     p32 = (uint32_t *) buffer;
     for( i = 0; i < ( title->width + 2 ) * ( title->height + 2 ); i++ )
@@ -386,16 +412,17 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
         nextLine = pen + 4 * ( title->width + 2 );
         memset( pen, 0xFF, 4 );
         pen += 4;
-        memcpy( pen, pic_preview.data[0] + 4 * job->width * i, 4 * job->width );
+        memcpy( pen, buf4 + 4 * job->width * i, 4 * job->width );
         pen += 4 * job->width;
         memset( pen, 0xFF, 4 );
         pen = nextLine;
     }
     memset( pen, 0xFF, 4 * ( job->width + 2 ) );
 
+    // Clean up
     avpicture_free( &pic_preview );
     avpicture_free( &pic_scale );
-    if( job->deinterlace ) avpicture_free( &pic_deint );
+    avpicture_free( &pic_deint );
     avpicture_free( &pic_in );
 }
 
@@ -509,6 +536,11 @@ hb_job_t * hb_job( hb_handle_t * h, int i )
     return hb_list_item( h->jobs, i );
 }
 
+hb_job_t * hb_current_job( hb_handle_t * h )
+{
+    return( h->current_job );
+}
+
 /**
  * Adds a job to the job list.
  * @param h Handle to hb_handle_t.
@@ -542,7 +574,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     title_copy->list_audio = hb_list_init();
 
     /* Do nothing about audio during first pass */
-    if( job->pass != 1 )
+    if( job->pass == 0 || job->pass == 2 )
     {
         for( i = 0; i < 8; i++ )
         {
@@ -562,23 +594,25 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     title_copy->list_subtitle = hb_list_init();
 
     /*
-     * The following code is confusing, there are three ways in which we select subtitles
-     * and it depends on whether this is single or two pass mode.
+     * The following code is confusing, there are three ways in which
+     * we select subtitles and it depends on whether this is single or
+     * two pass mode.
      *
-     * subtitle_scan may be enabled, in which case the first pass scans all subtitles
-     * of that language. The second pass does not select any because they are set at the
-     * end of the first pass.
+     * subtitle_scan may be enabled, in which case the first pass
+     * scans all subtitles of that language. The second pass does not
+     * select any because they are set at the end of the first pass.
      *
-     * native_language may have a preferred language, in which case we may be switching
-     * the language we want for the subtitles in the first pass of a single pass, or the
-     * second pass of a two pass.
+     * native_language may have a preferred language, in which case we
+     * may be switching the language we want for the subtitles in the
+     * first pass of a single pass, or the second pass of a two pass.
      *
-     * We may have manually selected a subtitle, in which case that is selected in the
-     * first pass of a single pass, or the second of a two pass.
+     * We may have manually selected a subtitle, in which case that is
+     * selected in the first pass of a single pass, or the second of a
+     * two pass.
      */
     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
@@ -630,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++ ) 
         {
@@ -666,7 +700,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
         {
             /*
              * Don't add subtitles here, we'll add them via select_subtitle
-             * at the end of pass 1
+             * at the end of the subtitle_scan.
              */
         } else {
             /*
@@ -731,7 +765,6 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
         for( i = 0; i < filter_count; i++ )
         {
             hb_filter_object_t * filter = hb_list_item( job->filters, i );
-            hb_log("Adding filter: %s", filter->name);
             hb_list_add( job_copy->filters, filter );
         }        
     }
@@ -768,6 +801,7 @@ void hb_start( hb_handle_t * h )
 {
     /* XXX Hack */
     h->job_count = hb_list_count( h->jobs );
+    h->job_count_permanent = h->job_count;
 
     hb_lock( h->state_lock );
     h->state.state = HB_STATE_WORKING;
@@ -787,7 +821,7 @@ void hb_start( hb_handle_t * h )
 
     h->work_die    = 0;
     h->work_thread = hb_work_init( h->jobs, h->cpu_count,
-                                   &h->work_die, &h->work_error );
+                                   &h->work_die, &h->work_error, &h->current_job );
 }
 
 /**
@@ -844,7 +878,17 @@ void hb_get_state( hb_handle_t * h, hb_state_t * s )
     hb_lock( h->state_lock );
 
     memcpy( s, &h->state, sizeof( hb_state_t ) );
-    h->state.state = HB_STATE_IDLE;
+    if ( h->state.state == HB_STATE_SCANDONE || h->state.state == HB_STATE_WORKDONE )
+        h->state.state = HB_STATE_IDLE;
+
+    hb_unlock( h->state_lock );
+}
+
+void hb_get_state2( hb_handle_t * h, hb_state_t * s )
+{
+    hb_lock( h->state_lock );
+
+    memcpy( s, &h->state, sizeof( hb_state_t ) );
 
     hb_unlock( h->state_lock );
 }
@@ -887,6 +931,7 @@ void hb_close( hb_handle_t ** _h )
     hb_lock_close( &h->pause_lock );
     free( h );
     *_h = NULL;
+
 }
 
 /**