]> granicus.if.org Git - handbrake/commitdiff
Applied and committed saintdev's patch to fix multi-track audio. Only in the CLI...
authormaurj <handbrake@maurj.com>
Wed, 21 Mar 2007 10:09:23 +0000 (10:09 +0000)
committermaurj <handbrake@maurj.com>
Wed, 21 Mar 2007 10:09:23 +0000 (10:09 +0000)
If the -6 option is specified in the CLI (and faac is specified), then *any* 5.1 tracks specified will be exported as 6-channel AAC.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@438 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/common.h
libhb/deca52.c
libhb/encfaac.c
libhb/internal.h
libhb/scan.c
libhb/sync.c
libhb/work.c

index d43e5169ffa4f0e93b4e551fcaf13f662d5701fc..a2be02a87b8bf07a56eb68fe1148a2aefb4af6dc 100644 (file)
@@ -150,18 +150,8 @@ struct hb_job_s
     /* Audio tracks:
          audios:         Indexes in hb_title_t's audios list, starting from 0.
                          -1 indicates the end of the list
-                channels:       The # of normal channels in the last used audio
-                lfechannels:    The # of lfe channels in the last used audio
-                channelsused:   The # of channels we will actually use for this job -
-                                calculated based on surround, channels and lfechannels
-                                                in work.c
-         ac3flags:       stores the flags from the AC3 source, as found in scan.c
             surround:       1 if 5.1 should be preserved for AAC, 0 otherwise */
     int             audios[8];
-    int             channels;
-    int             lfechannels;
-    int             channelsused;
-       int             ac3flags;
        int             surround;
 
     /* Audio settings:
@@ -231,12 +221,14 @@ struct hb_audio_s
     int  codec;
     int  rate;
     int  bitrate;
-       /* indicates the number of normal channels the source audio has */
+       /* channels:       The # of normal channels in the last used audio
+          lfechannels:    The # of lfe channels in the last used audio
+          channelsused:   The # of channels we will actually use for this job -
+                          calculated based on surround, channels and lfechannels
+                          in work.c */
     int  channels;
-       /* indicates the number of lfe channels the source audio has */
        int  lfechannels;
-       /* stores the flags from the AC3 source, as found in scan.c */
-       int  ac3flags;
+       int channelsused;
 
 #ifdef __LIBHB__
     /* Internal data */
index 5294a5be51889a9acc88d82e026d0a9584683bf1..511a9a15e74bd0f23b808f364d19e47621036d6d 100644 (file)
@@ -69,18 +69,18 @@ int deca52Init( hb_work_object_t * w, hb_job_t * job )
        /* Decide what format we want out of a52dec
        work.c has already done some of this deduction for us in do_job() */
        
