diff options
-rw-r--r-- | libhb/common.c | 62 | ||||
-rw-r--r-- | libhb/common.h | 83 | ||||
-rw-r--r-- | libhb/deca52.c | 7 | ||||
-rw-r--r-- | libhb/decdca.c | 72 | ||||
-rw-r--r-- | libhb/muxmp4.c | 4 | ||||
-rw-r--r-- | libhb/scan.c | 4 | ||||
-rw-r--r-- | libhb/stream.c | 6 |
7 files changed, 139 insertions, 99 deletions
diff --git a/libhb/common.c b/libhb/common.c index 23c6ea21e..0bc48a842 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -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; - } /********************************************************************** diff --git a/libhb/common.h b/libhb/common.h index ab1a0c169..ac486b4a5 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -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; diff --git a/libhb/deca52.c b/libhb/deca52.c index 09eb88101..f0befdd01 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -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; diff --git a/libhb/decdca.c b/libhb/decdca.c index 49fb3ecae..a459dcd23 100644 --- a/libhb/decdca.c +++ b/libhb/decdca.c @@ -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; diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index cad1d3944..df55db7fd 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -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; } diff --git a/libhb/scan.c b/libhb/scan.c index 1f222ac7a..30d609d23 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -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)" ); } diff --git a/libhb/stream.c b/libhb/stream.c index eb2a42e6f..26de66ee5 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -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 + |