]> granicus.if.org Git - handbrake/commitdiff
decdca: attempt to fix Dolby Surround and Pro Logic II mixdown. We were doing it...
authorRodeo <tdskywalker@gmail.com>
Sun, 27 May 2012 13:38:41 +0000 (13:38 +0000)
committerRodeo <tdskywalker@gmail.com>
Sun, 27 May 2012 13:38:41 +0000 (13:38 +0000)
This means Dolby Pro Logic II is now only available for sources with at least L, R, C, Ls, Rs channels (as well as any additional channels), due to some libdca limitations. This will eventually go away when we use our own downmixing for all sources.

Further cleanup to follow.

Also cleans up usage of audio->config.in.flags (was audio->config.flags.*).

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

libhb/common.c
libhb/common.h
libhb/deca52.c
libhb/decdca.c
libhb/muxmp4.c
libhb/scan.c
libhb/stream.c

index 23c6ea21ee7f6c1f466139085d1c0b31b973a60c..0bc48a84231f24a29eb64569f290f75fb3644691 100644 (file)
@@ -705,41 +705,33 @@ int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown )
     }
     switch (layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
     {
-        // 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
-            best_mixdown = HB_AMIXDOWN_STEREO;
-            break;
-
         // mono input
         case HB_INPUT_CH_LAYOUT_MONO:
-            // everything else passes through
             best_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
+        // Dolby Pro Logic (a.k.a. Dolby Surround), 4.0 channels (matrix-encoded)
+        // 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:
-            best_mixdown = HB_AMIXDOWN_DOLBY;
-            break;
-
-        // 4 channel discrete
+        // 3 or 4 discrete channels
+        // case HB_INPUT_CH_LAYOUT_3F:   // FIXME: can it be downmixed to Dolby?
+        // case HB_INPUT_CH_LAYOUT_2F1R: // FIXME: can it be downmixed to Dolby?
         case HB_INPUT_CH_LAYOUT_2F2R:
         case HB_INPUT_CH_LAYOUT_3F1R:
             // a52dec and libdca can't upmix to 6ch, 
             // so we must downmix these.
-            best_mixdown = HB_AMIXDOWN_DOLBYPLII;
+            // libdca only supports DPLII if the source is 3F2R to begin with
+            best_mixdown = HB_AMIXDOWN_DOLBY;
             break;
 
-        // 5, 6, 7, or 8 channel discrete
+        // 5 to 8 discrete channels
         case HB_INPUT_CH_LAYOUT_4F2R:
         case HB_INPUT_CH_LAYOUT_3F4R:
         case HB_INPUT_CH_LAYOUT_3F2R:
-            if ( ! ( layout & HB_INPUT_CH_LAYOUT_HAS_LFE ) )
+            if (!(layout & HB_INPUT_CH_LAYOUT_HAS_LFE))
             {
-                // we don't do 5 channel discrete so mixdown to DPLII
+                // we don't do 5-channel discrete
                 // a52dec and libdca can't upmix to 6ch, 
                 // so we must downmix this.
                 best_mixdown = HB_AMIXDOWN_DOLBYPLII;
@@ -759,6 +751,12 @@ int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown )
                 }
             }
             break;
+
+        // stereo input or something not handled above
+        default:
+            // mono gets mixed up to stereo & more than stereo gets mixed down
+            best_mixdown = HB_AMIXDOWN_STEREO;
+            break;
     }
     // return the best that is not greater than the requested mixdown
     // 0 means the caller requested the best available mixdown
