(e)ac3: parse and store the Dolby Surround, Surround EX and Headphone mode flags.
authorTim Walker <tdskywalker@gmail.com>
Wed, 11 Dec 2013 02:03:34 +0000 (02:03 +0000)
committerTim Walker <tdskywalker@gmail.com>
Sun, 5 Jan 2014 15:41:56 +0000 (16:41 +0100)
libavcodec/ac3.h
libavcodec/ac3_parser.c
libavcodec/ac3dec.c
libavcodec/ac3dec.h
libavcodec/eac3dec.c

index 647432f..f01da07 100644 (file)
@@ -80,6 +80,30 @@ typedef enum {
     AC3_CHMODE_3F2R
 } 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 {
     int sr_code;
     int sr_shift;
@@ -108,6 +132,7 @@ typedef struct AC3HeaderInfo {
     int surround_mix_level;                 ///< Surround mix level index
     uint16_t channel_map;
     int num_blocks;                         ///< number of audio blocks
+    int dolby_surround_mode;
     /** @} */
 
     /** @name Derived values
index 4abcf16..5ea09f8 100644 (file)
@@ -68,6 +68,9 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
     hdr->center_mix_level   = 5;  // -4.5dB
     hdr->surround_mix_level = 6;  // -6.0dB
 
+    /* set default dolby surround mode */
+    hdr->dolby_surround_mode = AC3_DSURMOD_NOTINDICATED;
+
     if(hdr->bitstream_id <= 10) {
         /* Normal AC-3 */
         hdr->crc1 = get_bits(gbc, 16);
@@ -85,7 +88,7 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
         hdr->channel_mode = get_bits(gbc, 3);
 
         if(hdr->channel_mode == AC3_CHMODE_STEREO) {
-            skip_bits(gbc, 2); // skip dsurmod
+            hdr->dolby_surround_mode = get_bits(gbc, 2);
         } else {
             if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO)
                 hdr->  center_mix_level =   center_levels[get_bits(gbc, 2)];
index e1c6962..2b71c83 100644 (file)
@@ -227,12 +227,26 @@ static int ac3_parse_header(AC3DecodeContext *s)
 
     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 */
-    if (get_bits1(gbc))
-        skip_bits(gbc, 14); //skip timecode1 / xbsi1
-    if (get_bits1(gbc))
-        skip_bits(gbc, 14); //skip timecode2 / xbsi2
+    if (s->bitstream_id != 6) {
+        if (get_bits1(gbc))
+            skip_bits(gbc, 14); //skip timecode1
+        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 */
     if (get_bits1(gbc)) {
@@ -259,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s)
 
     /* get decoding parameters from header info */
     s->bit_alloc_params.sr_code     = hdr.sr_code;
+    s->bitstream_id                 = hdr.bitstream_id;
     s->bitstream_mode               = hdr.bitstream_mode;
     s->channel_mode                 = hdr.channel_mode;
     s->lfe_on                       = hdr.lfe_on;
@@ -274,6 +289,7 @@ static int parse_frame_header(AC3DecodeContext *s)
     s->num_blocks                   = hdr.num_blocks;
     s->frame_type                   = hdr.frame_type;
     s->substreamid                  = hdr.substreamid;
+    s->dolby_surround_mode          = hdr.dolby_surround_mode;
 
     if (s->lfe_on) {
         s->start_freq[s->lfe_ch]     = 0;
@@ -282,7 +298,7 @@ static int parse_frame_header(AC3DecodeContext *s)
         s->channel_in_cpl[s->lfe_ch] = 0;
     }
 
-    if (hdr.bitstream_id <= 10) {
+    if (s->bitstream_id <= 10) {
         s->eac3                  = 0;
         s->snr_offset_strategy   = 2;
         s->block_switch_syntax   = 1;
index 7b4a528..73ca1c3 100644 (file)
@@ -79,6 +79,7 @@ typedef struct AC3DecodeContext {
     int bit_rate;                           ///< stream bit rate, in bits-per-second
     int sample_rate;                        ///< sample frequency, in Hz
     int num_blocks;                         ///< number of audio blocks
+    int bitstream_id;                       ///< bitstream id                           (bsid)
     int bitstream_mode;                     ///< bitstream mode                         (bsmod)
     int channel_mode;                       ///< channel mode                           (acmod)
     int lfe_on;                             ///< lfe channel in use
@@ -86,6 +87,9 @@ typedef struct AC3DecodeContext {
     int center_mix_level;                   ///< Center mix level index
     int surround_mix_level;                 ///< Surround mix level index
     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
index baba454..fb6c51b 100644 (file)
@@ -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 */
     if (get_bits1(gbc)) {
         /* center and surround mix levels */
@@ -413,10 +418,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
         s->bitstream_mode = get_bits(gbc, 3);
         skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
         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) {
-            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++) {
             if (get_bits1(gbc)) {