OSDN Git Service

add bootstrap step to libdca
[handbrake-jp/handbrake-jp-git.git] / libhb / work.c
index d8fc4d9..c9d32de 100644 (file)
@@ -128,7 +128,8 @@ hb_work_object_t * hb_codec_encoder( int codec )
         case HB_ACODEC_FAAC:   return hb_get_work( WORK_ENCFAAC );
         case HB_ACODEC_LAME:   return hb_get_work( WORK_ENCLAME );
         case HB_ACODEC_VORBIS: return hb_get_work( WORK_ENCVORBIS );
-        case HB_ACODEC_CA_AAC:  return hb_get_work( WORK_ENC_CA_AAC );
+        case HB_ACODEC_CA_AAC: return hb_get_work( WORK_ENC_CA_AAC );
+        case HB_ACODEC_AC3:    return hb_get_work( WORK_ENCAC3 );
     }
     return NULL;
 }
@@ -317,11 +318,7 @@ void hb_display_job_info( hb_job_t * job )
             {
                 hb_log( " * subtitle track %i, %s (id %x) %s [%s] -> %s%s%s", subtitle->track, subtitle->lang, subtitle->id,
                         subtitle->format == PICTURESUB ? "Picture" : "Text",
-                        subtitle->source == VOBSUB ? "VOBSUB" : 
-                        subtitle->source == CC608SUB || subtitle->source == CC708SUB ? "CC" : 
-                        subtitle->source == UTF8SUB ? "UTF-8" : 
-                        subtitle->source == TX3GSUB ? "TX3G" : 
-                        subtitle->source == SSASUB ? "SSA" : "Unknown",
+                        hb_subsource_name( subtitle->source ),
                         job->indepth_scan ? "Foreign Audio Search" :
                         subtitle->config.dest == RENDERSUB ? "Render/Burn in" : "Pass-Through",
                         subtitle->config.force ? ", Forced Only" : "",
@@ -348,7 +345,7 @@ void hb_display_job_info( hb_job_t * job )
                 hb_log( "     + bitrate: %d kbps, samplerate: %d Hz", audio->config.in.bitrate / 1000, audio->config.in.samplerate );
             }
 
-            if( (audio->config.out.codec != HB_ACODEC_AC3) && (audio->config.out.codec != HB_ACODEC_DCA) )
+            if( (audio->config.out.codec != HB_ACODEC_AC3_PASS) && (audio->config.out.codec != HB_ACODEC_DCA_PASS) )
             {
                 for (j = 0; j < hb_audio_mixdowns_count; j++)
                 {
@@ -359,22 +356,24 @@ void hb_display_job_info( hb_job_t * job )
                 }
             }
 
-            if ( audio->config.out.dynamic_range_compression && (audio->config.out.codec != HB_ACODEC_AC3) && (audio->config.out.codec != HB_ACODEC_DCA))
+            if ( audio->config.out.dynamic_range_compression && (audio->config.out.codec != HB_ACODEC_AC3_PASS) && (audio->config.out.codec != HB_ACODEC_DCA_PASS))
             {
                 hb_log("   + dynamic range compression: %f", audio->config.out.dynamic_range_compression);
             }
             
-            if( (audio->config.out.codec == HB_ACODEC_AC3) || (audio->config.out.codec == HB_ACODEC_DCA) )
+            if( (audio->config.out.codec == HB_ACODEC_AC3_PASS) || (audio->config.out.codec == HB_ACODEC_DCA_PASS) )
             {
-                hb_log( "   + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3) ?
+                hb_log( "   + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3_PASS) ?
                     "AC3" : "DCA" );
             }
             else
             {
-                hb_log( "   + encoder: %s", ( audio->config.out.codec == HB_ACODEC_FAAC ) ?
-                    "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ?
-                    "lame" : ( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ?
-                              "ca_aac" : "vorbis"  ) ) );
+                hb_log( "   + encoder: %s", 
+                    ( audio->config.out.codec == HB_ACODEC_FAAC ) ?  "faac" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_LAME ) ?  "lame" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ?  "ca_aac" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_AC3 ) ?  "ffac3" : 
+                    "vorbis"  ) ) ) );
                 hb_log( "     + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );            
             }
         }
@@ -422,6 +421,7 @@ static void do_job( hb_job_t * job, int cpu_count )
 
     hb_audio_t   * audio;
     hb_subtitle_t * subtitle;
