add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header()
authorBartlomiej Wolowiec <bartek.wolowiec@gmail.com>
Thu, 24 Apr 2008 22:27:13 +0000 (22:27 +0000)
committerBartlomiej Wolowiec <bartek.wolowiec@gmail.com>
Thu, 24 Apr 2008 22:27:13 +0000 (22:27 +0000)
and then reads the channel_map stuff

Originally committed as revision 12944 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/ac3.h
libavcodec/ac3_parser.c
libavcodec/ac3_parser.h
libavcodec/ac3tab.c
libavcodec/ac3tab.h

index cc91f20..e933f86 100644 (file)
@@ -97,6 +97,7 @@ typedef struct {
     uint16_t frame_size;
     int center_mix_level;                   ///< Center mix level index
     int surround_mix_level;                 ///< Surround mix level index
+    uint16_t channel_map;
     /** @} */
 } AC3HeaderInfo;
 
index 471fb4f..a6b9b74 100644 (file)
@@ -136,6 +136,35 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
     return 0;
 }
 
+int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr){
+    int ret, i;
+    ret = ff_ac3_parse_header(gbc, hdr);
+    if(!ret){
+        if(hdr->bitstream_id>10){
+            /* Enhanced AC-3 */
+            skip_bits(gbc, 5); // skip bitstream id
+
+            /* skip dialog normalization and compression gain */
+            for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
+                skip_bits(gbc, 5); // skip dialog normalization
+                if (get_bits1(gbc)) {
+                    skip_bits(gbc, 8); //skip Compression gain word
+                }
+            }
+            /* dependent stream channel map */
+            if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT && get_bits1(gbc)) {
+                    hdr->channel_map = get_bits(gbc, 16); //custom channel map
+                    return 0;
+            }
+        }
+        //default channel map based on acmod and lfeon
+        hdr->channel_map = ff_eac3_default_chmap[hdr->channel_mode];
+        if(hdr->lfe_on)
+            hdr->channel_map |= AC3_CHMAP_LFE;
+    }
+    return ret;
+}
+
 static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
         int *need_next_header, int *new_frame_start)
 {
index 3f19b13..63bea56 100644 (file)
@@ -46,4 +46,15 @@ typedef enum {
  */
 int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr);
 
+/**
+ * Parses AC-3 frame header and sets channel_map
+ * Parses the header up to the lfeon (channel_map in E-AC-3)
+ * element, which is the first 52, 54 or 104 bits depending
+ * on the audio coding mode.
+ * @param gbc[in] BitContext containing the first 54 bits of the frame.
+ * @param hdr[out] Pointer to struct where header info is written.
+ * @return value returned by ff_ac3_parse_header
+ */
+int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr);
+
 #endif /* FFMPEG_AC3_PARSER_H */
index c87200b..66afcd4 100644 (file)
@@ -247,3 +247,16 @@ const uint8_t ff_ac3_critical_band_size_tab[50]={
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
     3, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
 };
+/**
+ * Default channel map for a dependent substream defined by acmod
+ */
+const uint16_t ff_eac3_default_chmap[8] = {
+    AC3_CHMAP_L |               AC3_CHMAP_R, // FIXME Ch1+Ch2
+                  AC3_CHMAP_C,
+    AC3_CHMAP_L |               AC3_CHMAP_R,
+    AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R,
+    AC3_CHMAP_L |               AC3_CHMAP_R |                   AC3_CHMAP_C_SUR,
+    AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R |                   AC3_CHMAP_C_SUR,
+    AC3_CHMAP_L |               AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR,
+    AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR
+};
index deb32b4..9e7728f 100644 (file)
@@ -39,5 +39,21 @@ extern const uint16_t ff_ac3_db_per_bit_tab[4];
 extern const int16_t  ff_ac3_floor_tab[8];
 extern const uint16_t ff_ac3_fast_gain_tab[8];
 extern const uint8_t  ff_ac3_critical_band_size_tab[50];
+extern const uint16_t ff_eac3_default_chmap[8];
+
+/** Custom channel map locations bitmask
+ *  Other channels described in documentation:
+ *      Lc/Rc pair, Lrs/Rrs pair, Ts, Lsd/Rsd pair,
+ *      Lw/Rw pair, Lvh/Rvh pair, Cvh, Reserved, LFE2
+ */
+enum CustomChannelMapLocation{
+    AC3_CHMAP_L=        1<<(15-0),
+    AC3_CHMAP_C=        1<<(15-1),
+    AC3_CHMAP_R=        1<<(15-2),
+    AC3_CHMAP_L_SUR=    1<<(15-3),
+    AC3_CHMAP_R_SUR =   1<<(15-4),
+    AC3_CHMAP_C_SUR=    1<<(15-7),
+    AC3_CHMAP_LFE =     1<<(15-15)
+};
 
 #endif /* FFMPEG_AC3TAB_H */