| @@ -124,4 +124,14 @@ static inline uint8_t xor_32_to_8(uint32_t value) | |||||
| return value; | return value; | ||||
| } | } | ||||
| typedef enum THDChannelModifier { | |||||
| THD_CH_MODIFIER_NOTINDICATED = 0x0, | |||||
| THD_CH_MODIFIER_STEREO = 0x0, // Stereo (not Dolby Surround) | |||||
| THD_CH_MODIFIER_LTRT = 0x1, // Dolby Surround | |||||
| THD_CH_MODIFIER_LBINRBIN = 0x2, // Dolby Headphone | |||||
| THD_CH_MODIFIER_MONO = 0x3, // Mono or Dual Mono | |||||
| THD_CH_MODIFIER_NOTSURROUNDEX = 0x1, // Not Dolby Digital EX | |||||
| THD_CH_MODIFIER_SURROUNDEX = 0x2, // Dolby Digital EX | |||||
| } THDChannelModifier; | |||||
| #endif /* AVCODEC_MLP_H */ | #endif /* AVCODEC_MLP_H */ | ||||
| @@ -169,13 +169,16 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) | |||||
| mh->group1_samplerate = mlp_samplerate(ratebits); | mh->group1_samplerate = mlp_samplerate(ratebits); | ||||
| mh->group2_samplerate = 0; | mh->group2_samplerate = 0; | ||||
| skip_bits(gb, 8); | |||||
| skip_bits(gb, 4); | |||||
| mh->channel_modifier_thd_stream0 = get_bits(gb, 2); | |||||
| mh->channel_modifier_thd_stream1 = get_bits(gb, 2); | |||||
| channel_arrangement = get_bits(gb, 5); | channel_arrangement = get_bits(gb, 5); | ||||
| mh->channels_thd_stream1 = truehd_channels(channel_arrangement); | mh->channels_thd_stream1 = truehd_channels(channel_arrangement); | ||||
| mh->channel_layout_thd_stream1 = truehd_layout(channel_arrangement); | mh->channel_layout_thd_stream1 = truehd_layout(channel_arrangement); | ||||
| skip_bits(gb, 2); | |||||
| mh->channel_modifier_thd_stream2 = get_bits(gb, 2); | |||||
| channel_arrangement = get_bits(gb, 13); | channel_arrangement = get_bits(gb, 13); | ||||
| mh->channels_thd_stream2 = truehd_channels(channel_arrangement); | mh->channels_thd_stream2 = truehd_channels(channel_arrangement); | ||||
| @@ -39,6 +39,10 @@ typedef struct MLPHeaderInfo | |||||
| int group1_samplerate; ///< Sample rate of first substream | int group1_samplerate; ///< Sample rate of first substream | ||||
| int group2_samplerate; ///< Sample rate of second substream (MLP only) | int group2_samplerate; ///< Sample rate of second substream (MLP only) | ||||
| int channel_modifier_thd_stream0; ///< Channel modifier for substream 0 of TrueHD sreams ("2-channel presentation") | |||||
| int channel_modifier_thd_stream1; ///< Channel modifier for substream 1 of TrueHD sreams ("6-channel presentation") | |||||
| int channel_modifier_thd_stream2; ///< Channel modifier for substream 2 of TrueHD sreams ("8-channel presentation") | |||||
| int channels_mlp; ///< Channel count for MLP streams | int channels_mlp; ///< Channel count for MLP streams | ||||
| int channels_thd_stream1; ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation") | int channels_thd_stream1; ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation") | ||||
| int channels_thd_stream2; ///< Channel count for substream 2 of TrueHD streams ("8-channel presentation") | int channels_thd_stream2; ///< Channel count for substream 2 of TrueHD streams ("8-channel presentation") | ||||
| @@ -60,6 +60,8 @@ typedef struct SubStream { | |||||
| uint8_t ch_assign[MAX_CHANNELS]; | uint8_t ch_assign[MAX_CHANNELS]; | ||||
| /// The channel layout for this substream | /// The channel layout for this substream | ||||
| uint64_t ch_layout; | uint64_t ch_layout; | ||||
| /// The matrix encoding mode for this substream | |||||
| enum AVMatrixEncoding matrix_encoding; | |||||
| /// Channel coding parameters for channels in the substream | /// Channel coding parameters for channels in the substream | ||||
| ChannelParams channel_params[MAX_CHANNELS]; | ChannelParams channel_params[MAX_CHANNELS]; | ||||
| @@ -374,6 +376,46 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) | |||||
| m->substream[substr].ch_layout = mh.channel_layout_thd_stream1; | m->substream[substr].ch_layout = mh.channel_layout_thd_stream1; | ||||
| } | } | ||||
| /* Parse the TrueHD decoder channel modifiers and set each substream's | |||||
| * AVMatrixEncoding accordingly. | |||||
| * | |||||
| * The meaning of the modifiers depends on the channel layout: | |||||
| * | |||||
| * - THD_CH_MODIFIER_LTRT, THD_CH_MODIFIER_LBINRBIN only apply to 2-channel | |||||
| * | |||||
| * - THD_CH_MODIFIER_MONO applies to 1-channel or 2-channel (dual mono) | |||||
| * | |||||
| * - THD_CH_MODIFIER_SURROUNDEX, THD_CH_MODIFIER_NOTSURROUNDEX only apply to | |||||
| * layouts with an Ls/Rs channel pair | |||||
| */ | |||||
| for (substr = 0; substr < MAX_SUBSTREAMS; substr++) | |||||
| m->substream[substr].matrix_encoding = AV_MATRIX_ENCODING_NONE; | |||||
| if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) { | |||||
| if (mh.num_substreams > 2 && | |||||
| mh.channel_layout_thd_stream2 & AV_CH_SIDE_LEFT && | |||||
| mh.channel_layout_thd_stream2 & AV_CH_SIDE_RIGHT && | |||||
| mh.channel_modifier_thd_stream2 == THD_CH_MODIFIER_SURROUNDEX) | |||||
| m->substream[2].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX; | |||||
| if (mh.num_substreams > 1 && | |||||
| mh.channel_layout_thd_stream1 & AV_CH_SIDE_LEFT && | |||||
| mh.channel_layout_thd_stream1 & AV_CH_SIDE_RIGHT && | |||||
| mh.channel_modifier_thd_stream1 == THD_CH_MODIFIER_SURROUNDEX) | |||||
| m->substream[1].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX; | |||||
| if (mh.num_substreams > 0) | |||||
| switch (mh.channel_modifier_thd_stream0) { | |||||
| case THD_CH_MODIFIER_LTRT: | |||||
| m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBY; | |||||
| break; | |||||
| case THD_CH_MODIFIER_LBINRBIN: | |||||
| m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| return 0; | return 0; | ||||
| } | } | ||||