+    hb_attachment_t * attachment;
     unsigned int subtitle_highest = 0;
     unsigned int subtitle_highest_id = 0;
     unsigned int subtitle_lowest = -1;
@@ -516,8 +516,8 @@ static void do_job( hb_job_t * job, int cpu_count )
     for( i = 0; i < hb_list_count( title->list_audio ); )
     {
         audio = hb_list_item( title->list_audio, i );
-        if( ( ( audio->config.out.codec == HB_ACODEC_AC3 ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||
-            ( ( audio->config.out.codec == HB_ACODEC_DCA ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) )
+        if( ( ( audio->config.out.codec == HB_ACODEC_AC3_PASS ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||
+            ( ( audio->config.out.codec == HB_ACODEC_DCA_PASS ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) )
         {
             hb_log( "Passthru requested and input codec is not the same as output codec for track %d",
                     audio->config.out.track );
@@ -525,14 +525,21 @@ static void do_job( hb_job_t * job, int cpu_count )
             free( audio );
             continue;
         }
-        if( audio->config.out.codec != HB_ACODEC_AC3 && 
-            audio->config.out.codec != HB_ACODEC_DCA &&
+        if( audio->config.out.codec != HB_ACODEC_AC3_PASS && 
+            audio->config.out.codec != HB_ACODEC_DCA_PASS &&
             audio->config.out.samplerate > 48000 )
         {
             hb_log( "Sample rate %d not supported.  Down-sampling to 48kHz.",
                     audio->config.out.samplerate );
             audio->config.out.samplerate = 48000;
         }
+        if( audio->config.out.codec == HB_ACODEC_AC3 && 
+            audio->config.out.bitrate > 640 )
+        {
+            hb_log( "Bitrate %d not supported.  Reducing to 640Kbps.",
+                    audio->config.out.bitrate );
+            audio->config.out.bitrate = 640;
+        }
         if ( audio->config.in.codec == HB_ACODEC_FFMPEG )
         {
             if ( aud_id_uses[audio->id] )
@@ -552,100 +559,64 @@ static void do_job( hb_job_t * job, int cpu_count )
     }
 
     int requested_mixdown = 0;
+    int best_mixdown = 0;
     int requested_mixdown_index = 0;
 
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
 
-        if( audio->config.out.codec != audio->config.in.codec )
-        {
-            /* sense-check the current mixdown options */
+        best_mixdown = hb_get_best_mixdown( audio->config.out.codec,
+                                            audio->config.in.channel_layout );
 
-            /* log the requested mixdown */
-            for (j = 0; j < hb_audio_mixdowns_count; j++) {
-                if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {
-                    requested_mixdown = audio->config.out.mixdown;
-                    requested_mixdown_index = j;
+        /* sense-check the current mixdown options */
+
+        /* sense-check the requested mixdown */
+        if( audio->config.out.mixdown == 0 &&
+            audio->config.out.codec != HB_ACODEC_AC3_PASS && 
+            audio->config.out.codec != HB_ACODEC_DCA_PASS )
+        {
+            /*
+             * Mixdown wasn't specified and this is not pass-through,
+             * set a default mixdown
+             */
+            audio->config.out.mixdown = best_mixdown;
+            for (j = 0; j < hb_audio_mixdowns_count; j++)
+            {
+                if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown)
+                {
+                    hb_log("work: mixdown not specified, track %i setting mixdown %s", i, hb_audio_mixdowns[j].human_readable_name);
+                    break;
                 }
             }
+        }
 
-            /* sense-check the requested mixdown */
-
-            if( audio->config.out.mixdown == 0 &&
-                audio->config.out.codec != HB_ACODEC_AC3 && 
-                audio->config.out.codec != HB_ACODEC_DCA )
-            {
-                /*
-                 * Mixdown wasn't specified and this is not pass-through,
-                 * set a default mixdown of stereo.
-                 */
-                audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
+        /* log the requested mixdown */
+        for (j = 0; j < hb_audio_mixdowns_count; j++) {
+            if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {
+                requested_mixdown = audio->config.out.mixdown;
+                requested_mixdown_index = j;
+                break;
             }
+        }
 
-            // Here we try to sanitize the audio input to output mapping.
-            // Constraints are:
-            //   1. only the AC3 & DCA decoder libraries currently support mixdown
-            //   2. the lame encoder library only supports stereo.
-            // So if the encoder is lame we need the output to be stereo (or multichannel
-            // matrixed into stereo like dpl). If the decoder is not AC3 or DCA the
-            // encoder has to handle the input format since we can't do a mixdown.
-            switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
+        if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+        {
+            if ( audio->config.out.mixdown > best_mixdown )
             {
-                // stereo input or something not handled below
-                default:
-                case HB_INPUT_CH_LAYOUT_STEREO:
-                    // mono gets mixed up to stereo & more than stereo gets mixed down
-                    if ( audio->config.out.mixdown > HB_AMIXDOWN_STEREO )
-                    {
-                        audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
-                    }
-                    break;
-
-                // mono input
-                case HB_INPUT_CH_LAYOUT_MONO:
-                    // everything else passes through
-                    audio->config.out.mixdown = HB_AMIXDOWN_MONO;
-                    break;
-
-                // dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input
-                // the A52 flags don't allow for a way to distinguish between DPL1 and
-                // DPL2 on a DVD so we always assume a DPL1 source for A52_DOLBY.
-                case HB_INPUT_CH_LAYOUT_DOLBY:
-                    if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
-                    {
-                        audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
-                    }
-                    break;
-
-                // 4 channel discrete
-                case HB_INPUT_CH_LAYOUT_2F2R:
-                case HB_INPUT_CH_LAYOUT_3F1R:
-                    if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
-                    {
-                        audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
-                    }
-                    break;
-
-                // 5 or 6 channel discrete
-                case HB_INPUT_CH_LAYOUT_3F2R:
-                    if ( ! ( audio->config.in.channel_layout &
-                                    HB_INPUT_CH_LAYOUT_HAS_LFE ) )
-                    {
-                        // we don't do 5 channel discrete so mixdown to DPLII
-                        audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
-                    }
-                    break;
+                audio->config.out.mixdown = best_mixdown;
             }
+        }
 
+        if ( audio->config.out.mixdown != requested_mixdown )
+        {
             /* log the output mixdown */
-            for (j = 0; j < hb_audio_mixdowns_count; j++) {
-                if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {
-                    if ( audio->config.out.mixdown != requested_mixdown )
-                    {
-                        hb_log("work: sanitizing track %i mixdown %s to %s", i, hb_audio_mixdowns[requested_mixdown_index].human_readable_name, hb_audio_mixdowns[j].human_readable_name);
-                    }
-                    break;
+            for (j = 0; j < hb_audio_mixdowns_count; j++)
+            {
+                if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown)
+                {
+                    hb_log("work: sanitizing track %i mixdown %s to %s", i, hb_audio_mixdowns[requested_mixdown_index].human_readable_name, hb_audio_mixdowns[j].human_readable_name);
+                break;
                 }
             }
         }
@@ -666,6 +637,13 @@ static void do_job( hb_job_t * job, int cpu_count )
 
     /* Video decoder */
     int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
+#if defined(USE_FF_MPEG2)
+    if (vcodec == WORK_DECMPEG2)
+    {
+        vcodec = WORK_DECAVCODECV;
+        title->video_codec_param = CODEC_ID_MPEG2VIDEO;
+    }
+#endif
     hb_list_add( job->list_work, ( w = hb_get_work( vcodec ) ) );
     w->codec_param = title->video_codec_param;
     w->fifo_in  = job->fifo_mpeg2;
@@ -819,6 +797,7 @@ static void do_job( hb_job_t * job, int cpu_count )
                 w = hb_get_work( WORK_DECSSASUB );
                 w->fifo_in  = subtitle->fifo_in;
                 w->fifo_out = subtitle->fifo_raw;
+                w->subtitle = subtitle;
                 hb_list_add( job->list_work, w );
             }
 
@@ -865,8 +844,8 @@ static void do_job( hb_job_t * job, int cpu_count )
             /*
             * Audio Encoder Thread
             */
-            if( audio->config.out.codec != HB_ACODEC_AC3 &&
-                audio->config.out.codec != HB_ACODEC_DCA )
+            if( audio->config.out.codec != HB_ACODEC_AC3_PASS &&
+                audio->config.out.codec != HB_ACODEC_DCA_PASS )
             {
                 /*
                 * Add the encoder thread if not doing AC-3 pass through
@@ -1181,6 +1160,9 @@ static void work_loop( void * _w )
             break;
         }
 
+        // Invalidate buf_out so that if there is no output
+        // we don't try to pass along junk.
+        buf_out = NULL;
         w->status = w->work( w, &buf_in, &buf_out );
 
         // Propagate any chapter breaks for the worker if and only if the