@@ -1608,30 +1606,36 @@ hb_audio_t *hb_audio_copy(const hb_audio_t *src)
  *********************************************************************/
 void hb_audio_config_init(hb_audio_config_t * audiocfg)
 {
-    /* Set read only paramaters to invalid values */
-    audiocfg->in.codec = 0xDEADBEEF;
-    audiocfg->in.bitrate = -1;
-    audiocfg->in.samplerate = -1;
-    audiocfg->in.channel_layout = 0;
-    audiocfg->in.channel_map = NULL;
+    /* Set read-only paramaters to invalid values */
+    audiocfg->in.codec = 0;
+    audiocfg->in.codec_param = 0;
+    audiocfg->in.reg_desc = 0;
+    audiocfg->in.stream_type = 0;
+    audiocfg->in.substream_type = 0;
     audiocfg->in.version = 0;
+    audiocfg->in.flags = 0;
     audiocfg->in.mode = 0;
-    audiocfg->flags.ac3 = 0;
+    audiocfg->in.samplerate = -1;
+    audiocfg->in.samples_per_frame = -1;
+    audiocfg->in.bitrate = -1;
+    audiocfg->in.channel_layout = -1;
+    audiocfg->in.channel_map = NULL;
     audiocfg->lang.description[0] = 0;
     audiocfg->lang.simple[0] = 0;
     audiocfg->lang.iso639_2[0] = 0;
 
-    /* Initalize some sensable defaults */
+    /* Initalize some sensible defaults */
     audiocfg->in.track = audiocfg->out.track = 0;
-    audiocfg->out.codec = HB_ACODEC_FAAC;
+    audiocfg->out.codec = hb_audio_encoders[0].encoder;
+    audiocfg->out.samplerate = -1;
+    audiocfg->out.samples_per_frame = -1;
     audiocfg->out.bitrate = -1;
     audiocfg->out.quality = HB_INVALID_AUDIO_QUALITY;
     audiocfg->out.compression_level = -1;
-    audiocfg->out.samplerate = -1;
     audiocfg->out.mixdown = -1;
     audiocfg->out.dynamic_range_compression = 0;
+    audiocfg->out.gain = 0;
     audiocfg->out.name = NULL;
-
 }
 
 /**********************************************************************
index ab1a0c1698fc96f61b78bad8b68a8edc41d24afe..ac486b4a5d30acc61481ad3c4e30767dc715e76d 100644 (file)
@@ -433,12 +433,12 @@ struct hb_job_s
 // DCA_FORMAT of DCA_STEREO                = 2    = 0x002
 // A52_FORMAT of A52_STEREO                = 2    = 0x02
 // discrete channel count of 2
-#define HB_AMIXDOWN_DOLBY                       0x042070A2
-// DCA_FORMAT of DCA_3F1R | DCA_OUT_DPLI   = 519  = 0x207
+#define HB_AMIXDOWN_DOLBY                       0x040000A2
+// DCA_FORMAT handled directly in decdca.c
 // A52_FORMAT of A52_DOLBY                 = 10   = 0x0A
 // discrete channel count of 2
-#define HB_AMIXDOWN_DOLBYPLII                   0x084094A2
-// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII  = 1033 = 0x409
+#define HB_AMIXDOWN_DOLBYPLII                   0x080004A2
+// DCA_FORMAT handled directly in decdca.c
 // A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74   = 0x4A
 // discrete channel count of 2
 #define HB_AMIXDOWN_6CH                         0x10089176
@@ -486,55 +486,44 @@ struct hb_audio_config_s
     /* Output */
     struct
     {
-            int track;      /* Output track number */
-            uint32_t codec;  /* Output audio codec.
-                                 * HB_ACODEC_AC3 means pass-through, then bitrate and samplerate
-                                 * are ignored.
-                                 */
-            int samplerate;         /* Output sample rate (Hz) */
-            int samples_per_frame;  /* Number of samples per frame */
-            int bitrate;            /* Output bitrate (kbps) */
-            float quality;          /* Output quality */
-            float compression_level;  /* Output compression level */
-            int mixdown;            /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */
-            double dynamic_range_compression; /* Amount of DRC that gets applied to this track */
-            double gain;    /* Gain in dB. negative is quieter */
-            char * name;    /* Output track name */
+            int track; /* Output track number */
+            uint32_t codec; /* Output audio codec */
+            int samplerate; /* Output sample rate (Hz) */
+            int samples_per_frame; /* Number of samples per frame */
+            int bitrate; /* Output bitrate (Kbps) */
+            float quality; /* Output quality (encoder-specific) */
+            float compression_level;  /* Output compression level (encoder-specific) */
+            int mixdown; /* The mixdown used for this audio track (see HB_AMIXDOWN_*) */
+            double dynamic_range_compression; /* Amount of DRC applied to this track */
+            double gain; /* Gain (in dB), negative is quieter */
+            char * name; /* Output track name */
     } out;
 
     /* Input */
     struct
     {
-        int track;                /* Input track number */
-        PRIVATE uint32_t codec;   /* Input audio codec */
-        PRIVATE uint32_t reg_desc; /* registration descriptor of source */
-        PRIVATE uint32_t stream_type; /* stream type from source stream */
-        PRIVATE uint32_t substream_type; /* substream for multiplexed streams */
-        PRIVATE uint32_t codec_param; /* per-codec config info */
+        int track; /* Input track number */
+        PRIVATE uint32_t codec; /* Input audio codec */
+        PRIVATE uint32_t codec_param; /* Per-codec config info */
+        PRIVATE uint32_t reg_desc; /* Registration descriptor of source */
+        PRIVATE uint32_t stream_type; /* Stream type from source stream */
+        PRIVATE uint32_t substream_type; /* Substream type for multiplexed streams */
         PRIVATE uint32_t version; /* Bitsream version */
-        PRIVATE uint32_t mode;    /* Bitstream mode, codec dependent encoding */
+        PRIVATE uint32_t flags; /* Bitstream flags, codec-specific */
+        PRIVATE uint32_t mode; /* Bitstream mode, codec-specific */
         PRIVATE int samplerate; /* Input sample rate (Hz) */
         PRIVATE int samples_per_frame; /* Number of samples per frame */
-        PRIVATE int bitrate;    /* Input bitrate (kbps) */
-        PRIVATE int channel_layout; /* channel_layout is the channel layout of this audio this is used to
-                                     * provide a common way of describing the source audio */
-        PRIVATE hb_chan_map_t * channel_map; /* source channel map, set by the audio decoder */
+        PRIVATE int bitrate; /* Input bitrate (bps) */
+        PRIVATE int channel_layout; /* Source channel layout, set by the audio decoder */
+        PRIVATE hb_chan_map_t * channel_map; /* Source channel map, set by the audio decoder */
     } in;
 
