//============================================================================ // 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 //============================================================================= namespace BDInfo { public abstract class TSCodecTrueHD { public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, ref string tag) { if (stream.IsInitialized && stream.CoreStream != null && stream.CoreStream.IsInitialized) return; bool syncFound = false; uint sync = 0; for (int i = 0; i < buffer.Length; i++) { sync = (sync << 8) + buffer.ReadByte(); if (sync == 0xF8726FBA) { syncFound = true; break; } } if (!syncFound) { tag = "CORE"; if (stream.CoreStream == null) { stream.CoreStream = new TSAudioStream(); stream.CoreStream.StreamType = TSStreamType.AC3_AUDIO; } if (!stream.CoreStream.IsInitialized) { buffer.BeginRead(); TSCodecAC3.Scan(stream.CoreStream, buffer, ref tag); } return; } tag = "HD"; int ratebits = buffer.ReadBits(4); if (ratebits != 0xF) { stream.SampleRate = (((ratebits & 8) > 0 ? 44100 : 48000) << (ratebits & 7)); } int temp1 = buffer.ReadBits(8); int channels_thd_stream1 = buffer.ReadBits(5); int temp2 = buffer.ReadBits(2); stream.ChannelCount = 0; stream.LFE = 0; int c_LFE2 = buffer.ReadBits(1); if (c_LFE2 == 1) { stream.LFE += 1; } int c_Cvh = buffer.ReadBits(1); if (c_Cvh == 1) { stream.ChannelCount += 1; } int c_LRw = buffer.ReadBits(1); if (c_LRw == 1) { stream.ChannelCount += 2; } int c_LRsd = buffer.ReadBits(1); if (c_LRsd == 1) { stream.ChannelCount += 2; } int c_Ts = buffer.ReadBits(1); if (c_Ts == 1) { stream.ChannelCount += 1; } int c_Cs = buffer.ReadBits(1); if (c_Cs == 1) { stream.ChannelCount += 1; } int c_LRrs = buffer.ReadBits(1); if (c_LRrs == 1) { stream.ChannelCount += 2; } int c_LRc = buffer.ReadBits(1); if (c_LRc == 1) { stream.ChannelCount += 2; } int c_LRvh = buffer.ReadBits(1); if (c_LRvh == 1) { stream.ChannelCount += 2; } int c_LRs = buffer.ReadBits(1); if (c_LRs == 1) { stream.ChannelCount += 2; } int c_LFE = buffer.ReadBits(1); if (c_LFE == 1) { stream.LFE += 1; } int c_C = buffer.ReadBits(1); if (c_C == 1) { stream.ChannelCount += 1; } int c_LR = buffer.ReadBits(1); if (c_LR == 1) { stream.ChannelCount += 2; } int access_unit_size = 40 << (ratebits & 7); int access_unit_size_pow2 = 64 << (ratebits & 7); int a1 = buffer.ReadBits(16); int a2 = buffer.ReadBits(16); int a3 = buffer.ReadBits(16); int is_vbr = buffer.ReadBits(1); int peak_bitrate = buffer.ReadBits(15); peak_bitrate = (peak_bitrate * stream.SampleRate) >> 4; double peak_bitdepth = (double)peak_bitrate / (stream.ChannelCount + stream.LFE) / stream.SampleRate; if (peak_bitdepth > 14) { stream.BitDepth = 24; } else { stream.BitDepth = 16; } #if DEBUG System.Diagnostics.Debug.WriteLine(string.Format( "{0}\t{1}\t{2:F2}", stream.PID, peak_bitrate, peak_bitdepth)); #endif /* // TODO: Get THD dialnorm from metadata if (stream.CoreStream != null) { TSAudioStream coreStream = (TSAudioStream)stream.CoreStream; if (coreStream.DialNorm != 0) { stream.DialNorm = coreStream.DialNorm; } } */ stream.IsVBR = true; stream.IsInitialized = true; } } }