|
|
|
|
//============================================================================
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|