-    /* Misc. */
-    union
-    {
-        PRIVATE int ac3;    /* flags.ac3 is only set when the source audio format is HB_ACODEC_AC3 */
-        PRIVATE int dca;    /* flags.dca is only set when the source audio format is HB_ACODEC_DCA */
-    } flags;
-#define AUDIO_F_DOLBY (1 << 31)  /* set if source uses Dolby Surround */
-
     struct
     {
         PRIVATE char description[1024];
         PRIVATE char simple[1024];
         PRIVATE char iso639_2[4];
-        PRIVATE uint8_t type; /* normal, visually impared, directors */
+        PRIVATE uint8_t type; /* normal, visually impaired, director's commentary */
     } lang;
 };
 
@@ -799,15 +788,15 @@ struct hb_state_s
 
 typedef struct hb_work_info_s
 {
-    const char *name;
-    int     profile;
-    int     level;
-    int     bitrate;
-    int     rate;
-    int     rate_base;
-    int     flags;
-    int     version;
-    int     mode;
+    const char * name;
+    int          profile;
+    int          level;
+    int          bitrate;
+    int          rate;
+    int          rate_base;
+    uint32_t     version;
+    uint32_t     flags;
+    uint32_t     mode;
     union {
         struct {    // info only valid for video decoders
             int     width;
index 09eb88101f58bba6f4cb8f73d9bccef5279dd13a..f0befdd014285fd1ac05641e8522ed03a9b8614e 100644 (file)
@@ -418,11 +418,6 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b,
     info->mode = raw & 0x7;      /* bsmod is the following 3 bits */
     info->samples_per_frame = 1536;
 
-    if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY )
-    {
-        info->flags |= AUDIO_F_DOLBY;
-    }
-
     switch( flags & A52_CHANNEL_MASK )
     {
         /* mono sources */
@@ -436,7 +431,7 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b,
         case A52_STEREO:
             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
             break;
-        /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
+        /* Dolby Pro Logic (a.k.a. Dolby Surround), 4.0 channels (matrix-encoded) */
         case A52_DOLBY:
             info->channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
             break;
index 49fb3ecae974cdfdb525aadfed138f8055eff92b..a459dcd23b2242e41c6bc7e331abcb9328288878 100644 (file)
@@ -76,17 +76,66 @@ static int decdcaInit( hb_work_object_t * w, hb_job_t * job )
 
     pv->list      = hb_list_init();
     pv->state     = dca_init( 0 );
+    pv->level     = 1.0;
+
+    /* Decide what format we want out of libdca;
+     * work.c has already done some of this deduction for us in do_job().
+     * Dolby Surround and Pro Logic II are a bit tricky. */
+    int layout = ( audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK );
+    switch( audio->config.out.mixdown )
+    {
+        case HB_AMIXDOWN_DOLBYPLII:
+        {
+            if( layout == HB_INPUT_CH_LAYOUT_3F2R )
+            {
+                // Dolby Pro Logic II output is supported
+                pv->flags_out = ( DCA_3F2R | DCA_OUT_DPLII );
+            }
+            else if( layout == HB_INPUT_CH_LAYOUT_3F1R )
+            {
+                // Dolby Surround output and DCA_3F1R downmix are supported
+                pv->flags_out = ( DCA_3F1R | DCA_OUT_DPLI );
+            }
+            else if( layout > HB_INPUT_CH_LAYOUT_DOLBY )
+            {
+                // Dolby Surround output is supported, but DCA_3F1R downmix isn't
+                pv->flags_out = DCA_DOLBY;
+            }
+            else
+            {
+                // Dolby Surround output not supported OR
+                // Dolby Surround input just gets passed through as is
+                pv->flags_out = DCA_STEREO;
+            }
+        } break;
 
-    /* Decide what format we want out of libdca
-    work.c has already done some of this deduction for us in do_job() */
+        case HB_AMIXDOWN_DOLBY:
+        {
+            if( layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_3F1R )
+            {
+                // Dolby Surround output and DCA_3F1R downmix are supported
+                pv->flags_out = ( DCA_3F1R | DCA_OUT_DPLI );
+            }
+            else if( layout > HB_INPUT_CH_LAYOUT_DOLBY )
+            {
+                // Dolby Surround output is supported, but DCA_3F1R downmix isn't
+                pv->flags_out = DCA_DOLBY;
+            }
+            else
+            {
+                // Dolby Surround output not supported OR
+                // Dolby Surround input just gets passed through as is
+                pv->flags_out = DCA_STEREO;
+            }
+        } break;
 
-    pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(audio->config.out.mixdown);
+        default:
+            pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT( audio->config.out.mixdown );
+            break;
+    }
 
     /* pass the number of channels used into the private work data */
-    /* will only be actually used if we're not doing AC3 passthru */
-    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
-
-    pv->level     = 1.0;
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( audio->config.out.mixdown );
 
     return 0;
 }
@@ -315,11 +364,6 @@ static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
     info->flags = flags;
     info->samples_per_frame = frame_length;
 
-    if ( ( flags & DCA_CHANNEL_MASK) == DCA_DOLBY )
-    {
-        info->flags |= AUDIO_F_DOLBY;
-    }
-
     switch( flags & DCA_CHANNEL_MASK )
     {
         /* mono sources */
@@ -333,6 +377,10 @@ static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
         case DCA_STEREO_TOTAL:
             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
             break;
+        /* Dolby Pro Logic (a.k.a. Dolby Surround), 4.0 channels (matrix-encoded) */
+        case DCA_DOLBY:
+            info->channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
+            break;
         /* 3F/2R input */
         case DCA_3F2R:
             info->channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
index cad1d3944a51edeed4f6ffb73b7c8968cf1b8181..df55db7fdced0d516714678abf616675ce4e5132 100644 (file)
@@ -282,8 +282,8 @@ static int MP4Init( hb_mux_object_t * m )
                 if ( audio->config.out.codec & HB_ACODEC_PASS_FLAG )
                 {
                     bsmod = audio->config.in.mode;
-                    acmod = audio->config.flags.ac3 & 0x7;
-                    lfeon = (audio->config.flags.ac3 & A52_LFE) ? 1 : 0;
+                    acmod = audio->config.in.flags & 0x7;
+                    lfeon = ( audio->config.in.flags & A52_LFE ) ? 1 : 0;
                     freq = audio->config.in.samplerate;
                     bitrate = audio->config.in.bitrate;
                 }
index 1f222ac7a48843ad53b24e3ef6c632a02657ee5f..30d609d239d01f5813cb5cfea30d79cc2fd67815 100644 (file)
@@ -1065,11 +1065,11 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
     audio->config.in.channel_layout = info.channel_layout;
     audio->config.in.channel_map = info.channel_map;
     audio->config.in.version = info.version;
+    audio->config.in.flags = info.flags;
     audio->config.in.mode = info.mode;
-    audio->config.flags.ac3 = info.flags;
 
     // update the audio description string based on the info we found
-    if ( audio->config.flags.ac3 & AUDIO_F_DOLBY )
+    if( audio->config.in.channel_layout == HB_INPUT_CH_LAYOUT_DOLBY )
     {
         strcat( audio->config.lang.description, " (Dolby Surround)" );
     }
index eb2a42e6f32287b31d7127d5d11a405686a764cc..26de66ee5386898512f239c4a6574fa147bc5b7a 100644 (file)
@@ -2039,7 +2039,11 @@ static void set_audio_description(
               sizeof( audio->config.lang.description ), "%s (%s)",
               audio->config.lang.simple, codec_name );
 
-    if ( audio->config.in.channel_layout )
+    if( audio->config.in.channel_layout == HB_INPUT_CH_LAYOUT_DOLBY )
+    {
+        strcat( audio->config.lang.description, " (Dolby Surround)" );
+    }
+    else if( audio->config.in.channel_layout )
     {
         int layout = audio->config.in.channel_layout;
         char *desc = audio->config.lang.description +