Commit 13345fc1 authored by Tim Walker's avatar Tim Walker

(e)ac3: parse and store the Dolby Surround, Surround EX and Headphone mode flags.

parent e9212309
...@@ -80,6 +80,30 @@ typedef enum { ...@@ -80,6 +80,30 @@ typedef enum {
AC3_CHMODE_3F2R AC3_CHMODE_3F2R
} AC3ChannelMode; } AC3ChannelMode;
/** Dolby Surround mode */
typedef enum AC3DolbySurroundMode {
AC3_DSURMOD_NOTINDICATED = 0,
AC3_DSURMOD_OFF,
AC3_DSURMOD_ON,
AC3_DSURMOD_RESERVED
} AC3DolbySurroundMode;
/** Dolby Surround EX mode */
typedef enum AC3DolbySurroundEXMode {
AC3_DSUREXMOD_NOTINDICATED = 0,
AC3_DSUREXMOD_OFF,
AC3_DSUREXMOD_ON,
AC3_DSUREXMOD_PLIIZ
} AC3DolbySurroundEXMode;
/** Dolby Headphone mode */
typedef enum AC3DolbyHeadphoneMode {
AC3_DHEADPHONMOD_NOTINDICATED = 0,
AC3_DHEADPHONMOD_OFF,
AC3_DHEADPHONMOD_ON,
AC3_DHEADPHONMOD_RESERVED
} AC3DolbyHeadphoneMode;
typedef struct AC3BitAllocParameters { typedef struct AC3BitAllocParameters {
int sr_code; int sr_code;
int sr_shift; int sr_shift;
...@@ -108,6 +132,7 @@ typedef struct AC3HeaderInfo { ...@@ -108,6 +132,7 @@ typedef struct AC3HeaderInfo {
int surround_mix_level; ///< Surround mix level index int surround_mix_level; ///< Surround mix level index
uint16_t channel_map; uint16_t channel_map;
int num_blocks; ///< number of audio blocks int num_blocks; ///< number of audio blocks
int dolby_surround_mode;
/** @} */ /** @} */
/** @name Derived values /** @name Derived values
......
...@@ -68,6 +68,9 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) ...@@ -68,6 +68,9 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
hdr->center_mix_level = 5; // -4.5dB hdr->center_mix_level = 5; // -4.5dB
hdr->surround_mix_level = 6; // -6.0dB hdr->surround_mix_level = 6; // -6.0dB
/* set default dolby surround mode */
hdr->dolby_surround_mode = AC3_DSURMOD_NOTINDICATED;
if(hdr->bitstream_id <= 10) { if(hdr->bitstream_id <= 10) {
/* Normal AC-3 */ /* Normal AC-3 */
hdr->crc1 = get_bits(gbc, 16); hdr->crc1 = get_bits(gbc, 16);
...@@ -85,7 +88,7 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) ...@@ -85,7 +88,7 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
hdr->channel_mode = get_bits(gbc, 3); hdr->channel_mode = get_bits(gbc, 3);
if(hdr->channel_mode == AC3_CHMODE_STEREO) { if(hdr->channel_mode == AC3_CHMODE_STEREO) {
skip_bits(gbc, 2); // skip dsurmod hdr->dolby_surround_mode = get_bits(gbc, 2);
} else { } else {
if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO)
hdr-> center_mix_level = center_levels[get_bits(gbc, 2)]; hdr-> center_mix_level = center_levels[get_bits(gbc, 2)];
......
...@@ -227,12 +227,26 @@ static int ac3_parse_header(AC3DecodeContext *s) ...@@ -227,12 +227,26 @@ static int ac3_parse_header(AC3DecodeContext *s)
skip_bits(gbc, 2); //skip copyright bit and original bitstream bit skip_bits(gbc, 2); //skip copyright bit and original bitstream bit
/* skip the timecodes (or extra bitstream information for Alternate Syntax) /* default dolby matrix encoding modes */
s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED;
s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED;
/* skip the timecodes or parse the Alternate Bit Stream Syntax
TODO: read & use the xbsi1 downmix levels */ TODO: read & use the xbsi1 downmix levels */
if (get_bits1(gbc)) if (s->bitstream_id != 6) {
skip_bits(gbc, 14); //skip timecode1 / xbsi1 if (get_bits1(gbc))
if (get_bits1(gbc)) skip_bits(gbc, 14); //skip timecode1
skip_bits(gbc, 14); //skip timecode2 / xbsi2 if (get_bits1(gbc))
skip_bits(gbc, 14); //skip timecode2
} else {
if (get_bits1(gbc))
skip_bits(gbc, 14); //skip xbsi1
if (get_bits1(gbc)) {
s->dolby_surround_ex_mode = get_bits(gbc, 2);
s->dolby_headphone_mode = get_bits(gbc, 2);
skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1)
}
}
/* skip additional bitstream info */ /* skip additional bitstream info */
if (get_bits1(gbc)) { if (get_bits1(gbc)) {
...@@ -259,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -259,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s)
/* get decoding parameters from header info */ /* get decoding parameters from header info */
s->bit_alloc_params.sr_code = hdr.sr_code; s->bit_alloc_params.sr_code = hdr.sr_code;
s->bitstream_id = hdr.bitstream_id;
s->bitstream_mode = hdr.bitstream_mode; s->bitstream_mode = hdr.bitstream_mode;
s->channel_mode = hdr.channel_mode; s->channel_mode = hdr.channel_mode;
s->lfe_on = hdr.lfe_on; s->lfe_on = hdr.lfe_on;
...@@ -274,6 +289,7 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -274,6 +289,7 @@ static int parse_frame_header(AC3DecodeContext *s)
s->num_blocks = hdr.num_blocks; s->num_blocks = hdr.num_blocks;
s->frame_type = hdr.frame_type; s->frame_type = hdr.frame_type;
s->substreamid = hdr.substreamid; s->substreamid = hdr.substreamid;
s->dolby_surround_mode = hdr.dolby_surround_mode;
if (s->lfe_on) { if (s->lfe_on) {
s->start_freq[s->lfe_ch] = 0; s->start_freq[s->lfe_ch] = 0;
...@@ -282,7 +298,7 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -282,7 +298,7 @@ static int parse_frame_header(AC3DecodeContext *s)
s->channel_in_cpl[s->lfe_ch] = 0; s->channel_in_cpl[s->lfe_ch] = 0;
} }
if (hdr.bitstream_id <= 10) { if (s->bitstream_id <= 10) {
s->eac3 = 0; s->eac3 = 0;
s->snr_offset_strategy = 2; s->snr_offset_strategy = 2;
s->block_switch_syntax = 1; s->block_switch_syntax = 1;
......
...@@ -79,6 +79,7 @@ typedef struct AC3DecodeContext { ...@@ -79,6 +79,7 @@ typedef struct AC3DecodeContext {
int bit_rate; ///< stream bit rate, in bits-per-second int bit_rate; ///< stream bit rate, in bits-per-second
int sample_rate; ///< sample frequency, in Hz int sample_rate; ///< sample frequency, in Hz
int num_blocks; ///< number of audio blocks int num_blocks; ///< number of audio blocks
int bitstream_id; ///< bitstream id (bsid)
int bitstream_mode; ///< bitstream mode (bsmod) int bitstream_mode; ///< bitstream mode (bsmod)
int channel_mode; ///< channel mode (acmod) int channel_mode; ///< channel mode (acmod)
int lfe_on; ///< lfe channel in use int lfe_on; ///< lfe channel in use
...@@ -86,6 +87,9 @@ typedef struct AC3DecodeContext { ...@@ -86,6 +87,9 @@ typedef struct AC3DecodeContext {
int center_mix_level; ///< Center mix level index int center_mix_level; ///< Center mix level index
int surround_mix_level; ///< Surround mix level index int surround_mix_level; ///< Surround mix level index
int eac3; ///< indicates if current frame is E-AC-3 int eac3; ///< indicates if current frame is E-AC-3
int dolby_surround_mode; ///< dolby surround mode (dsurmod)
int dolby_surround_ex_mode; ///< dolby surround ex mode (dsurexmod)
int dolby_headphone_mode; ///< dolby headphone mode (dheadphonmod)
///@} ///@}
///@name Frame syntax parameters ///@name Frame syntax parameters
......
...@@ -341,6 +341,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s) ...@@ -341,6 +341,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
} }
} }
/* default dolby matrix encoding modes */
s->dolby_surround_mode = AC3_DSURMOD_NOTINDICATED;
s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED;
s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED;
/* mixing metadata */ /* mixing metadata */
if (get_bits1(gbc)) { if (get_bits1(gbc)) {
/* center and surround mix levels */ /* center and surround mix levels */
...@@ -413,10 +418,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s) ...@@ -413,10 +418,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
s->bitstream_mode = get_bits(gbc, 3); s->bitstream_mode = get_bits(gbc, 3);
skip_bits(gbc, 2); // skip copyright bit and original bitstream bit skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
if (s->channel_mode == AC3_CHMODE_STEREO) { if (s->channel_mode == AC3_CHMODE_STEREO) {
skip_bits(gbc, 4); // skip Dolby surround and headphone mode s->dolby_surround_mode = get_bits(gbc, 2);
s->dolby_headphone_mode = get_bits(gbc, 2);
} }
if (s->channel_mode >= AC3_CHMODE_2F2R) { if (s->channel_mode >= AC3_CHMODE_2F2R) {
skip_bits(gbc, 2); // skip Dolby surround EX mode s->dolby_surround_ex_mode = get_bits(gbc, 2);
} }
for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
if (get_bits1(gbc)) { if (get_bits1(gbc)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment