diff options
Diffstat (limited to 'BDInfo/TSCodecAC3.cs')
| -rw-r--r-- | BDInfo/TSCodecAC3.cs | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/BDInfo/TSCodecAC3.cs b/BDInfo/TSCodecAC3.cs new file mode 100644 index 000000000..144141c30 --- /dev/null +++ b/BDInfo/TSCodecAC3.cs @@ -0,0 +1,309 @@ +//============================================================================ +// BDInfo - Blu-ray Video and Audio Analysis Tool +// Copyright © 2010 Cinema Squid +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//============================================================================= + +#undef DEBUG +using System.IO; + +namespace BDInfo +{ + public abstract class TSCodecAC3 + { + private static byte[] eac3_blocks = new byte[] { 1, 2, 3, 6 }; + + public static void Scan( + TSAudioStream stream, + TSStreamBuffer buffer, + ref string tag) + { + if (stream.IsInitialized) return; + + byte[] sync = buffer.ReadBytes(2); + if (sync == null || + sync[0] != 0x0B || + sync[1] != 0x77) + { + return; + } + + int sr_code = 0; + int frame_size = 0; + int frame_size_code = 0; + int channel_mode = 0; + int lfe_on = 0; + int dial_norm = 0; + int num_blocks = 0; + + byte[] hdr = buffer.ReadBytes(4); + int bsid = (hdr[3] & 0xF8) >> 3; + buffer.Seek(-4, SeekOrigin.Current); + if (bsid <= 10) + { + byte[] crc = buffer.ReadBytes(2); + sr_code = buffer.ReadBits(2); + frame_size_code = buffer.ReadBits(6); + bsid = buffer.ReadBits(5); + int bsmod = buffer.ReadBits(3); + + channel_mode = buffer.ReadBits(3); + int cmixlev = 0; + if (((channel_mode & 0x1) > 0) && (channel_mode != 0x1)) + { + cmixlev = buffer.ReadBits(2); + } + int surmixlev = 0; + if ((channel_mode & 0x4) > 0) + { + surmixlev = buffer.ReadBits(2); + } + int dsurmod = 0; + if (channel_mode == 0x2) + { + dsurmod = buffer.ReadBits(2); + if (dsurmod == 0x2) + { + stream.AudioMode = TSAudioMode.Surround; + } + } + lfe_on = buffer.ReadBits(1); + dial_norm = buffer.ReadBits(5); + int compr = 0; + if (1 == buffer.ReadBits(1)) + { + compr = buffer.ReadBits(8); + } + int langcod = 0; + if (1 == buffer.ReadBits(1)) + { + langcod = buffer.ReadBits(8); + } + int mixlevel = 0; + int roomtyp = 0; + if (1 == buffer.ReadBits(1)) + { + mixlevel = buffer.ReadBits(5); + roomtyp = buffer.ReadBits(2); + } + if (channel_mode == 0) + { + int dialnorm2 = buffer.ReadBits(5); + int compr2 = 0; + if (1 == buffer.ReadBits(1)) + { + compr2 = buffer.ReadBits(8); + } + int langcod2 = 0; + if (1 == buffer.ReadBits(1)) + { + langcod2 = buffer.ReadBits(8); + } + int mixlevel2 = 0; + int roomtyp2 = 0; + if (1 == buffer.ReadBits(1)) + { + mixlevel2 = buffer.ReadBits(5); + roomtyp2 = buffer.ReadBits(2); + } + } + int copyrightb = buffer.ReadBits(1); + int origbs = buffer.ReadBits(1); + if (bsid == 6) + { + if (1 == buffer.ReadBits(1)) + { + int dmixmod = buffer.ReadBits(2); + int ltrtcmixlev = buffer.ReadBits(3); + int ltrtsurmixlev = buffer.ReadBits(3); + int lorocmixlev = buffer.ReadBits(3); + int lorosurmixlev = buffer.ReadBits(3); + } + if (1 == buffer.ReadBits(1)) + { + int dsurexmod = buffer.ReadBits(2); + int dheadphonmod = buffer.ReadBits(2); + if (dheadphonmod == 0x2) + { + // TODO + } + int adconvtyp = buffer.ReadBits(1); + int xbsi2 = buffer.ReadBits(8); + int encinfo = buffer.ReadBits(1); + if (dsurexmod == 2) + { + stream.AudioMode = TSAudioMode.Extended; + } + } + } + } + else + { + int frame_type = buffer.ReadBits(2); + int substreamid = buffer.ReadBits(3); + frame_size = (buffer.ReadBits(11) + 1) << 1; + + sr_code = buffer.ReadBits(2); + if (sr_code == 3) + { + sr_code = buffer.ReadBits(2); + } + else + { + num_blocks = buffer.ReadBits(2); + } + channel_mode = buffer.ReadBits(3); + lfe_on = buffer.ReadBits(1); + } + + switch (channel_mode) + { + case 0: // 1+1 + stream.ChannelCount = 2; + if (stream.AudioMode == TSAudioMode.Unknown) + { + stream.AudioMode = TSAudioMode.DualMono; + } + break; + case 1: // 1/0 + stream.ChannelCount = 1; + break; + case 2: // 2/0 + stream.ChannelCount = 2; + if (stream.AudioMode == TSAudioMode.Unknown) + { + stream.AudioMode = TSAudioMode.Stereo; + } + break; + case 3: // 3/0 + stream.ChannelCount = 3; + break; + case 4: // 2/1 + stream.ChannelCount = 3; + break; + case 5: // 3/1 + stream.ChannelCount = 4; + break; + case 6: // 2/2 + stream.ChannelCount = 4; + break; + case 7: // 3/2 + stream.ChannelCount = 5; + break; + default: + stream.ChannelCount = 0; + break; + } + + switch (sr_code) + { + case 0: + stream.SampleRate = 48000; + break; + case 1: + stream.SampleRate = 44100; + break; + case 2: + stream.SampleRate = 32000; + break; + default: + stream.SampleRate = 0; + break; + } + + if (bsid <= 10) + { + switch (frame_size_code >> 1) + { + case 18: + stream.BitRate = 640000; + break; + case 17: + stream.BitRate = 576000; + break; + case 16: + stream.BitRate = 512000; + break; + case 15: + stream.BitRate = 448000; + break; + case 14: + stream.BitRate = 384000; + break; + case 13: + stream.BitRate = 320000; + break; + case 12: + stream.BitRate = 256000; + break; + case 11: + stream.BitRate = 224000; + break; + case 10: + stream.BitRate = 192000; + break; + case 9: + stream.BitRate = 160000; + break; + case 8: + stream.BitRate = 128000; + break; + case 7: + stream.BitRate = 112000; + break; + case 6: + stream.BitRate = 96000; + break; + case 5: + stream.BitRate = 80000; + break; + case 4: + stream.BitRate = 64000; + break; + case 3: + stream.BitRate = 56000; + break; + case 2: + stream.BitRate = 48000; + break; + case 1: + stream.BitRate = 40000; + break; + case 0: + stream.BitRate = 32000; + break; + default: + stream.BitRate = 0; + break; + } + } + else + { + stream.BitRate = (long) + (4.0 * frame_size * stream.SampleRate / (num_blocks * 256)); + } + + stream.LFE = lfe_on; + if (stream.StreamType != TSStreamType.AC3_PLUS_AUDIO && + stream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO) + { + stream.DialNorm = dial_norm - 31; + } + stream.IsVBR = false; + stream.IsInitialized = true; + } + } +} |
