# HG changeset patch # User bwolowiec # Date 1209076033 0 # Node ID 2d0b86dfe5bb3a6e30a363aa15462e6917acdf04 # Parent 33d3c14d5a574a614a8fcb53aadb77f9bf313cd6 add a ff_ac3_parse_header_full() which calls ff_ac3_parse_header() and then reads the channel_map stuff diff -r 33d3c14d5a57 -r 2d0b86dfe5bb ac3.h --- a/ac3.h Thu Apr 24 12:39:25 2008 +0000 +++ b/ac3.h Thu Apr 24 22:27:13 2008 +0000 @@ -97,6 +97,7 @@ 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; diff -r 33d3c14d5a57 -r 2d0b86dfe5bb ac3_parser.c --- a/ac3_parser.c Thu Apr 24 12:39:25 2008 +0000 +++ b/ac3_parser.c Thu Apr 24 22:27:13 2008 +0000 @@ -136,6 +136,35 @@ 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) { diff -r 33d3c14d5a57 -r 2d0b86dfe5bb ac3_parser.h --- a/ac3_parser.h Thu Apr 24 12:39:25 2008 +0000 +++ b/ac3_parser.h Thu Apr 24 22:27:13 2008 +0000 @@ -46,4 +46,15 @@ */ 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 */ diff -r 33d3c14d5a57 -r 2d0b86dfe5bb ac3tab.c --- a/ac3tab.c Thu Apr 24 12:39:25 2008 +0000 +++ b/ac3tab.c Thu Apr 24 22:27:13 2008 +0000 @@ -247,3 +247,16 @@ 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 +}; diff -r 33d3c14d5a57 -r 2d0b86dfe5bb ac3tab.h --- a/ac3tab.h Thu Apr 24 12:39:25 2008 +0000 +++ b/ac3tab.h Thu Apr 24 22:27:13 2008 +0000 @@ -39,5 +39,21 @@ 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 */