-       if (job->channelsused == 6) {
+       if (w->config->a52.channelsused == 6) {
                /* we're going to be encoding to AAC,
                and have turned on the "preserve 5.1" flag */
                pv->flags_out = A52_3F2R | A52_LFE;
-       } else if (job->channelsused == 1) {
+       } else if (w->config->a52.channelsused == 1) {
                /* we're going to be encoding to AAC, */
                /* and want to keep the mono-ness of the source audio */
                pv->flags_out = A52_MONO;
-       } else if (job->channelsused == 2 && job->channels == 5 && job->lfechannels == 1) {
+       } else if (w->config->a52.channelsused == 2 && w->config->a52.channels == 5 && w->config->a52.lfechannels == 1) {
                /* we are mixing a 5.1 source down to stereo, so use dolby surround */
                pv->flags_out = A52_DOLBY;
-       } else if (job->channelsused == 2 && ((job->ac3flags & A52_CHANNEL_MASK) == A52_DOLBY)) {
+       } else if (w->config->a52.channelsused == 2 && ((w->config->a52.ac3flags & A52_CHANNEL_MASK) == A52_DOLBY)) {
                /* we have a dolby stereo surround source, so preserve it */
                pv->flags_out = A52_DOLBY;
        } else {
@@ -89,7 +89,7 @@ int deca52Init( hb_work_object_t * w, hb_job_t * job )
        }
 
        /* pass the number of channels used into the private work data */
-       pv->channelsused = job->channelsused;
+       pv->channelsused = w->config->a52.channelsused;
 
     pv->level     = 32768.0;
 
index 262bc4de9964f8f9ae5dd2d15a9009e1693b208c..3cbe48f247af84ff08e62e0dba549e1224771727 100644 (file)
@@ -54,9 +54,9 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
     pv->job   = job;
 
        /* pass the number of channels used into the private work data */
-       pv->channelsused = job->channelsused;
+       pv->channelsused = w->config->aac.channelsused;
 
-    pv->faac = faacEncOpen( job->arate, job->channelsused, &pv->input_samples,
+    pv->faac = faacEncOpen( job->arate, w->config->aac.channelsused, &pv->input_samples,
                            &pv->output_bytes );
     pv->buf  = malloc( pv->input_samples * sizeof( float ) );
     
@@ -65,7 +65,7 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
     cfg->aacObjectType = LOW;
     cfg->allowMidside  = 1;
        
-       if (job->channelsused == 6) {
+       if (w->config->aac.channelsused == 6) {
                /* we are preserving 5.1 audio into 6-channel AAC,
                so indicate that we have an lfe channel */
                cfg->useLfe    = 1;
@@ -79,10 +79,11 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
     cfg->outputFormat  = 0;
     cfg->inputFormat   =  FAAC_INPUT_FLOAT;
        
-       if (job->channelsused == 6) {
+       if (w->config->aac.channelsused == 6) {
                /* we are preserving 5.1 audio into 6-channel AAC, and need to
                re-map the output of deca52 into our own mapping - the mapping
                below is the default mapping expected by QuickTime */
+               /* This doesn't seem to be correct for VLC on Linux */
                cfg->channel_map[0] = 2;
                cfg->channel_map[1] = 1;
                cfg->channel_map[2] = 3;
index 79c9787409a0d0b54ccdff9a7a770ee47ac4fcb3..baba5627b9215ae181b21e0d9ac277096d2b5504 100644 (file)
@@ -134,12 +134,26 @@ union hb_esconfig_u
     {
         uint8_t bytes[HB_CONFIG_MAX_SIZE];
         int     length;
+       /* Total channels actually used for this audio track */
+       int channelsused;
     } aac;
 
     struct
     {
         uint8_t headers[3][HB_CONFIG_MAX_SIZE];
     } vorbis;
+    
+    struct
+    {
+       /* indicates the number of normal channels the source audio has */
+        int  channels;
+       /* indicates the number of lfe channels the source audio has */
+       int  lfechannels;
+       /* ac3flags:       stores the flags from the AC3 source, as found in scan.c */
+       int  ac3flags;
+       /* Total channels actually used for this audio track */
+       int channelsused;
+    } a52;
 };
 
 enum
index daf8da27e8fdb48745a49341b0afa4185c8616cf..5d817c737e5b8c9feafeab785e78c7b6af8405a7 100644 (file)
@@ -493,7 +493,7 @@ static void LookForAC3( hb_title_t * title, hb_buffer_t * b )
                        
                        /* store the AC3 tags for future reference
                        This enables us to find out if we had a stereo or Dolby source later on */
-                       audio->ac3flags = flags;
+                       audio->config.a52.ac3flags = flags;
 
             /* XXX */
             sprintf( audio->lang + strlen( audio->lang ),
index 24ee4a8af08c4e7d7e42d33106c6057aecc36089..22266ec63a491463bf63bfa003f86bd98b3b8cc9 100644 (file)
@@ -56,11 +56,11 @@ struct hb_work_private_s
 /***********************************************************************
  * Local prototypes
  **********************************************************************/
-static void InitAudio( hb_work_object_t * w, int i, int channelsused );
+static void InitAudio( hb_work_object_t * w, int i );
 static int  SyncVideo( hb_work_object_t * w );
-static void SyncAudio( hb_work_object_t * w, int i, int channelsused );
+static void SyncAudio( hb_work_object_t * w, int i );
 static int  NeedSilence( hb_work_object_t * w, hb_audio_t * );
-static void InsertSilence( hb_work_object_t * w, int i, int channelsused );
+static void InsertSilence( hb_work_object_t * w, int i );
 static void UpdateState( hb_work_object_t * w );
 
 /***********************************************************************
@@ -100,9 +100,7 @@ int syncInit( hb_work_object_t * w, hb_job_t * job )
     /* Initialize libsamplerate for every audio track we have */
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
-               /* this should really pass in a channelsused value for this audio
-               but for now, it uses the global job value of channelsused */
-        InitAudio( w, i, job->channelsused );
+        InitAudio( w, i );
     }
 
     /* Get subtitle info, if any */
@@ -155,9 +153,7 @@ int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
     {
         for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
         {
-                       /* this should really pass in a channelsused value for this audio
-                       but for now, it uses the global job value of channelsused */
-            SyncAudio( w, i, pv->job->channelsused );
+            SyncAudio( w, i );
         }
     }
 
@@ -174,7 +170,7 @@ hb_work_object_t hb_sync =
     syncClose
 };
 
-static void InitAudio( hb_work_object_t * w, int i, int channelsused )
+static void InitAudio( hb_work_object_t * w, int i )
 {
     hb_work_private_t * pv = w->private_data;
     hb_job_t        * job   = pv->job;
@@ -225,7 +221,7 @@ static void InitAudio( hb_work_object_t * w, int i, int channelsused )
     {
         /* Initialize libsamplerate */
         int error;
-        sync->state             = src_new( SRC_LINEAR, channelsused, &error );
+        sync->state             = src_new( SRC_LINEAR, sync->audio->channelsused, &error );
         sync->data.end_of_input = 0;
     }
 }
@@ -412,7 +408,7 @@ static int SyncVideo( hb_work_object_t * w )
  ***********************************************************************
  * 
  **********************************************************************/
-static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
+static void SyncAudio( hb_work_object_t * w, int i )
 {
     hb_work_private_t * pv = w->private_data;
     hb_job_t        * job;
@@ -485,7 +481,7 @@ static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
         else if( buf->start > pts_expected + 9000 )
         {
             /* Missing audio, send a frame of silence */
-            InsertSilence( w, i, channelsused );
+            InsertSilence( w, i );
             continue;
         }
 
@@ -503,7 +499,7 @@ static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
 
             int count_in, count_out;
 
-            count_in  = buf_raw->size / channelsused / sizeof( float );
+            count_in  = buf_raw->size / audio->channelsused / sizeof( float );
             count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
             if( buf->start < pts_expected - 1500 )
                 count_out--;
@@ -517,7 +513,7 @@ static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
             sync->data.src_ratio = (double) sync->data.output_frames /
                                    (double) sync->data.input_frames;
 
-            buf = hb_buffer_init( sync->data.output_frames * channelsused *
+            buf = hb_buffer_init( sync->data.output_frames * audio->channelsused *
                                   sizeof( float ) );
             sync->data.data_out = (float *) buf->data;
             if( src_process( sync->state, &sync->data ) )
@@ -527,7 +523,7 @@ static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
             }
             hb_buffer_close( &buf_raw );
 
-            buf->size = sync->data.output_frames_gen * channelsused * sizeof( float );
+            buf->size = sync->data.output_frames_gen * audio->channelsused * sizeof( float );
 
             /* Set dates for resampled data */
             buf->start = start;
@@ -543,7 +539,7 @@ static void SyncAudio( hb_work_object_t * w, int i, int channelsused )
 
     if( NeedSilence( w, audio ) )
     {
-        InsertSilence( w, i, channelsused );
+        InsertSilence( w, i );
     }
 }
 
@@ -583,7 +579,7 @@ static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
     return 0;
 }
 
-static void InsertSilence( hb_work_object_t * w, int i, int channelsused )
+static void InsertSilence( hb_work_object_t * w, int i )
 {
     hb_work_private_t * pv = w->private_data;
     hb_job_t        * job;
@@ -610,7 +606,7 @@ static void InsertSilence( hb_work_object_t * w, int i, int channelsused )
     }
     else
     {
-        buf        = hb_buffer_init( channelsused * job->arate / 20 *
+        buf        = hb_buffer_init( sync->audio->channelsused * job->arate / 20 *
                                      sizeof( float ) );
         buf->start = sync->count_frames * 90000 / job->arate;
         buf->stop  = buf->start + 90000 / 20;
index 106df6c7324ab69e1832bf431f8b4fe699a93471..e9ce46e9ff716b7fda06173ec6ffcc919ae0beae 100644 (file)
@@ -91,6 +91,10 @@ static void do_job( hb_job_t * job, int cpu_count )
     hb_title_t    * title;
     int             i;
     hb_work_object_t * w;
+    
+    /* FIXME: This feels really hackish, anything better? */
+    hb_work_object_t * audio_w = NULL;
+
     hb_audio_t   * audio;
     hb_subtitle_t * subtitle;
     int done;
@@ -234,7 +238,13 @@ static void do_job( hb_job_t * job, int cpu_count )
         }
         w->fifo_in  = audio->fifo_in;
         w->fifo_out = audio->fifo_raw;
-        hb_list_add( job->list_work, w );
+        w->config   = &audio->config;
+        
+        /* FIXME: This feels really hackish, anything better? */
+        audio_w = calloc( sizeof( hb_work_object_t ), 1 );
+        audio_w = memcpy( audio_w, w, sizeof( hb_work_object_t ));
+        
+        hb_list_add( job->list_work, audio_w );
 
         switch( job->acodec )
         {
@@ -253,12 +263,15 @@ static void do_job( hb_job_t * job, int cpu_count )
             w->fifo_in  = audio->fifo_sync;
             w->fifo_out = audio->fifo_out;
             w->config   = &audio->config;
-            hb_list_add( job->list_work, w );
+            
+            /* FIXME: This feels really hackish, anything better? */
+            audio_w = calloc( sizeof( hb_work_object_t ), 1 );
+            audio_w = memcpy( audio_w, w, sizeof( hb_work_object_t ));
+        
+            hb_list_add( job->list_work, audio_w );
         }
                
-               /* store this audio's channel counts with the job */
-               /* this should be an array -
-               we just use the last channel count for now */
+               /* store this audio's channel counts in the audio struct */
                
                /* we will only end up with a channelsused value other than 2
                if we are encoding to AAC.  All other audio encodings will get
@@ -269,37 +282,30 @@ static void do_job( hb_job_t * job, int cpu_count )
                        if (job->acodec == HB_ACODEC_FAAC && job->surround) {
                                /* we're going to be encoding to AAC,
                                and have turned on the "preserve 5.1" flag */
-                               job->channelsused = 6;
+                               audio->channelsused = 6;
                        } else {
                                /* mix 5.1 down to Dolby Digital (2-channel) for
                                non-AAC audio, or for AAC without 5.1 preservation */
-                               job->channelsused = 2;
+                               audio->channelsused = 2;
                        }
                } else if (audio->channels == 1 && audio->lfechannels == 0) {
                        /* we have a 1.0 mono AC-3 source soundtrack */
                        if (job->acodec == HB_ACODEC_FAAC) {
                                /* we're going to be encoding to AAC,
                                so mix down to a mono AAC track */
-                               job->channelsused = 1;
+                               audio->channelsused = 1;
                        } else {
                                /* mix up the mono track to stereo for non-AAC formats */
-                               job->channelsused = 2;
+                               audio->channelsused = 2;
                        }
                } else {
                        /* mix everything else down to stereo */
                        /* dolby pro-logic will be preserved in deca52.c if necessary
-                       by referring to the value of job->ac3flags stored below */
-                       job->channelsused = 2;
+                       by referring to the value of audio->config->a52.ac3flags */
+                       audio->channelsused = 2;
                }
                
-               /* remember the actual number of channels and lfe channels */
-               /* again, we are using the last channel's count for now */
-               job->channels = audio->channels;
-               job->lfechannels = audio->lfechannels;
-               
-               /* remember the AC3 flags for future reference */
-               /* again, we are using the last channel's flags for now */
-               job->ac3flags = audio->ac3flags;
+        audio->config.aac.channelsused = audio->config.a52.channelsused = audio->channelsused;
                
     }
 
@@ -351,6 +357,17 @@ static void do_job( hb_job_t * job, int cpu_count )
         hb_list_rem( job->list_work, w );
         hb_thread_close( &w->thread );
         w->close( w );
+        
+        /* FIXME: This feels really hackish, anything better? */
+        if ( w->id == WORK_DECA52 ||
+             w->id == WORK_DECLPCM ||
+             w->id == WORK_ENCFAAC ||
+             w->id == WORK_ENCLAME ||
+             w->id == WORK_ENCVORBIS )
+        {
+            free( w );
+            w = NULL;
+        }
     }
 
     /* Stop read & write threads */