public override TSStream Clone() { TSAudioStream stream = new TSAudioStream(); CopyTo(stream); stream.SampleRate = SampleRate; stream.ChannelLayout = ChannelLayout; stream.ChannelCount = ChannelCount; stream.BitDepth = BitDepth; stream.LFE = LFE; stream.DialNorm = DialNorm; stream.AudioMode = AudioMode; if (CoreStream != null) { stream.CoreStream = (TSAudioStream)CoreStream.Clone(); } return(stream); }
public void Scan() { FileStream fileStream = null; BinaryReader fileReader = null; try { #if DEBUG Debug.WriteLine(string.Format( "Scanning {0}...", Name)); #endif Streams.Clear(); fileStream = File.OpenRead(FileInfo.FullName); fileReader = new BinaryReader(fileStream); byte[] data = new byte[fileStream.Length]; fileReader.Read(data, 0, data.Length); byte[] fileType = new byte[8]; Array.Copy(data, 0, fileType, 0, fileType.Length); FileType = ASCIIEncoding.ASCII.GetString(fileType); if (FileType != "HDMV0100" && FileType != "HDMV0200") { throw new Exception(string.Format( "Clip info file {0} has an unknown file type {1}.", FileInfo.Name, FileType)); } #if DEBUG Debug.WriteLine(string.Format( "\tFileType: {0}", FileType)); #endif int clipIndex = ((int)data[12] << 24) + ((int)data[13] << 16) + ((int)data[14] << 8) + ((int)data[15]); int clipLength = ((int)data[clipIndex] << 24) + ((int)data[clipIndex + 1] << 16) + ((int)data[clipIndex + 2] << 8) + ((int)data[clipIndex + 3]); byte[] clipData = new byte[clipLength]; Array.Copy(data, clipIndex + 4, clipData, 0, clipData.Length); int streamCount = clipData[8]; #if DEBUG Debug.WriteLine(string.Format( "\tStreamCount: {0}", streamCount)); #endif int streamOffset = 10; for (int streamIndex = 0; streamIndex < streamCount; streamIndex++) { TSStream stream = null; ushort PID = (ushort) ((clipData[streamOffset] << 8) + clipData[streamOffset + 1]); streamOffset += 2; TSStreamType streamType = (TSStreamType) clipData[streamOffset + 1]; switch (streamType) { case TSStreamType.MVC_VIDEO: // TODO break; case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.VC1_VIDEO: { TSVideoFormat videoFormat = (TSVideoFormat) (clipData[streamOffset + 2] >> 4); TSFrameRate frameRate = (TSFrameRate) (clipData[streamOffset + 2] & 0xF); TSAspectRatio aspectRatio = (TSAspectRatio) (clipData[streamOffset + 3] >> 4); stream = new TSVideoStream(); ((TSVideoStream)stream).VideoFormat = videoFormat; ((TSVideoStream)stream).AspectRatio = aspectRatio; ((TSVideoStream)stream).FrameRate = frameRate; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", PID, streamType, videoFormat, frameRate, aspectRatio)); #endif } break; case TSStreamType.AC3_AUDIO: case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: case TSStreamType.AC3_TRUE_HD_AUDIO: case TSStreamType.DTS_AUDIO: case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: case TSStreamType.LPCM_AUDIO: case TSStreamType.MPEG1_AUDIO: case TSStreamType.MPEG2_AUDIO: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); TSChannelLayout channelLayout = (TSChannelLayout) (clipData[streamOffset + 2] >> 4); TSSampleRate sampleRate = (TSSampleRate) (clipData[streamOffset + 2] & 0xF); stream = new TSAudioStream(); ((TSAudioStream)stream).LanguageCode = languageCode; ((TSAudioStream)stream).ChannelLayout = channelLayout; ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate); ((TSAudioStream)stream).LanguageCode = languageCode; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", PID, streamType, languageCode, channelLayout, sampleRate)); #endif } break; case TSStreamType.INTERACTIVE_GRAPHICS: case TSStreamType.PRESENTATION_GRAPHICS: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 2, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); stream = new TSGraphicsStream(); stream.LanguageCode = languageCode; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", PID, streamType, languageCode)); #endif } break; case TSStreamType.SUBTITLE: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", PID, streamType, languageCode)); #endif stream = new TSTextStream(); stream.LanguageCode = languageCode; } break; } if (stream != null) { stream.PID = PID; stream.StreamType = streamType; Streams.Add(PID, stream); } streamOffset += clipData[streamOffset] + 1; } IsValid = true; } finally { if (fileReader != null) { fileReader.Close(); } if (fileStream != null) { fileStream.Close(); } } }
public override TSStream Clone() { TSAudioStream stream = new TSAudioStream(); CopyTo(stream); stream.SampleRate = SampleRate; stream.ChannelLayout = ChannelLayout; stream.ChannelCount = ChannelCount; stream.BitDepth = BitDepth; stream.LFE = LFE; stream.DialNorm = DialNorm; stream.AudioMode = AudioMode; if (CoreStream != null) { stream.CoreStream = (TSAudioStream)CoreStream.Clone(); } return stream; }
public void Generate( BDROM BDROM, List <TSPlaylistFile> playlists, ScanBDROMResult scanResult) { Playlists = playlists; StreamWriter reportFile = null; if (BDInfoSettings.AutosaveReport) { string reportName = string.Format( "BDINFO.{0}.txt", BDROM.VolumeLabel); reportFile = File.CreateText(Path.Combine(Environment.CurrentDirectory, reportName)); } textBoxReport.Text = ""; string protection = (BDROM.IsBDPlus ? "BD+" : "AACS"); string bdjava = (BDROM.IsBDJava ? "Yes" : "No"); report += string.Format( "{0,-16}{1}\r\n", "Disc Title:", BDROM.VolumeLabel); report += string.Format( "{0,-16}{1:N0} bytes\r\n", "Disc Size:", BDROM.Size); report += string.Format( "{0,-16}{1}\r\n", "Protection:", protection); report += string.Format( "{0,-16}{1}\r\n", "BD-Java:", bdjava); List <string> extraFeatures = new List <string>(); if (BDROM.Is50Hz) { extraFeatures.Add("50Hz Content"); } if (BDROM.Is3D) { extraFeatures.Add("Blu-ray 3D"); } if (BDROM.IsDBOX) { extraFeatures.Add("D-BOX Motion Code"); } if (BDROM.IsPSP) { extraFeatures.Add("PSP Digital Copy"); } if (extraFeatures.Count > 0) { report += string.Format( "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray())); } report += string.Format( "{0,-16}{1}\r\n", "BDInfo:", Application.ProductVersion); report += "\r\n"; report += string.Format( "{0,-16}{1}\r\n", "Notes:", ""); report += "\r\n"; report += "BDINFO HOME:\r\n"; report += " Cinema Squid\r\n"; report += " http://www.cinemasquid.com/blu-ray/tools/bdinfo\r\n"; report += "\r\n"; report += "INCLUDES FORUMS REPORT FOR:\r\n"; report += " AVS Forum Blu-ray Audio and Video Specifications Thread\r\n"; report += " http://www.avsforum.com/avs-vb/showthread.php?t=1155731\r\n"; report += "\r\n"; if (scanResult.ScanException != null) { report += string.Format( "WARNING: Report is incomplete because: {0}\r\n", scanResult.ScanException.Message); } if (scanResult.FileExceptions.Count > 0) { report += "WARNING: File errors were encountered during scan:\r\n"; foreach (string fileName in scanResult.FileExceptions.Keys) { Exception fileException = scanResult.FileExceptions[fileName]; report += string.Format( "\r\n{0}\t{1}\r\n", fileName, fileException.Message); report += string.Format( "{0}\r\n", fileException.StackTrace); } } foreach (TSPlaylistFile playlist in playlists) { string summary = ""; comboBoxPlaylist.Items.Add(playlist); string title = playlist.Name; string discSize = string.Format( "{0:N0}", BDROM.Size); TimeSpan playlistTotalLength = new TimeSpan((long)(playlist.TotalLength * 10000000)); string totalLength = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds, playlistTotalLength.Milliseconds); string totalLengthShort = string.Format( "{0:D1}:{1:D2}:{2:D2}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds); string totalSize = string.Format( "{0:N0}", playlist.TotalSize); string totalBitrate = string.Format( "{0:F2}", Math.Round((double)playlist.TotalBitRate / 10000) / 100); TimeSpan playlistAngleLength = new TimeSpan((long)(playlist.TotalAngleLength * 10000000)); string totalAngleLength = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistAngleLength.Hours, playlistAngleLength.Minutes, playlistAngleLength.Seconds, playlistAngleLength.Milliseconds); string totalAngleSize = string.Format( "{0:N0}", playlist.TotalAngleSize); string totalAngleBitrate = string.Format( "{0:F2}", Math.Round((double)playlist.TotalAngleBitRate / 10000) / 100); List <string> angleLengths = new List <string>(); List <string> angleSizes = new List <string>(); List <string> angleBitrates = new List <string>(); List <string> angleTotalLengths = new List <string>(); List <string> angleTotalSizes = new List <string>(); List <string> angleTotalBitrates = new List <string>(); if (playlist.AngleCount > 0) { for (int angleIndex = 0; angleIndex < playlist.AngleCount; angleIndex++) { double angleLength = 0; ulong angleSize = 0; ulong angleTotalSize = 0; if (angleIndex < playlist.AngleClips.Count && playlist.AngleClips[angleIndex] != null) { foreach (TSStreamClip clip in playlist.AngleClips[angleIndex].Values) { angleTotalSize += clip.PacketSize; if (clip.AngleIndex == angleIndex + 1) { angleSize += clip.PacketSize; angleLength += clip.Length; } } } angleSizes.Add(string.Format( "{0:N0}", angleSize)); TimeSpan angleTimeSpan = new TimeSpan((long)(angleLength * 10000000)); angleLengths.Add(string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", angleTimeSpan.Hours, angleTimeSpan.Minutes, angleTimeSpan.Seconds, angleTimeSpan.Milliseconds)); angleTotalSizes.Add(string.Format( "{0:N0}", angleTotalSize)); angleTotalLengths.Add(totalLength); double angleBitrate = 0; if (angleLength > 0) { angleBitrate = Math.Round((double)(angleSize * 8) / angleLength / 10000) / 100; } angleBitrates.Add(string.Format("{0:F2}", angleBitrate)); double angleTotalBitrate = 0; if (playlist.TotalLength > 0) { angleTotalBitrate = Math.Round((double)(angleTotalSize * 8) / playlist.TotalLength / 10000) / 100; } angleTotalBitrates.Add(string.Format( "{0:F2}", angleTotalBitrate)); } } string videoCodec = ""; string videoBitrate = ""; if (playlist.VideoStreams.Count > 0) { TSStream videoStream = playlist.VideoStreams[0]; videoCodec = videoStream.CodecAltName; videoBitrate = string.Format( "{0:F2}", Math.Round((double)videoStream.BitRate / 10000) / 100); } string audio1 = ""; string languageCode1 = ""; if (playlist.AudioStreams.Count > 0) { TSAudioStream audioStream = playlist.AudioStreams[0]; languageCode1 = audioStream.LanguageCode; audio1 = string.Format( "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio1 += string.Format( " {0}Kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio1 += string.Format( " ({0}kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } } string audio2 = ""; if (playlist.AudioStreams.Count > 1) { for (int i = 1; i < playlist.AudioStreams.Count; i++) { TSAudioStream audioStream = playlist.AudioStreams[i]; if (audioStream.LanguageCode == languageCode1 && audioStream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO && audioStream.StreamType != TSStreamType.DTS_HD_SECONDARY_AUDIO && !(audioStream.StreamType == TSStreamType.AC3_AUDIO && audioStream.ChannelCount == 2)) { audio2 = string.Format( "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio2 += string.Format( " {0}Kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio2 += string.Format( " ({0}kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } break; } } } report += "\r\n"; report += "********************\r\n"; report += "PLAYLIST: " + playlist.Name + "\r\n"; report += "********************\r\n"; report += "\r\n"; report += "<--- BEGIN FORUMS PASTE --->\r\n"; report += "[code]\r\n"; report += string.Format( "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", "", "", "", "", "", "Total", "Video", "", ""); report += string.Format( "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", "Title", "Codec", "Length", "Movie Size", "Disc Size", "Bitrate", "Bitrate", "Main Audio Track", "Secondary Audio Track"); report += string.Format( "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", "-----", "------", "-------", "--------------", "--------------", "-------", "-------", "------------------", "---------------------"); report += string.Format( "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", title, videoCodec, totalLengthShort, totalSize, discSize, totalBitrate, videoBitrate, audio1, audio2); report += "[/code]\r\n"; report += "\r\n"; report += "[code]\r\n"; report += "\r\n"; report += "DISC INFO:\r\n"; report += "\r\n"; report += string.Format( "{0,-16}{1}\r\n", "Disc Title:", BDROM.VolumeLabel); report += string.Format( "{0,-16}{1:N0} bytes\r\n", "Disc Size:", BDROM.Size); report += string.Format( "{0,-16}{1}\r\n", "Protection:", protection); report += string.Format( "{0,-16}{1}\r\n", "BD-Java:", bdjava); if (extraFeatures.Count > 0) { report += string.Format( "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray())); } report += string.Format( "{0,-16}{1}\r\n", "BDInfo:", Application.ProductVersion); report += "\r\n"; report += "PLAYLIST REPORT:\r\n"; report += "\r\n"; report += string.Format( "{0,-24}{1}\r\n", "Name:", title); report += string.Format( "{0,-24}{1} (h:m:s.ms)\r\n", "Length:", totalLength); report += string.Format( "{0,-24}{1:N0} bytes\r\n", "Size:", totalSize); report += string.Format( "{0,-24}{1} Mbps\r\n", "Total Bitrate:", totalBitrate); if (playlist.AngleCount > 0) { for (int angleIndex = 0; angleIndex < playlist.AngleCount; angleIndex++) { report += "\r\n"; report += string.Format( "{0,-24}{1} (h:m:s.ms) / {2} (h:m:s.ms)\r\n", string.Format("Angle {0} Length:", angleIndex + 1), angleLengths[angleIndex], angleTotalLengths[angleIndex]); report += string.Format( "{0,-24}{1:N0} bytes / {2:N0} bytes\r\n", string.Format("Angle {0} Size:", angleIndex + 1), angleSizes[angleIndex], angleTotalSizes[angleIndex]); report += string.Format( "{0,-24}{1} Mbps / {2} Mbps\r\n", string.Format("Angle {0} Total Bitrate:", angleIndex + 1), angleBitrates[angleIndex], angleTotalBitrates[angleIndex], angleIndex); } report += "\r\n"; report += string.Format( "{0,-24}{1} (h:m:s.ms)\r\n", "All Angles Length:", totalAngleLength); report += string.Format( "{0,-24}{1} bytes\r\n", "All Angles Size:", totalAngleSize); report += string.Format( "{0,-24}{1} Mbps\r\n", "All Angles Bitrate:", totalAngleBitrate); } /* * report += string.Format( * "{0,-24}{1}\r\n", "Description:", ""); */ summary += string.Format( "Disc Title: {0}\r\n", BDROM.VolumeLabel); summary += string.Format( "Disc Size: {0:N0} bytes\r\n", BDROM.Size); summary += string.Format( "Protection: {0}\r\n", protection); summary += string.Format( "BD-Java: {0}\r\n", bdjava); summary += string.Format( "Playlist: {0}\r\n", title); summary += string.Format( "Size: {0:N0} bytes\r\n", totalSize); summary += string.Format( "Length: {0}\r\n", totalLength); summary += string.Format( "Total Bitrate: {0} Mbps\r\n", totalBitrate); if (playlist.HasHiddenTracks) { report += "\r\n(*) Indicates included stream hidden by this playlist.\r\n"; } if (playlist.VideoStreams.Count > 0) { report += "\r\n"; report += "VIDEO:\r\n"; report += "\r\n"; report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", "Codec", "Bitrate", "Description"); report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", "-----", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsVideoStream) { continue; } string streamName = stream.CodecName; if (stream.AngleIndex > 0) { streamName += string.Format( " ({0})", stream.AngleIndex); } string streamBitrate = string.Format( "{0:D}", (int)Math.Round((double)stream.BitRate / 1000)); if (stream.AngleIndex > 0) { streamBitrate += string.Format( " ({0:D})", (int)Math.Round((double)stream.ActiveBitRate / 1000)); } streamBitrate += " kbps"; report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", (stream.IsHidden ? "* " : "") + streamName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Video: {0} / {1} / {2}\r\n", streamName, streamBitrate, stream.Description); } } if (playlist.AudioStreams.Count > 0) { report += "\r\n"; report += "AUDIO:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsAudioStream) { continue; } string streamBitrate = string.Format( "{0:D} kbps", (int)Math.Round((double)stream.BitRate / 1000)); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Audio: {0} / {1} / {2}\r\n", stream.LanguageName, stream.CodecName, stream.Description); } } if (playlist.GraphicsStreams.Count > 0) { report += "\r\n"; report += "SUBTITLES:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsGraphicsStream) { continue; } string streamBitrate = string.Format( "{0:F3} kbps", (double)stream.BitRate / 1000); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Subtitle: {0} / {1}\r\n", stream.LanguageName, streamBitrate, stream.Description); } } if (playlist.TextStreams.Count > 0) { report += "\r\n"; report += "TEXT:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsTextStream) { continue; } string streamBitrate = string.Format( "{0:F3} kbps", (double)stream.BitRate / 1000); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); } } report += "\r\n"; report += "FILES:\r\n"; report += "\r\n"; report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", "Name", "Time In", "Length", "Size", "Total Bitrate"); report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", "----", "-------", "------", "----", "-------------"); foreach (TSStreamClip clip in playlist.StreamClips) { string clipName = clip.DisplayName; if (clip.AngleIndex > 0) { clipName += string.Format( " ({0})", clip.AngleIndex); } string clipSize = string.Format( "{0:N0}", clip.PacketSize); TimeSpan clipInSpan = new TimeSpan((long)(clip.RelativeTimeIn * 10000000)); TimeSpan clipOutSpan = new TimeSpan((long)(clip.RelativeTimeOut * 10000000)); TimeSpan clipLengthSpan = new TimeSpan((long)(clip.Length * 10000000)); string clipTimeIn = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", clipInSpan.Hours, clipInSpan.Minutes, clipInSpan.Seconds, clipInSpan.Milliseconds); string clipLength = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", clipLengthSpan.Hours, clipLengthSpan.Minutes, clipLengthSpan.Seconds, clipLengthSpan.Milliseconds); string clipBitrate = Math.Round( (double)clip.PacketBitRate / 1000).ToString("N0"); report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", clipName, clipTimeIn, clipLength, clipSize, clipBitrate); } report += "\r\n"; report += "CHAPTERS:\r\n"; report += "\r\n"; report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}{5,-16}{6,-16}{7,-16}{8,-16}{9,-16}{10,-16}{11,-16}{12,-16}\r\n", "Number", "Time In", "Length", "Avg Video Rate", "Max 1-Sec Rate", "Max 1-Sec Time", "Max 5-Sec Rate", "Max 5-Sec Time", "Max 10Sec Rate", "Max 10Sec Time", "Avg Frame Size", "Max Frame Size", "Max Frame Time"); report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}{5,-16}{6,-16}{7,-16}{8,-16}{9,-16}{10,-16}{11,-16}{12,-16}\r\n", "------", "-------", "------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------"); Queue <double> window1Bits = new Queue <double>(); Queue <double> window1Seconds = new Queue <double>(); double window1BitsSum = 0; double window1SecondsSum = 0; double window1PeakBitrate = 0; double window1PeakLocation = 0; Queue <double> window5Bits = new Queue <double>(); Queue <double> window5Seconds = new Queue <double>(); double window5BitsSum = 0; double window5SecondsSum = 0; double window5PeakBitrate = 0; double window5PeakLocation = 0; Queue <double> window10Bits = new Queue <double>(); Queue <double> window10Seconds = new Queue <double>(); double window10BitsSum = 0; double window10SecondsSum = 0; double window10PeakBitrate = 0; double window10PeakLocation = 0; double chapterPosition = 0; double chapterBits = 0; long chapterFrameCount = 0; double chapterSeconds = 0; double chapterMaxFrameSize = 0; double chapterMaxFrameLocation = 0; ushort diagPID = playlist.VideoStreams[0].PID; int chapterIndex = 0; int clipIndex = 0; int diagIndex = 0; while (chapterIndex < playlist.Chapters.Count) { TSStreamClip clip = null; TSStreamFile file = null; if (clipIndex < playlist.StreamClips.Count) { clip = playlist.StreamClips[clipIndex]; file = clip.StreamFile; } double chapterStart = playlist.Chapters[chapterIndex]; double chapterEnd; if (chapterIndex < playlist.Chapters.Count - 1) { chapterEnd = playlist.Chapters[chapterIndex + 1]; } else { chapterEnd = playlist.TotalLength; } double chapterLength = chapterEnd - chapterStart; List <TSStreamDiagnostics> diagList = null; if (clip != null && clip.AngleIndex == 0 && file != null && file.StreamDiagnostics.ContainsKey(diagPID)) { diagList = file.StreamDiagnostics[diagPID]; while (diagIndex < diagList.Count && chapterPosition < chapterEnd) { TSStreamDiagnostics diag = diagList[diagIndex++]; if (diag.Marker < clip.TimeIn) { continue; } chapterPosition = diag.Marker - clip.TimeIn + clip.RelativeTimeIn; double seconds = diag.Interval; double bits = diag.Bytes * 8.0; chapterBits += bits; chapterSeconds += seconds; if (diag.Tag != null) { chapterFrameCount++; } window1SecondsSum += seconds; window1Seconds.Enqueue(seconds); window1BitsSum += bits; window1Bits.Enqueue(bits); window5SecondsSum += diag.Interval; window5Seconds.Enqueue(diag.Interval); window5BitsSum += bits; window5Bits.Enqueue(bits); window10SecondsSum += seconds; window10Seconds.Enqueue(seconds); window10BitsSum += bits; window10Bits.Enqueue(bits); if (bits > chapterMaxFrameSize * 8) { chapterMaxFrameSize = bits / 8; chapterMaxFrameLocation = chapterPosition; } if (window1SecondsSum > 1.0) { double bitrate = window1BitsSum / window1SecondsSum; if (bitrate > window1PeakBitrate && chapterPosition - window1SecondsSum > 0) { window1PeakBitrate = bitrate; window1PeakLocation = chapterPosition - window1SecondsSum; } window1BitsSum -= window1Bits.Dequeue(); window1SecondsSum -= window1Seconds.Dequeue(); } if (window5SecondsSum > 5.0) { double bitrate = window5BitsSum / window5SecondsSum; if (bitrate > window5PeakBitrate && chapterPosition - window5SecondsSum > 0) { window5PeakBitrate = bitrate; window5PeakLocation = chapterPosition - window5SecondsSum; if (window5PeakLocation < 0) { window5PeakLocation = 0; window5PeakLocation = 0; } } window5BitsSum -= window5Bits.Dequeue(); window5SecondsSum -= window5Seconds.Dequeue(); } if (window10SecondsSum > 10.0) { double bitrate = window10BitsSum / window10SecondsSum; if (bitrate > window10PeakBitrate && chapterPosition - window10SecondsSum > 0) { window10PeakBitrate = bitrate; window10PeakLocation = chapterPosition - window10SecondsSum; } window10BitsSum -= window10Bits.Dequeue(); window10SecondsSum -= window10Seconds.Dequeue(); } } } if (diagList == null || diagIndex == diagList.Count) { if (clipIndex < playlist.StreamClips.Count) { clipIndex++; diagIndex = 0; } else { chapterPosition = chapterEnd; } } if (chapterPosition >= chapterEnd) { ++chapterIndex; TimeSpan window1PeakSpan = new TimeSpan((long)(window1PeakLocation * 10000000)); TimeSpan window5PeakSpan = new TimeSpan((long)(window5PeakLocation * 10000000)); TimeSpan window10PeakSpan = new TimeSpan((long)(window10PeakLocation * 10000000)); TimeSpan chapterMaxFrameSpan = new TimeSpan((long)(chapterMaxFrameLocation * 10000000)); TimeSpan chapterStartSpan = new TimeSpan((long)(chapterStart * 10000000)); TimeSpan chapterEndSpan = new TimeSpan((long)(chapterEnd * 10000000)); TimeSpan chapterLengthSpan = new TimeSpan((long)(chapterLength * 10000000)); double chapterBitrate = 0; if (chapterLength > 0) { chapterBitrate = chapterBits / chapterLength; } double chapterAvgFrameSize = 0; if (chapterFrameCount > 0) { chapterAvgFrameSize = chapterBits / chapterFrameCount / 8; } report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}{5,-16}{6,-16}{7,-16}{8,-16}{9,-16}{10,-16}{11,-16}{12,-16}\r\n", chapterIndex, string.Format("{0:D1}:{1:D2}:{2:D2}.{3:D3}", chapterStartSpan.Hours, chapterStartSpan.Minutes, chapterStartSpan.Seconds, chapterStartSpan.Milliseconds), string.Format("{0:D1}:{1:D2}:{2:D2}.{3:D3}", chapterLengthSpan.Hours, chapterLengthSpan.Minutes, chapterLengthSpan.Seconds, chapterLengthSpan.Milliseconds), string.Format("{0:N0} kbps", Math.Round(chapterBitrate / 1000)), string.Format("{0:N0} kbps", Math.Round(window1PeakBitrate / 1000)), string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", window1PeakSpan.Hours, window1PeakSpan.Minutes, window1PeakSpan.Seconds, window1PeakSpan.Milliseconds), string.Format("{0:N0} kbps", Math.Round(window5PeakBitrate / 1000)), string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", window5PeakSpan.Hours, window5PeakSpan.Minutes, window5PeakSpan.Seconds, window5PeakSpan.Milliseconds), string.Format("{0:N0} kbps", Math.Round(window10PeakBitrate / 1000)), string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", window10PeakSpan.Hours, window10PeakSpan.Minutes, window10PeakSpan.Seconds, window10PeakSpan.Milliseconds), string.Format("{0:N0} bytes", chapterAvgFrameSize), string.Format("{0:N0} bytes", chapterMaxFrameSize), string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", chapterMaxFrameSpan.Hours, chapterMaxFrameSpan.Minutes, chapterMaxFrameSpan.Seconds, chapterMaxFrameSpan.Milliseconds)); window1Bits = new Queue <double>(); window1Seconds = new Queue <double>(); window1BitsSum = 0; window1SecondsSum = 0; window1PeakBitrate = 0; window1PeakLocation = 0; window5Bits = new Queue <double>(); window5Seconds = new Queue <double>(); window5BitsSum = 0; window5SecondsSum = 0; window5PeakBitrate = 0; window5PeakLocation = 0; window10Bits = new Queue <double>(); window10Seconds = new Queue <double>(); window10BitsSum = 0; window10SecondsSum = 0; window10PeakBitrate = 0; window10PeakLocation = 0; chapterBits = 0; chapterSeconds = 0; chapterFrameCount = 0; chapterMaxFrameSize = 0; chapterMaxFrameLocation = 0; } } if (BDInfoSettings.GenerateStreamDiagnostics) { report += "\r\n"; report += "STREAM DIAGNOSTICS:\r\n"; report += "\r\n"; report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-24}{5,-24}{6,-24}{7,-16}{8,-16}\r\n", "File", "PID", "Type", "Codec", "Language", "Seconds", "Bitrate", "Bytes", "Packets"); report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-24}{5,-24}{6,-24}{7,-16}{8,-16}\r\n", "----", "---", "----", "-----", "--------", "--------------", "--------------", "-------------", "-----", "-------"); Dictionary <string, TSStreamClip> reportedClips = new Dictionary <string, TSStreamClip>(); foreach (TSStreamClip clip in playlist.StreamClips) { if (clip.StreamFile == null) { continue; } if (reportedClips.ContainsKey(clip.Name)) { continue; } reportedClips[clip.Name] = clip; string clipName = clip.DisplayName; if (clip.AngleIndex > 0) { clipName += string.Format(" ({0})", clip.AngleIndex); } foreach (TSStream clipStream in clip.StreamFile.Streams.Values) { if (!playlist.Streams.ContainsKey(clipStream.PID)) { continue; } TSStream playlistStream = playlist.Streams[clipStream.PID]; string clipBitRate = "0"; string clipSeconds = "0"; if (clip.StreamFile.Length > 0) { clipSeconds = clip.StreamFile.Length.ToString("F3"); clipBitRate = Math.Round( (double)clipStream.PayloadBytes * 8 / clip.StreamFile.Length / 1000).ToString("N0"); } string language = ""; if (playlistStream.LanguageCode != null && playlistStream.LanguageCode.Length > 0) { language = string.Format( "{0} ({1})", playlistStream.LanguageCode, playlistStream.LanguageName); } report += string.Format( "{0,-16}{1,-16}{2,-16}{3,-16}{4,-24}{5,-24}{6,-24}{7,-16}{8,-16}\r\n", clipName, string.Format("{0} (0x{1:X})", clipStream.PID, clipStream.PID), string.Format("0x{0:X2}", (byte)clipStream.StreamType), clipStream.CodecShortName, language, clipSeconds, clipBitRate, clipStream.PayloadBytes.ToString("N0"), clipStream.PacketCount.ToString("N0")); } } } report += "\r\n"; report += "[/code]\r\n"; report += "<---- END FORUMS PASTE ---->\r\n"; report += "\r\n"; if (BDInfoSettings.GenerateTextSummary) { report += "QUICK SUMMARY:\r\n\r\n"; report += summary; report += "\r\n"; } if (BDInfoSettings.AutosaveReport && reportFile != null) { try { reportFile.Write(report); } catch { } } textBoxReport.Text += report; report = ""; GC.Collect(); } if (BDInfoSettings.AutosaveReport && reportFile != null) { try { reportFile.Write(report); } catch { } } textBoxReport.Text += report; if (reportFile != null) { reportFile.Close(); } textBoxReport.Select(0, 0); comboBoxPlaylist.SelectedIndex = 0; comboBoxChartType.SelectedIndex = 0; }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag) { if (stream.IsInitialized) return; bool syncFound = false; uint sync = 0; for (int i = 0; i < buffer.Length; i++) { sync = (sync << 8) + buffer.ReadByte(); if (sync == 0x7FFE8001) { syncFound = true; break; } } if (!syncFound) return; int frame_type = buffer.ReadBits(1); int samples_deficit = buffer.ReadBits(5); int crc_present = buffer.ReadBits(1); int sample_blocks = buffer.ReadBits(7); int frame_size = buffer.ReadBits(14); if (frame_size < 95) { return; } int amode = buffer.ReadBits(6); int sample_rate = buffer.ReadBits(4); if (sample_rate < 0 || sample_rate >= dca_sample_rates.Length) { return; } int bit_rate = buffer.ReadBits(5); if (bit_rate < 0 || bit_rate >= dca_bit_rates.Length) { return; } int downmix = buffer.ReadBits(1); int dynrange = buffer.ReadBits(1); int timestamp = buffer.ReadBits(1); int aux_data = buffer.ReadBits(1); int hdcd = buffer.ReadBits(1); int ext_descr = buffer.ReadBits(3); int ext_coding = buffer.ReadBits(1); int aspf = buffer.ReadBits(1); int lfe = buffer.ReadBits(2); int predictor_history = buffer.ReadBits(1); if (crc_present == 1) { int crc = buffer.ReadBits(16); } int multirate_inter = buffer.ReadBits(1); int version = buffer.ReadBits(4); int copy_history = buffer.ReadBits(2); int source_pcm_res = buffer.ReadBits(3); int front_sum = buffer.ReadBits(1); int surround_sum = buffer.ReadBits(1); int dialog_norm = buffer.ReadBits(4); if (source_pcm_res < 0 || source_pcm_res >= dca_bits_per_sample.Length) { return; } int subframes = buffer.ReadBits(4); int total_channels = buffer.ReadBits(3) + 1 + ext_coding; stream.SampleRate = dca_sample_rates[sample_rate]; stream.ChannelCount = total_channels; stream.LFE = (lfe > 0 ? 1 : 0); stream.BitDepth = dca_bits_per_sample[source_pcm_res]; stream.DialNorm = -dialog_norm; if ((source_pcm_res & 0x1) == 0x1) { stream.AudioMode = TSAudioMode.Extended; } stream.BitRate = (uint)dca_bit_rates[bit_rate]; switch (stream.BitRate) { case 1: if (bitrate > 0) { stream.BitRate = bitrate; stream.IsVBR = false; stream.IsInitialized = true; } else { stream.BitRate = 0; } break; case 2: case 3: stream.IsVBR = true; stream.IsInitialized = true; break; default: stream.IsVBR = false; stream.IsInitialized = true; break; } }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, ref string tag) { if (stream.IsInitialized) { return; } byte[] header = buffer.ReadBytes(4); int flags = (header[2] << 8) + header[3]; switch ((flags & 0xF000) >> 12) { case 1: // 1/0/0 stream.ChannelCount = 1; stream.LFE = 0; break; case 3: // 2/0/0 stream.ChannelCount = 2; stream.LFE = 0; break; case 4: // 3/0/0 stream.ChannelCount = 3; stream.LFE = 0; break; case 5: // 2/1/0 stream.ChannelCount = 3; stream.LFE = 0; break; case 6: // 3/1/0 stream.ChannelCount = 4; stream.LFE = 0; break; case 7: // 2/2/0 stream.ChannelCount = 4; stream.LFE = 0; break; case 8: // 3/2/0 stream.ChannelCount = 5; stream.LFE = 0; break; case 9: // 3/2/1 stream.ChannelCount = 5; stream.LFE = 1; break; case 10: // 3/4/0 stream.ChannelCount = 7; stream.LFE = 0; break; case 11: // 3/4/1 stream.ChannelCount = 7; stream.LFE = 1; break; default: stream.ChannelCount = 0; stream.LFE = 0; break; } switch ((flags & 0xC0) >> 6) { case 1: stream.BitDepth = 16; break; case 2: stream.BitDepth = 20; break; case 3: stream.BitDepth = 24; break; default: stream.BitDepth = 0; break; } switch ((flags & 0xF00) >> 8) { case 1: stream.SampleRate = 48000; break; case 4: stream.SampleRate = 96000; break; case 5: stream.SampleRate = 192000; break; default: stream.SampleRate = 0; break; } stream.BitRate = (uint) (stream.SampleRate * stream.BitDepth * (stream.ChannelCount + stream.LFE)); stream.IsVBR = false; stream.IsInitialized = true; }
public void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag, long?bitrate) { if (stream.IsInitialized) { return; } var sync = buffer.ReadBytes(2); if (sync == null || sync[0] != 0x0B || sync[1] != 0x77) { return; } var secondFrame = stream.ChannelCount > 0; uint srCode; uint frameSize = 0; uint frameSizeCode = 0; uint channelMode; uint lfeOn; uint dialNorm = 0; uint dialNormExt = 0; uint numBlocks = 0; var hdr = buffer.ReadBytes(4); var bsid = (uint)((hdr[3] & 0xF8) >> 3); buffer.Seek(-4, SeekOrigin.Current); if (bsid <= 10) { buffer.BSSkipBytes(2); srCode = buffer.ReadBits2(2); frameSizeCode = buffer.ReadBits2(6); bsid = buffer.ReadBits2(5); buffer.BSSkipBits(3); channelMode = buffer.ReadBits2(3); if ((channelMode & 0x1) > 0 && channelMode != 0x1) { buffer.BSSkipBits(2); } if ((channelMode & 0x4) > 0) { buffer.BSSkipBits(2); } if (channelMode == 0x2) { var dsurmod = buffer.ReadBits2(2); if (dsurmod == 0x2) { stream.AudioMode = TSAudioMode.Surround; } } lfeOn = buffer.ReadBits2(1); dialNorm = buffer.ReadBits2(5); if (buffer.ReadBool()) { buffer.BSSkipBits(8); } if (buffer.ReadBool()) { buffer.BSSkipBits(8); } if (buffer.ReadBool()) { buffer.BSSkipBits(7); } if (channelMode == 0) { buffer.BSSkipBits(5); if (buffer.ReadBool()) { buffer.BSSkipBits(8); } if (buffer.ReadBool()) { buffer.BSSkipBits(8); } if (buffer.ReadBool()) { buffer.BSSkipBits(7); } } buffer.BSSkipBits(2); if (bsid == 6) { if (buffer.ReadBool()) { buffer.BSSkipBits(14); } if (buffer.ReadBool()) { uint dsurexmod = buffer.ReadBits2(2); uint dheadphonmod = buffer.ReadBits2(2); if (dheadphonmod == 0x2) { // TODO } buffer.BSSkipBits(10); if (dsurexmod == 2) { stream.AudioMode = TSAudioMode.Extended; } } } } else { uint frameType = buffer.ReadBits2(2); buffer.BSSkipBits(3); frameSize = (buffer.ReadBits4(11) + 1) << 1; srCode = buffer.ReadBits2(2); if (srCode == 3) { srCode = buffer.ReadBits2(2); numBlocks = 3; } else { numBlocks = buffer.ReadBits2(2); } channelMode = buffer.ReadBits2(3); lfeOn = buffer.ReadBits2(1); bsid = buffer.ReadBits2(5); dialNormExt = buffer.ReadBits2(5); if (buffer.ReadBool()) { buffer.BSSkipBits(8); } if (channelMode == 0) // 1+1 { buffer.BSSkipBits(5); if (buffer.ReadBool()) { buffer.BSSkipBits(8); } } if (frameType == 1) //dependent stream { stream.CoreStream = (TSAudioStream)stream.Clone(); stream.CoreStream.StreamType = TSStreamType.AC3_AUDIO; if (buffer.ReadBool()) //channel remapping { var chanmap = buffer.ReadBits4(16); stream.ChannelCount = stream.CoreStream.ChannelCount; stream.ChannelCount += AC3ChanMap((int)chanmap); lfeOn = (uint)stream.CoreStream.LFE; } } var emdfFound = false; do { var emdfSync = buffer.ReadBits4(16); if (emdfSync == 0x5838) { emdfFound = true; break; } buffer.Seek(-2, SeekOrigin.Current); buffer.BSSkipBits(1); // skip 1 bit } while (buffer.Position < buffer.Length); if (emdfFound) { var emdfContainerSize = buffer.ReadBits4(16); var remainAfterEmdf = buffer.DataBitStreamRemain() - emdfContainerSize * 8; uint emdfVersion = buffer.ReadBits2(2); //emdf_version if (emdfVersion == 3) { emdfVersion += buffer.ReadBits2(2); } if (emdfVersion > 0) { buffer.BSSkipBits((int)(buffer.DataBitStreamRemain() - remainAfterEmdf)); } else { var temp = buffer.ReadBits2(3); if (temp == 0x7) { buffer.BSSkipBits(2); //skip 3 bits } var emdfPayloadID = buffer.ReadBits2(5); if (emdfPayloadID > 0 && emdfPayloadID < 16) { if (emdfPayloadID == 0x1F) { buffer.BSSkipBits(5); //skip 5 bits } EmdfPayloadConfig(buffer); var emdfPayloadSize = buffer.ReadBits2(8) * 8; buffer.BSSkipBits(emdfPayloadSize + 1); } while ((emdfPayloadID = buffer.ReadBits2(5)) != 14 && buffer.Position < buffer.Length) { if (emdfPayloadID == 0x1F) { buffer.BSSkipBits(5); //skip 5 bits } EmdfPayloadConfig(buffer); var emdfPayloadSize = buffer.ReadBits2(8) * 8; buffer.ReadBits4(emdfPayloadSize + 1); } if (buffer.Position < buffer.Length && emdfPayloadID == 14) { EmdfPayloadConfig(buffer); buffer.BSSkipBits(12); uint jocNumObjectsBits = buffer.ReadBits2(6); if (jocNumObjectsBits > 0) { stream.HasExtensions = true; } } } } } if (channelMode < 8 && stream.ChannelCount == 0) { stream.ChannelCount = AC3Channels[channelMode]; } if (stream.AudioMode == TSAudioMode.Unknown) { switch (channelMode) { case 0: // 1+1 stream.AudioMode = TSAudioMode.DualMono; break; case 2: // 2/0 stream.AudioMode = TSAudioMode.Stereo; break; default: stream.AudioMode = TSAudioMode.Unknown; break; } } switch (srCode) { 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) { var fSize = frameSizeCode >> 1; if (fSize < 19) { stream.BitRate = AC3Bitrate[fSize] * 1000; } } else { stream.BitRate = (long)(4.0 * frameSize * stream.SampleRate / (numBlocks * 256)); if (stream.CoreStream != null) { stream.BitRate += stream.CoreStream.BitRate; } } stream.LFE = (int)lfeOn; if (stream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO) { if (stream.StreamType == TSStreamType.AC3_PLUS_AUDIO && bsid == 6 || stream.StreamType == TSStreamType.AC3_AUDIO) { stream.DialNorm = (int)dialNorm * -1; } else if (stream.StreamType == TSStreamType.AC3_PLUS_AUDIO && secondFrame) { stream.DialNorm = (int)dialNormExt * -1; } } stream.IsVBR = false; if (stream.StreamType == TSStreamType.AC3_PLUS_AUDIO && bsid == 6 && !secondFrame) { stream.IsInitialized = false; } else { stream.IsInitialized = true; } }
public static int CompareAudioStreams( TSAudioStream x, TSAudioStream y) { if (x == y) { return 0; } else if (x == null && y == null) { return 0; } else if (x == null && y != null) { return -1; } else if (x != null && y == null) { return 1; } else { if (x.ChannelCount > y.ChannelCount) { return -1; } else if (y.ChannelCount > x.ChannelCount) { return 1; } else { int sortX = GetStreamTypeSortIndex(x.StreamType); int sortY = GetStreamTypeSortIndex(y.StreamType); if (sortX > sortY) { return -1; } else if (sortY > sortX) { return 1; } else { if (x.LanguageCode == "eng") { return -1; } else if (y.LanguageCode == "eng") { return 1; } else { return string.Compare( x.LanguageName, y.LanguageName); } } } } }
protected TSStream CreatePlaylistStream(byte[] data, ref int pos) { TSStream stream = null; int start = pos; int headerLength = data[pos++]; int headerPos = pos; int headerType = data[pos++]; int pid = 0; int subpathid = 0; int subclipid = 0; switch (headerType) { case 1: pid = ReadInt16(data, ref pos); break; case 2: subpathid = data[pos++]; subclipid = data[pos++]; pid = ReadInt16(data, ref pos); break; case 3: subpathid = data[pos++]; pid = ReadInt16(data, ref pos); break; case 4: subpathid = data[pos++]; subclipid = data[pos++]; pid = ReadInt16(data, ref pos); break; default: break; } pos = headerPos + headerLength; int streamLength = data[pos++]; int streamPos = pos; var streamType = (TSStreamType)data[pos++]; switch (streamType) { case TSStreamType.MVC_VIDEO: // TODO break; case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.VC1_VIDEO: var videoFormat = (TSVideoFormat) (data[pos] >> 4); var frameRate = (TSFrameRate) (data[pos] & 0xF); var aspectRatio = (TSAspectRatio) (data[pos + 1] >> 4); stream = new TSVideoStream(); ((TSVideoStream)stream).VideoFormat = videoFormat; ((TSVideoStream)stream).AspectRatio = aspectRatio; ((TSVideoStream)stream).FrameRate = frameRate; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", pid, streamType, videoFormat, frameRate, aspectRatio)); #endif break; case TSStreamType.AC3_AUDIO: case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: case TSStreamType.AC3_TRUE_HD_AUDIO: case TSStreamType.DTS_AUDIO: case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: case TSStreamType.LPCM_AUDIO: case TSStreamType.MPEG1_AUDIO: case TSStreamType.MPEG2_AUDIO: int audioFormat = ReadByte(data, ref pos); var channelLayout = (TSChannelLayout) (audioFormat >> 4); var sampleRate = (TSSampleRate) (audioFormat & 0xF); string audioLanguage = ReadString(data, 3, ref pos); stream = new TSAudioStream(); ((TSAudioStream)stream).ChannelLayout = channelLayout; ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate); ((TSAudioStream)stream).LanguageCode = audioLanguage; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", pid, streamType, audioLanguage, channelLayout, sampleRate)); #endif break; case TSStreamType.INTERACTIVE_GRAPHICS: case TSStreamType.PRESENTATION_GRAPHICS: string graphicsLanguage = ReadString(data, 3, ref pos); stream = new TSGraphicsStream(); ((TSGraphicsStream)stream).LanguageCode = graphicsLanguage; if (data[pos] != 0) { } #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", pid, streamType, graphicsLanguage)); #endif break; case TSStreamType.SUBTITLE: int code = ReadByte(data, ref pos); // TODO string textLanguage = ReadString(data, 3, ref pos); stream = new TSTextStream(); ((TSTextStream)stream).LanguageCode = textLanguage; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", pid, streamType, textLanguage)); #endif break; default: break; } pos = streamPos + streamLength; if (stream != null) { stream.PID = (ushort)pid; stream.StreamType = streamType; } return(stream); }
private void LoadStreamClips() { AngleClips.Clear(); if (AngleCount > 0) { for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++) { AngleClips.Add(new Dictionary <double, TSStreamClip>()); } } TSStreamClip referenceClip = null; if (StreamClips.Count > 0) { referenceClip = StreamClips[0]; } foreach (TSStreamClip clip in StreamClips) { if (clip.StreamClipFile.Streams.Count > referenceClip.StreamClipFile.Streams.Count) { referenceClip = clip; } else if (clip.Length > referenceClip.Length) { referenceClip = clip; } if (AngleCount > 0) { if (clip.AngleIndex == 0) { for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++) { AngleClips[angleIndex][clip.RelativeTimeIn] = clip; } } else { AngleClips[clip.AngleIndex - 1][clip.RelativeTimeIn] = clip; } } } foreach (TSStream clipStream in referenceClip.StreamClipFile.Streams.Values) { if (!Streams.ContainsKey(clipStream.PID)) { TSStream stream = clipStream.Clone(); Streams[clipStream.PID] = stream; if (!IsCustom && !PlaylistStreams.ContainsKey(stream.PID)) { stream.IsHidden = true; HasHiddenTracks = true; } if (stream.IsVideoStream) { VideoStreams.Add((TSVideoStream)stream); } else if (stream.IsAudioStream) { AudioStreams.Add((TSAudioStream)stream); } else if (stream.IsGraphicsStream) { GraphicsStreams.Add((TSGraphicsStream)stream); } else if (stream.IsTextStream) { TextStreams.Add((TSTextStream)stream); } } } if (referenceClip.StreamFile != null) { // TODO: Better way to add this in? if (_settings.EnableSSIF && referenceClip.StreamFile.InterleavedFile != null && referenceClip.StreamFile.Streams.ContainsKey(4114) && !Streams.ContainsKey(4114)) { TSStream stream = referenceClip.StreamFile.Streams[4114].Clone(); Streams[4114] = stream; if (stream.IsVideoStream) { VideoStreams.Add((TSVideoStream)stream); } } foreach (TSStream clipStream in referenceClip.StreamFile.Streams.Values) { if (Streams.ContainsKey(clipStream.PID)) { TSStream stream = Streams[clipStream.PID]; if (stream.StreamType != clipStream.StreamType) { continue; } if (clipStream.BitRate > stream.BitRate) { stream.BitRate = clipStream.BitRate; } stream.IsVBR = clipStream.IsVBR; if (stream.IsVideoStream && clipStream.IsVideoStream) { ((TSVideoStream)stream).EncodingProfile = ((TSVideoStream)clipStream).EncodingProfile; } else if (stream.IsAudioStream && clipStream.IsAudioStream) { TSAudioStream audioStream = (TSAudioStream)stream; TSAudioStream clipAudioStream = (TSAudioStream)clipStream; if (clipAudioStream.ChannelCount > audioStream.ChannelCount) { audioStream.ChannelCount = clipAudioStream.ChannelCount; } if (clipAudioStream.LFE > audioStream.LFE) { audioStream.LFE = clipAudioStream.LFE; } if (clipAudioStream.SampleRate > audioStream.SampleRate) { audioStream.SampleRate = clipAudioStream.SampleRate; } if (clipAudioStream.BitDepth > audioStream.BitDepth) { audioStream.BitDepth = clipAudioStream.BitDepth; } if (clipAudioStream.DialNorm < audioStream.DialNorm) { audioStream.DialNorm = clipAudioStream.DialNorm; } if (clipAudioStream.AudioMode != TSAudioMode.Unknown) { audioStream.AudioMode = clipAudioStream.AudioMode; } if (clipAudioStream.CoreStream != null && audioStream.CoreStream == null) { audioStream.CoreStream = (TSAudioStream) clipAudioStream.CoreStream.Clone(); } } } } } for (int i = 0; i < AngleCount; i++) { AngleStreams.Add(new Dictionary <ushort, TSStream>()); } if (!_settings.KeepStreamOrder) { VideoStreams.Sort(CompareVideoStreams); } foreach (TSStream stream in VideoStreams) { SortedStreams.Add(stream); for (int i = 0; i < AngleCount; i++) { TSStream angleStream = stream.Clone(); angleStream.AngleIndex = i + 1; AngleStreams[i][angleStream.PID] = angleStream; SortedStreams.Add(angleStream); } } if (!_settings.KeepStreamOrder) { AudioStreams.Sort(CompareAudioStreams); } foreach (TSStream stream in AudioStreams) { SortedStreams.Add(stream); } if (!_settings.KeepStreamOrder) { GraphicsStreams.Sort(CompareGraphicsStreams); } foreach (TSStream stream in GraphicsStreams) { SortedStreams.Add(stream); } if (!_settings.KeepStreamOrder) { TextStreams.Sort(CompareTextStreams); } foreach (TSStream stream in TextStreams) { SortedStreams.Add(stream); } }
protected TSStream CreatePlaylistStream(byte[] data, ref int pos) { TSStream stream = null; int start = pos; int headerLength = data[pos++]; int headerPos = pos; int headerType = data[pos++]; int pid = 0; int subpathid = 0; int subclipid = 0; switch (headerType) { case 1: pid = ReadInt16(data, ref pos); break; case 2: subpathid = data[pos++]; subclipid = data[pos++]; pid = ReadInt16(data, ref pos); break; case 3: subpathid = data[pos++]; pid = ReadInt16(data, ref pos); break; case 4: subpathid = data[pos++]; subclipid = data[pos++]; pid = ReadInt16(data, ref pos); break; default: break; } pos = headerPos + headerLength; int streamLength = data[pos++]; int streamPos = pos; TSStreamType streamType = (TSStreamType)data[pos++]; switch (streamType) { case TSStreamType.MVC_VIDEO: // TODO break; case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.VC1_VIDEO: TSVideoFormat videoFormat = (TSVideoFormat) (data[pos] >> 4); TSFrameRate frameRate = (TSFrameRate) (data[pos] & 0xF); TSAspectRatio aspectRatio = (TSAspectRatio) (data[pos + 1] >> 4); stream = new TSVideoStream(); ((TSVideoStream)stream).VideoFormat = videoFormat; ((TSVideoStream)stream).AspectRatio = aspectRatio; ((TSVideoStream)stream).FrameRate = frameRate; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", pid, streamType, videoFormat, frameRate, aspectRatio)); #endif break; case TSStreamType.AC3_AUDIO: case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: case TSStreamType.AC3_TRUE_HD_AUDIO: case TSStreamType.DTS_AUDIO: case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: case TSStreamType.LPCM_AUDIO: case TSStreamType.MPEG1_AUDIO: case TSStreamType.MPEG2_AUDIO: int audioFormat = ReadByte(data, ref pos); TSChannelLayout channelLayout = (TSChannelLayout) (audioFormat >> 4); TSSampleRate sampleRate = (TSSampleRate) (audioFormat & 0xF); string audioLanguage = ReadString(data, 3, ref pos); stream = new TSAudioStream(); ((TSAudioStream)stream).ChannelLayout = channelLayout; ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate); ((TSAudioStream)stream).LanguageCode = audioLanguage; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", pid, streamType, audioLanguage, channelLayout, sampleRate)); #endif break; case TSStreamType.INTERACTIVE_GRAPHICS: case TSStreamType.PRESENTATION_GRAPHICS: string graphicsLanguage = ReadString(data, 3, ref pos); stream = new TSGraphicsStream(); ((TSGraphicsStream)stream).LanguageCode = graphicsLanguage; if (data[pos] != 0) { } #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", pid, streamType, graphicsLanguage)); #endif break; case TSStreamType.SUBTITLE: int code = ReadByte(data, ref pos); // TODO string textLanguage = ReadString(data, 3, ref pos); stream = new TSTextStream(); ((TSTextStream)stream).LanguageCode = textLanguage; #if DEBUG Debug.WriteLine(string.Format( "\t{0} {1} {2}", pid, streamType, textLanguage)); #endif break; default: break; } pos = streamPos + streamLength; if (stream != null) { stream.PID = (ushort)pid; stream.StreamType = streamType; } return stream; }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag) { if (stream.IsInitialized) { return; } bool syncFound = false; uint sync = 0; for (int i = 0; i < buffer.Length; i++) { sync = (sync << 8) + buffer.ReadByte(); if (sync == 0x7FFE8001) { syncFound = true; break; } } if (!syncFound) { return; } int frame_type = buffer.ReadBits(1); int samples_deficit = buffer.ReadBits(5); int crc_present = buffer.ReadBits(1); int sample_blocks = buffer.ReadBits(7); int frame_size = buffer.ReadBits(14); if (frame_size < 95) { return; } int amode = buffer.ReadBits(6); int sample_rate = buffer.ReadBits(4); if (sample_rate < 0 || sample_rate >= dca_sample_rates.Length) { return; } int bit_rate = buffer.ReadBits(5); if (bit_rate < 0 || bit_rate >= dca_bit_rates.Length) { return; } int downmix = buffer.ReadBits(1); int dynrange = buffer.ReadBits(1); int timestamp = buffer.ReadBits(1); int aux_data = buffer.ReadBits(1); int hdcd = buffer.ReadBits(1); int ext_descr = buffer.ReadBits(3); int ext_coding = buffer.ReadBits(1); int aspf = buffer.ReadBits(1); int lfe = buffer.ReadBits(2); int predictor_history = buffer.ReadBits(1); if (crc_present == 1) { int crc = buffer.ReadBits(16); } int multirate_inter = buffer.ReadBits(1); int version = buffer.ReadBits(4); int copy_history = buffer.ReadBits(2); int source_pcm_res = buffer.ReadBits(3); int front_sum = buffer.ReadBits(1); int surround_sum = buffer.ReadBits(1); int dialog_norm = buffer.ReadBits(4); if (source_pcm_res < 0 || source_pcm_res >= dca_bits_per_sample.Length) { return; } int subframes = buffer.ReadBits(4); int total_channels = buffer.ReadBits(3) + 1 + ext_coding; stream.SampleRate = dca_sample_rates[sample_rate]; stream.ChannelCount = total_channels; stream.LFE = (lfe > 0 ? 1 : 0); stream.BitDepth = dca_bits_per_sample[source_pcm_res]; stream.DialNorm = -dialog_norm; if ((source_pcm_res & 0x1) == 0x1) { stream.AudioMode = TSAudioMode.Extended; } stream.BitRate = (uint)dca_bit_rates[bit_rate]; switch (stream.BitRate) { case 1: if (bitrate > 0) { stream.BitRate = bitrate; stream.IsVBR = false; stream.IsInitialized = true; } else { stream.BitRate = 0; } break; case 2: case 3: stream.IsVBR = true; stream.IsInitialized = true; break; default: stream.IsVBR = false; stream.IsInitialized = true; break; } }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, ref string tag) { if (stream.IsInitialized) return; byte[] header = buffer.ReadBytes(4); int flags = (header[2] << 8) + header[3]; switch ((flags & 0xF000) >> 12) { case 1: // 1/0/0 stream.ChannelCount = 1; stream.LFE = 0; break; case 3: // 2/0/0 stream.ChannelCount = 2; stream.LFE = 0; break; case 4: // 3/0/0 stream.ChannelCount = 3; stream.LFE = 0; break; case 5: // 2/1/0 stream.ChannelCount = 3; stream.LFE = 0; break; case 6: // 3/1/0 stream.ChannelCount = 4; stream.LFE = 0; break; case 7: // 2/2/0 stream.ChannelCount = 4; stream.LFE = 0; break; case 8: // 3/2/0 stream.ChannelCount = 5; stream.LFE = 0; break; case 9: // 3/2/1 stream.ChannelCount = 5; stream.LFE = 1; break; case 10: // 3/4/0 stream.ChannelCount = 7; stream.LFE = 0; break; case 11: // 3/4/1 stream.ChannelCount = 7; stream.LFE = 1; break; default: stream.ChannelCount = 0; stream.LFE = 0; break; } switch ((flags & 0xC0) >> 6) { case 1: stream.BitDepth = 16; break; case 2: stream.BitDepth = 20; break; case 3: stream.BitDepth = 24; break; default: stream.BitDepth = 0; break; } switch ((flags & 0xF00) >> 8) { case 1: stream.SampleRate = 48000; break; case 4: stream.SampleRate = 96000; break; case 5: stream.SampleRate = 192000; break; default: stream.SampleRate = 0; break; } stream.BitRate = (uint) (stream.SampleRate * stream.BitDepth * (stream.ChannelCount + stream.LFE)); stream.IsVBR = false; stream.IsInitialized = true; }
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; }
public void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag, long?bitrate) { if (stream.IsInitialized && stream.CoreStream != null && stream.CoreStream.IsInitialized) { return; } var syncFound = false; uint sync = 0; for (var i = 0; i < buffer.Length; i++) { sync = (sync << 8) + buffer.ReadByte(); if (sync == 0xF8726FBA) { syncFound = true; break; } } if (!syncFound) { tag = "CORE"; stream.CoreStream ??= new TSAudioStream { StreamType = TSStreamType.AC3_AUDIO }; if (stream.CoreStream.IsInitialized) { return; } buffer.BeginRead(); (new TSCodecAC3()).Scan(stream.CoreStream, buffer, ref tag, bitrate); return; } tag = "HD"; int ratebits = buffer.ReadBits2(4); if (ratebits != 0xF) { stream.SampleRate = ((ratebits & 8) > 0 ? 44100 : 48000) << (ratebits & 7); } buffer.BSSkipBits(15); stream.ChannelCount = 0; stream.LFE = 0; if (buffer.ReadBool()) { stream.LFE += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.ChannelCount += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } if (buffer.ReadBool()) { stream.LFE += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 1; } if (buffer.ReadBool()) { stream.ChannelCount += 2; } buffer.BSSkipBits(49); var peakBitrate = buffer.ReadBits4(15); peakBitrate = (uint)((peakBitrate * stream.SampleRate) >> 4); var peakBitdepth = (double)peakBitrate / (stream.ChannelCount + stream.LFE) / stream.SampleRate; stream.BitDepth = peakBitdepth > 14 ? 24 : 16; buffer.BSSkipBits(79); var hasExtensions = buffer.ReadBool(); var numExtensions = buffer.ReadBits2(4) * 2 + 1; var hasContent = Convert.ToBoolean(buffer.ReadBits4(4)); if (hasExtensions) { for (var idx = 0; idx < numExtensions; ++idx) { if (Convert.ToBoolean(buffer.ReadBits2(8))) { hasContent = true; } } if (hasContent) { stream.HasExtensions = true; } } #if DEBUG Debug.WriteLine($"{stream.PID}\t{peakBitrate}\t{peakBitdepth:F2}"); #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; if (stream.CoreStream != null && stream.CoreStream.IsInitialized) { stream.IsInitialized = true; } }
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; }
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; }
private TSStream CreateStream( ushort streamPID, byte streamType, List<TSDescriptor> streamDescriptors) { TSStream stream = null; switch ((TSStreamType)streamType) { case TSStreamType.MVC_VIDEO: case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.VC1_VIDEO: { stream = new TSVideoStream(); } break; case TSStreamType.AC3_AUDIO: case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: case TSStreamType.AC3_TRUE_HD_AUDIO: case TSStreamType.DTS_AUDIO: case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: case TSStreamType.LPCM_AUDIO: case TSStreamType.MPEG1_AUDIO: case TSStreamType.MPEG2_AUDIO: { stream = new TSAudioStream(); } break; case TSStreamType.INTERACTIVE_GRAPHICS: case TSStreamType.PRESENTATION_GRAPHICS: { stream = new TSGraphicsStream(); } break; case TSStreamType.SUBTITLE: { stream = new TSTextStream(); } break; default: break; } if (stream != null && !Streams.ContainsKey(streamPID)) { stream.PID = streamPID; stream.StreamType = (TSStreamType)streamType; stream.Descriptors = streamDescriptors; Streams[stream.PID] = stream; } if (!StreamDiagnostics.ContainsKey(streamPID)) { StreamDiagnostics[streamPID] = new List<TSStreamDiagnostics>(); } return stream; }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag) { if (stream.IsInitialized && (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO || (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 == 0x64582025) { syncFound = true; break; } } if (!syncFound) { tag = "CORE"; if (stream.CoreStream == null) { stream.CoreStream = new TSAudioStream(); stream.CoreStream.StreamType = TSStreamType.DTS_AUDIO; } if (!stream.CoreStream.IsInitialized) { buffer.BeginRead(); TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag); } return; } tag = "HD"; int temp1 = buffer.ReadBits(8); int nuSubStreamIndex = buffer.ReadBits(2); int nuExtSSHeaderSize = 0; int nuExtSSFSize = 0; int bBlownUpHeader = buffer.ReadBits(1); if (1 == bBlownUpHeader) { nuExtSSHeaderSize = buffer.ReadBits(12) + 1; nuExtSSFSize = buffer.ReadBits(20) + 1; } else { nuExtSSHeaderSize = buffer.ReadBits(8) + 1; nuExtSSFSize = buffer.ReadBits(16) + 1; } int nuNumAudioPresent = 1; int nuNumAssets = 1; int bStaticFieldsPresent = buffer.ReadBits(1); if (1 == bStaticFieldsPresent) { int nuRefClockCode = buffer.ReadBits(2); int nuExSSFrameDurationCode = buffer.ReadBits(3) + 1; long nuTimeStamp = 0; if (1 == buffer.ReadBits(1)) { nuTimeStamp = (buffer.ReadBits(18) << 18) + buffer.ReadBits(18); } nuNumAudioPresent = buffer.ReadBits(3) + 1; nuNumAssets = buffer.ReadBits(3) + 1; int[] nuActiveExSSMask = new int[nuNumAudioPresent]; for (int i = 0; i < nuNumAudioPresent; i++) { nuActiveExSSMask[i] = buffer.ReadBits(nuSubStreamIndex + 1); //? } for (int i = 0; i < nuNumAudioPresent; i++) { for (int j = 0; j < nuSubStreamIndex + 1; j++) { if (((j + 1) % 2) == 1) { int mask = buffer.ReadBits(8); } } } if (1 == buffer.ReadBits(1)) { int nuMixMetadataAdjLevel = buffer.ReadBits(2); int nuBits4MixOutMask = buffer.ReadBits(2) * 4 + 4; int nuNumMixOutConfigs = buffer.ReadBits(2) + 1; int[] nuMixOutChMask = new int[nuNumMixOutConfigs]; for (int i = 0; i < nuNumMixOutConfigs; i++) { nuMixOutChMask[i] = buffer.ReadBits(nuBits4MixOutMask); } } } int[] AssetSizes = new int[nuNumAssets]; for (int i = 0; i < nuNumAssets; i++) { if (1 == bBlownUpHeader) { AssetSizes[i] = buffer.ReadBits(20) + 1; } else { AssetSizes[i] = buffer.ReadBits(16) + 1; } } for (int i = 0; i < nuNumAssets; i++) { long bufferPosition = buffer.Position; int nuAssetDescriptorFSIZE = buffer.ReadBits(9) + 1; int DescriptorDataForAssetIndex = buffer.ReadBits(3); if (1 == bStaticFieldsPresent) { int AssetTypeDescrPresent = buffer.ReadBits(1); if (1 == AssetTypeDescrPresent) { int AssetTypeDescriptor = buffer.ReadBits(4); } int LanguageDescrPresent = buffer.ReadBits(1); if (1 == LanguageDescrPresent) { int LanguageDescriptor = buffer.ReadBits(24); } int bInfoTextPresent = buffer.ReadBits(1); if (1 == bInfoTextPresent) { int nuInfoTextByteSize = buffer.ReadBits(10) + 1; int[] InfoText = new int[nuInfoTextByteSize]; for (int j = 0; j < nuInfoTextByteSize; j++) { InfoText[j] = buffer.ReadBits(8); } } int nuBitResolution = buffer.ReadBits(5) + 1; int nuMaxSampleRate = buffer.ReadBits(4); int nuTotalNumChs = buffer.ReadBits(8) + 1; int bOne2OneMapChannels2Speakers = buffer.ReadBits(1); int nuSpkrActivityMask = 0; if (1 == bOne2OneMapChannels2Speakers) { int bEmbeddedStereoFlag = 0; if (nuTotalNumChs > 2) { bEmbeddedStereoFlag = buffer.ReadBits(1); } int bEmbeddedSixChFlag = 0; if (nuTotalNumChs > 6) { bEmbeddedSixChFlag = buffer.ReadBits(1); } int bSpkrMaskEnabled = buffer.ReadBits(1); int nuNumBits4SAMask = 0; if (1 == bSpkrMaskEnabled) { nuNumBits4SAMask = buffer.ReadBits(2); nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4; nuSpkrActivityMask = buffer.ReadBits(nuNumBits4SAMask); } // TODO... } stream.SampleRate = SampleRates[nuMaxSampleRate]; stream.BitDepth = nuBitResolution; stream.LFE = 0; if ((nuSpkrActivityMask & 0x8) == 0x8) { ++stream.LFE; } if ((nuSpkrActivityMask & 0x1000) == 0x1000) { ++stream.LFE; } stream.ChannelCount = nuTotalNumChs - stream.LFE; } if (nuNumAssets > 1) { // TODO... break; } } // TODO if (stream.CoreStream != null) { TSAudioStream coreStream = (TSAudioStream)stream.CoreStream; if (coreStream.AudioMode == TSAudioMode.Extended && stream.ChannelCount == 5) { stream.AudioMode = TSAudioMode.Extended; } /* * if (coreStream.DialNorm != 0) * { * stream.DialNorm = coreStream.DialNorm; * } */ } if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO) { stream.IsVBR = true; stream.IsInitialized = true; } else if (bitrate > 0) { stream.IsVBR = false; stream.BitRate = bitrate; if (stream.CoreStream != null) { stream.BitRate += stream.CoreStream.BitRate; stream.IsInitialized = true; } stream.IsInitialized = (stream.BitRate > 0 ? true : false); } }
public void Scan() { FileStream fileStream = null; BinaryReader fileReader = null; try { Debug.WriteLine(string.Format( "Scanning {0}...", Name)); Streams.Clear(); fileStream = File.OpenRead(FileInfo.FullName); fileReader = new BinaryReader(fileStream); byte[] data = new byte[fileStream.Length]; fileReader.Read(data, 0, data.Length); byte[] fileType = new byte[8]; Array.Copy(data, 0, fileType, 0, fileType.Length); FileType = ASCIIEncoding.ASCII.GetString(fileType); if (FileType != "HDMV0100" && FileType != "HDMV0200") { throw new Exception(string.Format( "Clip info file {0} has an unknown file type {1}.", FileInfo.Name, FileType)); } Debug.WriteLine(string.Format( "\tFileType: {0}", FileType)); int clipIndex = ((int)data[12] << 24) + ((int)data[13] << 16) + ((int)data[14] << 8) + ((int)data[15]); int clipLength = ((int)data[clipIndex] << 24) + ((int)data[clipIndex + 1] << 16) + ((int)data[clipIndex + 2] << 8) + ((int)data[clipIndex + 3]); byte[] clipData = new byte[clipLength]; Array.Copy(data, clipIndex + 4, clipData, 0, clipData.Length); int streamCount = clipData[8]; Debug.WriteLine(string.Format( "\tStreamCount: {0}", streamCount)); int streamOffset = 10; for (int streamIndex = 0; streamIndex < streamCount; streamIndex++) { TSStream stream = null; ushort PID = (ushort) ((clipData[streamOffset] << 8) + clipData[streamOffset + 1]); streamOffset += 2; TSStreamType streamType = (TSStreamType) clipData[streamOffset + 1]; switch (streamType) { case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.VC1_VIDEO: { TSVideoFormat videoFormat = (TSVideoFormat) (clipData[streamOffset + 2] >> 4); TSFrameRate frameRate = (TSFrameRate) (clipData[streamOffset + 2] & 0xF); TSAspectRatio aspectRatio = (TSAspectRatio) (clipData[streamOffset + 3] >> 4); stream = new TSVideoStream(); ((TSVideoStream)stream).VideoFormat = videoFormat; ((TSVideoStream)stream).AspectRatio = aspectRatio; ((TSVideoStream)stream).FrameRate = frameRate; Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", PID, streamType, videoFormat, frameRate, aspectRatio)); } break; case TSStreamType.AC3_AUDIO: case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: case TSStreamType.AC3_TRUE_HD_AUDIO: case TSStreamType.DTS_AUDIO: case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: case TSStreamType.LPCM_AUDIO: case TSStreamType.MPEG1_AUDIO: case TSStreamType.MPEG2_AUDIO: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); TSChannelLayout channelLayout = (TSChannelLayout) (clipData[streamOffset + 2] >> 4); TSSampleRate sampleRate = (TSSampleRate) (clipData[streamOffset + 2] & 0xF); stream = new TSAudioStream(); ((TSAudioStream)stream).LanguageCode = languageCode; ((TSAudioStream)stream).ChannelLayout = channelLayout; ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate); ((TSAudioStream)stream).LanguageCode = languageCode; Debug.WriteLine(string.Format( "\t{0} {1} {2} {3} {4}", PID, streamType, languageCode, channelLayout, sampleRate)); } break; case TSStreamType.INTERACTIVE_GRAPHICS: case TSStreamType.PRESENTATION_GRAPHICS: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 2, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); stream = new TSGraphicsStream(); stream.LanguageCode = languageCode; Debug.WriteLine(string.Format( "\t{0} {1} {2}", PID, streamType, languageCode)); } break; case TSStreamType.SUBTITLE: { byte[] languageBytes = new byte[3]; Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length); string languageCode = ASCIIEncoding.ASCII.GetString(languageBytes); Debug.WriteLine(string.Format( "\t{0} {1} {2}", PID, streamType, languageCode)); stream = new TSTextStream(); stream.LanguageCode = languageCode; } break; } if (stream != null) { stream.PID = PID; stream.StreamType = streamType; Streams.Add(PID, stream); } streamOffset += clipData[streamOffset] + 1; } IsValid = true; } finally { if (fileReader != null) fileReader.Close(); if (fileStream != null) fileStream.Close(); } }
public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag) { if (stream.IsInitialized && (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO || (stream.CoreStream != null && stream.CoreStream.IsInitialized))) { return; } var syncFound = false; uint sync = 0; for (var i = 0; i < buffer.Length; i++) { sync = (sync << 8) + buffer.ReadByte(); if (sync == 0x64582025) { syncFound = true; break; } } if (!syncFound) { tag = "CORE"; if (stream.CoreStream == null) { stream.CoreStream = new TSAudioStream { StreamType = TSStreamType.DTS_AUDIO }; } if (!stream.CoreStream.IsInitialized) { buffer.BeginRead(); TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag); } return; } tag = "HD"; buffer.BSSkipBits(8); var nuSubStreamIndex = buffer.ReadBits4(2); var bBlownUpHeader = buffer.ReadBool(); buffer.BSSkipBits(bBlownUpHeader ? 32 : 24); var nuNumAssets = 1; var bStaticFieldsPresent = buffer.ReadBool(); if (bStaticFieldsPresent) { buffer.BSSkipBits(5); if (buffer.ReadBool()) { buffer.BSSkipBits(36); } var nuNumAudioPresent = buffer.ReadBits2(3) + 1; nuNumAssets = buffer.ReadBits2(3) + 1; var nuActiveExSsMask = new uint[nuNumAudioPresent]; for (var i = 0; i < nuNumAudioPresent; i++) { nuActiveExSsMask[i] = buffer.ReadBits4((int)(nuSubStreamIndex + 1)); //? } for (var i = 0; i < nuNumAudioPresent; i++) { for (var j = 0; j < nuSubStreamIndex + 1; j++) { if (((j + 1) % 2) == 1) { buffer.BSSkipBits(8); } } } if (buffer.ReadBool()) { buffer.BSSkipBits(2); var nuBits4MixOutMask = buffer.ReadBits2(2) * 4 + 4; var nuNumMixOutConfigs = buffer.ReadBits2(2) + 1; var nuMixOutChMask = new uint[nuNumMixOutConfigs]; for (var i = 0; i < nuNumMixOutConfigs; i++) { nuMixOutChMask[i] = buffer.ReadBits4(nuBits4MixOutMask); } } } var assetSizes = new uint[nuNumAssets]; for (var i = 0; i < nuNumAssets; i++) { if (bBlownUpHeader) { assetSizes[i] = buffer.ReadBits4(20) + 1; } else { assetSizes[i] = buffer.ReadBits4(16) + 1; } } for (var i = 0; i < nuNumAssets; i++) { buffer.BSSkipBits(12); if (bStaticFieldsPresent) { if (buffer.ReadBool()) { buffer.BSSkipBits(4); } if (buffer.ReadBool()) { buffer.BSSkipBits(24); } if (buffer.ReadBool()) { var nuInfoTextByteSize = buffer.ReadBits2(10) + 1; var infoText = new ushort[nuInfoTextByteSize]; for (var j = 0; j < nuInfoTextByteSize; j++) { infoText[j] = buffer.ReadBits2(8); } } var nuBitResolution = buffer.ReadBits2(5) + 1; int nuMaxSampleRate = buffer.ReadBits2(4); var nuTotalNumChs = buffer.ReadBits2(8) + 1; uint nuSpkrActivityMask = 0; if (buffer.ReadBool()) { if (nuTotalNumChs > 2) { buffer.BSSkipBits(1); } if (nuTotalNumChs > 6) { buffer.BSSkipBits(1); } if (buffer.ReadBool()) { int nuNumBits4SAMask = buffer.ReadBits2(2); nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4; nuSpkrActivityMask = buffer.ReadBits4(nuNumBits4SAMask); } // TODO... } stream.SampleRate = SampleRates[nuMaxSampleRate]; stream.BitDepth = nuBitResolution; stream.LFE = 0; if ((nuSpkrActivityMask & 0x8) == 0x8) { ++stream.LFE; } if ((nuSpkrActivityMask & 0x1000) == 0x1000) { ++stream.LFE; } stream.ChannelCount = nuTotalNumChs - stream.LFE; } if (nuNumAssets > 1) { // TODO... break; } } uint temp2 = 0; while (buffer.Position < buffer.Length) { temp2 = (temp2 << 8) + buffer.ReadByte(); switch (temp2) { case 0x41A29547: // XLL Extended data case 0x655E315E: // XBR Extended data case 0x0A801921: // XSA Extended data case 0x1D95F262: // X96k case 0x47004A03: // XXch case 0x5A5A5A5A: // Xch int temp3 = 0; for (var i = (int)buffer.Position; i < buffer.Length; i++) { temp3 = (temp3 << 8) + buffer.ReadByte(); if (temp3 == 0x02000850) //DTS:X Pattern { stream.HasExtensions = true; break; } } break; } if (stream.HasExtensions) { break; } } // TODO if (stream.CoreStream != null) { var coreStream = (TSAudioStream)stream.CoreStream; if (coreStream.AudioMode == TSAudioMode.Extended && stream.ChannelCount == 5) { stream.AudioMode = TSAudioMode.Extended; } /* * if (coreStream.DialNorm != 0) * { * stream.DialNorm = coreStream.DialNorm; * } */ } if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO) { stream.IsVBR = true; stream.IsInitialized = true; } else if (bitrate > 0) { stream.IsVBR = false; stream.BitRate = bitrate; if (stream.CoreStream != null) { stream.BitRate += stream.CoreStream.BitRate; stream.IsInitialized = true; } stream.IsInitialized = (stream.BitRate > 0); } }
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); buffer.ReadBits(24); buffer.ReadBits(24); 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 stream.IsVBR = true; stream.IsInitialized = true; }
/// <summary> /// Adds the audio stream. /// </summary> /// <param name="streams">The streams.</param> /// <param name="audioStream">The audio stream.</param> private void AddAudioStream(List<MediaStream> streams, TSAudioStream audioStream) { var stream = new MediaStream { Codec = audioStream.CodecShortName, Language = audioStream.LanguageCode, Channels = audioStream.ChannelCount, SampleRate = audioStream.SampleRate, Type = MediaStreamType.Audio, Index = streams.Count }; var bitrate = Convert.ToInt32(audioStream.BitRate); if (bitrate > 0) { stream.BitRate = bitrate; } if (audioStream.LFE > 0) { stream.Channels = audioStream.ChannelCount + 1; } streams.Add(stream); }
public static void Scan( TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag) { if (stream.IsInitialized && (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO || (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 == 0x64582025) { syncFound = true; break; } } if (!syncFound) { tag = "CORE"; if (stream.CoreStream == null) { stream.CoreStream = new TSAudioStream(); stream.CoreStream.StreamType = TSStreamType.DTS_AUDIO; } if (!stream.CoreStream.IsInitialized) { buffer.BeginRead(); TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag); } return; } tag = "HD"; int temp1 = buffer.ReadBits(8); int nuSubStreamIndex = buffer.ReadBits(2); int nuExtSSHeaderSize = 0; int nuExtSSFSize = 0; int bBlownUpHeader = buffer.ReadBits(1); if (1 == bBlownUpHeader) { nuExtSSHeaderSize = buffer.ReadBits(12) + 1; nuExtSSFSize = buffer.ReadBits(20) + 1; } else { nuExtSSHeaderSize = buffer.ReadBits(8) + 1; nuExtSSFSize = buffer.ReadBits(16) + 1; } int nuNumAudioPresent = 1; int nuNumAssets = 1; int bStaticFieldsPresent = buffer.ReadBits(1); if (1 == bStaticFieldsPresent) { int nuRefClockCode = buffer.ReadBits(2); int nuExSSFrameDurationCode = buffer.ReadBits(3) + 1; long nuTimeStamp = 0; if (1 == buffer.ReadBits(1)) { nuTimeStamp = (buffer.ReadBits(18) << 18) + buffer.ReadBits(18); } nuNumAudioPresent = buffer.ReadBits(3) + 1; nuNumAssets = buffer.ReadBits(3) + 1; int[] nuActiveExSSMask = new int[nuNumAudioPresent]; for (int i = 0; i < nuNumAudioPresent; i++) { nuActiveExSSMask[i] = buffer.ReadBits(nuSubStreamIndex + 1); //? } for (int i = 0; i < nuNumAudioPresent; i++) { for (int j = 0; j < nuSubStreamIndex + 1; j++) { if (((j + 1) % 2) == 1) { int mask = buffer.ReadBits(8); } } } if (1 == buffer.ReadBits(1)) { int nuMixMetadataAdjLevel = buffer.ReadBits(2); int nuBits4MixOutMask = buffer.ReadBits(2) * 4 + 4; int nuNumMixOutConfigs = buffer.ReadBits(2) + 1; int[] nuMixOutChMask = new int[nuNumMixOutConfigs]; for (int i = 0; i < nuNumMixOutConfigs; i++) { nuMixOutChMask[i] = buffer.ReadBits(nuBits4MixOutMask); } } } int[] AssetSizes = new int[nuNumAssets]; for (int i = 0; i < nuNumAssets; i++) { if (1 == bBlownUpHeader) { AssetSizes[i] = buffer.ReadBits(20) + 1; } else { AssetSizes[i] = buffer.ReadBits(16) + 1; } } for (int i = 0; i < nuNumAssets; i++) { long bufferPosition = buffer.Position; int nuAssetDescriptorFSIZE = buffer.ReadBits(9) + 1; int DescriptorDataForAssetIndex = buffer.ReadBits(3); if (1 == bStaticFieldsPresent) { int AssetTypeDescrPresent = buffer.ReadBits(1); if (1 == AssetTypeDescrPresent) { int AssetTypeDescriptor = buffer.ReadBits(4); } int LanguageDescrPresent = buffer.ReadBits(1); if (1 == LanguageDescrPresent) { int LanguageDescriptor = buffer.ReadBits(24); } int bInfoTextPresent = buffer.ReadBits(1); if (1 == bInfoTextPresent) { int nuInfoTextByteSize = buffer.ReadBits(10) + 1; int[] InfoText = new int[nuInfoTextByteSize]; for (int j = 0; j < nuInfoTextByteSize; j++) { InfoText[j] = buffer.ReadBits(8); } } int nuBitResolution = buffer.ReadBits(5) + 1; int nuMaxSampleRate = buffer.ReadBits(4); int nuTotalNumChs = buffer.ReadBits(8) + 1; int bOne2OneMapChannels2Speakers = buffer.ReadBits(1); int nuSpkrActivityMask = 0; if (1 == bOne2OneMapChannels2Speakers) { int bEmbeddedStereoFlag = 0; if (nuTotalNumChs > 2) { bEmbeddedStereoFlag = buffer.ReadBits(1); } int bEmbeddedSixChFlag = 0; if (nuTotalNumChs > 6) { bEmbeddedSixChFlag = buffer.ReadBits(1); } int bSpkrMaskEnabled = buffer.ReadBits(1); int nuNumBits4SAMask = 0; if (1 == bSpkrMaskEnabled) { nuNumBits4SAMask = buffer.ReadBits(2); nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4; nuSpkrActivityMask = buffer.ReadBits(nuNumBits4SAMask); } // TODO... } stream.SampleRate = SampleRates[nuMaxSampleRate]; stream.BitDepth = nuBitResolution; stream.LFE = 0; if ((nuSpkrActivityMask & 0x8) == 0x8) { ++stream.LFE; } if ((nuSpkrActivityMask & 0x1000) == 0x1000) { ++stream.LFE; } stream.ChannelCount = nuTotalNumChs - stream.LFE; } if (nuNumAssets > 1) { // TODO... break; } } // TODO if (stream.CoreStream != null) { TSAudioStream coreStream = (TSAudioStream)stream.CoreStream; if (coreStream.AudioMode == TSAudioMode.Extended && stream.ChannelCount == 5) { stream.AudioMode = TSAudioMode.Extended; } /* if (coreStream.DialNorm != 0) { stream.DialNorm = coreStream.DialNorm; } */ } if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO) { stream.IsVBR = true; stream.IsInitialized = true; } else if (bitrate > 0) { stream.IsVBR = false; stream.BitRate = bitrate; if (stream.CoreStream != null) { stream.BitRate += stream.CoreStream.BitRate; stream.IsInitialized = true; } stream.IsInitialized = (stream.BitRate > 0 ? true : false); } }
public static int CompareAudioStreams( TSAudioStream x, TSAudioStream y) { if (x == y) { return(0); } else if (x == null && y == null) { return(0); } else if (x == null && y != null) { return(-1); } else if (x != null && y == null) { return(1); } else { if (x.ChannelCount > y.ChannelCount) { return(-1); } else if (y.ChannelCount > x.ChannelCount) { return(1); } else { int sortX = GetStreamTypeSortIndex(x.StreamType); int sortY = GetStreamTypeSortIndex(y.StreamType); if (sortX > sortY) { return(-1); } else if (sortY > sortX) { return(1); } else { if (x.LanguageCode == "eng") { return(-1); } else if (y.LanguageCode == "eng") { return(1); } else { return(string.Compare( x.LanguageName, y.LanguageName)); } } } } }
public void Generate( BDROM BDROM, List <TSPlaylistFile> playlists, ScanBDROMResult scanResult) { Playlists = playlists; StreamWriter reportFile = null; if (BDInfoSettings.AutosaveReport) { string reportName = string.Format( "BDINFO.{0}.txt", BDROM.VolumeLabel); reportFile = File.CreateText(Path.Combine(Environment.CurrentDirectory, reportName)); } textBoxReport.Text = ""; string protection = (BDROM.IsBDPlus ? "BD+" : "AACS"); string bdjava = (BDROM.IsBDJava ? "Yes" : "No"); List <string> extraFeatures = new List <string>(); if (BDROM.Is50Hz) { extraFeatures.Add("50Hz Content"); } if (BDROM.Is3D) { extraFeatures.Add("Blu-ray 3D"); } if (BDROM.IsDBOX) { extraFeatures.Add("D-BOX Motion Code"); } if (BDROM.IsPSP) { extraFeatures.Add("PSP Digital Copy"); } if (extraFeatures.Count > 0) { report += string.Format( "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray())); } if (scanResult.ScanException != null) { report += string.Format( "WARNING: Report is incomplete because: {0}\r\n", scanResult.ScanException.Message); } if (scanResult.FileExceptions.Count > 0) { report += "WARNING: File errors were encountered during scan:\r\n"; foreach (string fileName in scanResult.FileExceptions.Keys) { Exception fileException = scanResult.FileExceptions[fileName]; report += string.Format( "\r\n{0}\t{1}\r\n", fileName, fileException.Message); report += string.Format( "{0}\r\n", fileException.StackTrace); } } foreach (TSPlaylistFile playlist in playlists) { string summary = ""; comboBoxPlaylist.Items.Add(playlist); string title = playlist.Name; string discSize = string.Format( "{0:N0}", BDROM.Size); TimeSpan playlistTotalLength = new TimeSpan((long)(playlist.TotalLength * 10000000)); string totalLength = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds, playlistTotalLength.Milliseconds); string totalLengthShort = string.Format( "{0:D1}:{1:D2}:{2:D2}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds); string totalSize = string.Format( "{0:N0}", playlist.TotalSize); string totalBitrate = string.Format( "{0:F2}", Math.Round((double)playlist.TotalBitRate / 10000) / 100); TimeSpan playlistAngleLength = new TimeSpan((long)(playlist.TotalAngleLength * 10000000)); string totalAngleLength = string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistAngleLength.Hours, playlistAngleLength.Minutes, playlistAngleLength.Seconds, playlistAngleLength.Milliseconds); string totalAngleSize = string.Format( "{0:N0}", playlist.TotalAngleSize); string totalAngleBitrate = string.Format( "{0:F2}", Math.Round((double)playlist.TotalAngleBitRate / 10000) / 100); List <string> angleLengths = new List <string>(); List <string> angleSizes = new List <string>(); List <string> angleBitrates = new List <string>(); List <string> angleTotalLengths = new List <string>(); List <string> angleTotalSizes = new List <string>(); List <string> angleTotalBitrates = new List <string>(); if (playlist.AngleCount > 0) { for (int angleIndex = 0; angleIndex < playlist.AngleCount; angleIndex++) { double angleLength = 0; ulong angleSize = 0; ulong angleTotalSize = 0; if (angleIndex < playlist.AngleClips.Count && playlist.AngleClips[angleIndex] != null) { foreach (TSStreamClip clip in playlist.AngleClips[angleIndex].Values) { angleTotalSize += clip.PacketSize; if (clip.AngleIndex == angleIndex + 1) { angleSize += clip.PacketSize; angleLength += clip.Length; } } } angleSizes.Add(string.Format( "{0:N0}", angleSize)); TimeSpan angleTimeSpan = new TimeSpan((long)(angleLength * 10000000)); angleLengths.Add(string.Format( "{0:D1}:{1:D2}:{2:D2}.{3:D3}", angleTimeSpan.Hours, angleTimeSpan.Minutes, angleTimeSpan.Seconds, angleTimeSpan.Milliseconds)); angleTotalSizes.Add(string.Format( "{0:N0}", angleTotalSize)); angleTotalLengths.Add(totalLength); double angleBitrate = 0; if (angleLength > 0) { angleBitrate = Math.Round((double)(angleSize * 8) / angleLength / 10000) / 100; } angleBitrates.Add(string.Format("{0:F2}", angleBitrate)); double angleTotalBitrate = 0; if (playlist.TotalLength > 0) { angleTotalBitrate = Math.Round((double)(angleTotalSize * 8) / playlist.TotalLength / 10000) / 100; } angleTotalBitrates.Add(string.Format( "{0:F2}", angleTotalBitrate)); } } string videoCodec = ""; string videoBitrate = ""; if (playlist.VideoStreams.Count > 0) { TSStream videoStream = playlist.VideoStreams[0]; videoCodec = videoStream.CodecAltName; videoBitrate = string.Format( "{0:F2}", Math.Round((double)videoStream.BitRate / 10000) / 100); } string audio1 = ""; string languageCode1 = ""; if (playlist.AudioStreams.Count > 0) { TSAudioStream audioStream = playlist.AudioStreams[0]; languageCode1 = audioStream.LanguageCode; audio1 = string.Format( "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio1 += string.Format( " {0} Kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio1 += string.Format( " ({0} kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } } string audio2 = ""; if (playlist.AudioStreams.Count > 1) { for (int i = 1; i < playlist.AudioStreams.Count; i++) { TSAudioStream audioStream = playlist.AudioStreams[i]; if (audioStream.LanguageCode == languageCode1 && audioStream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO && audioStream.StreamType != TSStreamType.DTS_HD_SECONDARY_AUDIO && !(audioStream.StreamType == TSStreamType.AC3_AUDIO && audioStream.ChannelCount == 2)) { audio2 = string.Format( "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio2 += string.Format( " {0} kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio2 += string.Format( " ({0} kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } break; } } } report += "DISC INFO:\r\n"; report += "\r\n"; report += string.Format( "{0,-16}{1}\r\n", "Disc Title:", BDROM.VolumeLabel); report += string.Format( "{0,-16}{1:N0} bytes\r\n", "Disc Size:", BDROM.Size); report += string.Format( "{0,-16}{1}\r\n", "Protection:", protection); report += string.Format( "{0,-16}{1}\r\n", "BD-Java:", bdjava); if (extraFeatures.Count > 0) { report += string.Format( "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray())); } report += string.Format( "{0,-16}{1}\r\n", "TDMaker:", Application.ProductVersion + " (BDInfo 0.5.8)"); report += "\r\n"; report += "PLAYLIST REPORT:\r\n"; report += "\r\n"; report += string.Format( "{0,-24}{1}\r\n", "Name:", title); report += string.Format( "{0,-24}{1} (h:m:s.ms)\r\n", "Length:", totalLength); report += string.Format( "{0,-24}{1:N0} bytes\r\n", "Size:", totalSize); report += string.Format( "{0,-24}{1} Mbps\r\n", "Total Bitrate:", totalBitrate); if (playlist.AngleCount > 0) { for (int angleIndex = 0; angleIndex < playlist.AngleCount; angleIndex++) { report += "\r\n"; report += string.Format( "{0,-24}{1} (h:m:s.ms) / {2} (h:m:s.ms)\r\n", string.Format("Angle {0} Length:", angleIndex + 1), angleLengths[angleIndex], angleTotalLengths[angleIndex]); report += string.Format( "{0,-24}{1:N0} bytes / {2:N0} bytes\r\n", string.Format("Angle {0} Size:", angleIndex + 1), angleSizes[angleIndex], angleTotalSizes[angleIndex]); report += string.Format( "{0,-24}{1} Mbps / {2} Mbps\r\n", string.Format("Angle {0} Total Bitrate:", angleIndex + 1), angleBitrates[angleIndex], angleTotalBitrates[angleIndex], angleIndex); } report += "\r\n"; report += string.Format( "{0,-24}{1} (h:m:s.ms)\r\n", "All Angles Length:", totalAngleLength); report += string.Format( "{0,-24}{1} bytes\r\n", "All Angles Size:", totalAngleSize); report += string.Format( "{0,-24}{1} Mbps\r\n", "All Angles Bitrate:", totalAngleBitrate); } /* * report += string.Format( * "{0,-24}{1}\r\n", "Description:", ""); */ summary += string.Format( "Disc Title: {0}\r\n", BDROM.VolumeLabel); summary += string.Format( "Disc Size: {0:N0} bytes\r\n", BDROM.Size); summary += string.Format( "Protection: {0}\r\n", protection); summary += string.Format( "BD-Java: {0}\r\n", bdjava); summary += string.Format( "Playlist: {0}\r\n", title); summary += string.Format( "Size: {0:N0} bytes\r\n", totalSize); summary += string.Format( "Length: {0}\r\n", totalLength); summary += string.Format( "Total Bitrate: {0} Mbps\r\n", totalBitrate); if (playlist.HasHiddenTracks) { report += "\r\n(*) Indicates included stream hidden by this playlist.\r\n"; } if (playlist.VideoStreams.Count > 0) { report += "\r\n"; report += "VIDEO:\r\n"; report += "\r\n"; report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", "Codec", "Bitrate", "Description"); report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", "-----", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsVideoStream) { continue; } string streamName = stream.CodecName; if (stream.AngleIndex > 0) { streamName += string.Format( " ({0})", stream.AngleIndex); } string streamBitrate = string.Format( "{0:D}", (int)Math.Round((double)stream.BitRate / 1000)); if (stream.AngleIndex > 0) { streamBitrate += string.Format( " ({0:D})", (int)Math.Round((double)stream.ActiveBitRate / 1000)); } streamBitrate += " kbps"; report += string.Format( "{0,-24}{1,-20}{2,-16}\r\n", (stream.IsHidden ? "* " : "") + streamName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Video: {0} / {1} / {2}\r\n", streamName, streamBitrate, stream.Description); } } if (playlist.AudioStreams.Count > 0) { report += "\r\n"; report += "AUDIO:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsAudioStream) { continue; } string streamBitrate = string.Format( "{0:D} kbps", (int)Math.Round((double)stream.BitRate / 1000)); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Audio: {0} / {1} / {2}\r\n", stream.LanguageName, stream.CodecName, stream.Description); } } if (playlist.GraphicsStreams.Count > 0) { report += "\r\n"; report += "SUBTITLES:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsGraphicsStream) { continue; } string streamBitrate = string.Format( "{0:F3} kbps", (double)stream.BitRate / 1000); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); summary += string.Format( (stream.IsHidden ? "* " : "") + "Subtitle: {0} / {1}\r\n", stream.LanguageName, streamBitrate, stream.Description); } } if (playlist.TextStreams.Count > 0) { report += "\r\n"; report += "TEXT:\r\n"; report += "\r\n"; report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description"); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------"); foreach (TSStream stream in playlist.SortedStreams) { if (!stream.IsTextStream) { continue; } string streamBitrate = string.Format( "{0:F3} kbps", (double)stream.BitRate / 1000); report += string.Format( "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description); } } report += "\r\n"; if (BDInfoSettings.AutosaveReport && reportFile != null) { try { reportFile.Write(report); } catch { } } textBoxReport.Text += report; GC.Collect(); } if (BDInfoSettings.AutosaveReport && reportFile != null) { try { reportFile.Write(report); } catch { } } textBoxReport.Text += report; if (reportFile != null) { reportFile.Close(); } textBoxReport.Select(0, 0); comboBoxPlaylist.SelectedIndex = 0; comboBoxChartType.SelectedIndex = 0; }