private static Track Transform(TSStream stream, int index, ref int numVideo, ref int numAudio, ref int numSubtitle) { var videoStream = stream as TSVideoStream; var audioStream = stream as TSAudioStream; var subtitleStream = stream as TSGraphicsStream; var indexOfType = 0; if (videoStream != null) indexOfType = numVideo++; if (audioStream != null) indexOfType = numAudio++; if (subtitleStream != null) indexOfType = numSubtitle++; return new Track { Index = index, PID = stream.PID, Language = stream.Language, IsHidden = stream.IsHidden, Codec = CodecTransformer.CodecFromStream(stream), IsVideo = stream.IsVideoStream, IsAudio = stream.IsAudioStream, IsSubtitle = stream.IsGraphicsStream || stream.IsTextStream, ChannelCount = audioStream != null ? audioStream.ChannelCountDouble : 0, BitDepth = audioStream != null ? audioStream.BitDepth : 0, VideoFormat = videoStream != null ? videoStream.VideoFormat : 0, FrameRate = videoStream != null ? videoStream.FrameRate : TSFrameRate.Unknown, AspectRatio = videoStream != null ? videoStream.AspectRatio : TSAspectRatio.Unknown, IndexOfType = indexOfType }; }
public static Codec CodecFromStream(TSStream stream) { if (stream == null) return Codec.UnknownCodec; var audioStream = stream as TSAudioStream; switch (stream.StreamType) { case TSStreamType.MPEG1_VIDEO: return Codec.MPEG1Video; case TSStreamType.MPEG2_VIDEO: return Codec.MPEG2Video; case TSStreamType.AVC_VIDEO: return Codec.AVC; case TSStreamType.MVC_VIDEO: return Codec.UnknownVideo; case TSStreamType.VC1_VIDEO: return Codec.VC1; case TSStreamType.MPEG1_AUDIO: return Codec.MP3; case TSStreamType.MPEG2_AUDIO: return Codec.UnknownAudio; case TSStreamType.LPCM_AUDIO: return Codec.LPCM; case TSStreamType.AC3_AUDIO: if (audioStream != null && audioStream.AudioMode == TSAudioMode.Extended) return Codec.AC3EX; if (audioStream != null && audioStream.AudioMode == TSAudioMode.Surround) return Codec.ProLogic; return Codec.AC3; case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: return Codec.EAC3; case TSStreamType.AC3_TRUE_HD_AUDIO: return Codec.TrueHD; case TSStreamType.DTS_AUDIO: if (audioStream != null && audioStream.AudioMode == TSAudioMode.Extended) return Codec.DTSES; return Codec.DTS; case TSStreamType.DTS_HD_AUDIO: return Codec.DTSHDHRA; case TSStreamType.DTS_HD_SECONDARY_AUDIO: return Codec.DTSExpress; case TSStreamType.DTS_HD_MASTER_AUDIO: return Codec.DTSHDMA; case TSStreamType.PRESENTATION_GRAPHICS: return Codec.PGS; case TSStreamType.INTERACTIVE_GRAPHICS: return Codec.IGS; case TSStreamType.SUBTITLE: return Codec.UnknownSubtitle; default: return Codec.UnknownCodec; } }
public bool IsCompatible(TSStreamClip clip) { foreach (TSStream stream1 in StreamFile.Streams.Values) { if (clip.StreamFile.Streams.ContainsKey(stream1.PID)) { TSStream stream2 = clip.StreamFile.Streams[stream1.PID]; if (stream1.StreamType != stream2.StreamType) { return(false); } } } return(true); }
protected void CopyTo(TSStream stream) { stream.PID = PID; stream.StreamType = StreamType; stream.IsVBR = IsVBR; stream.BitRate = BitRate; stream.IsInitialized = IsInitialized; stream.LanguageCode = _LanguageCode; if (Descriptors != null) { stream.Descriptors = new List <TSDescriptor>(); foreach (TSDescriptor descriptor in Descriptors) { stream.Descriptors.Add(descriptor.Clone()); } } }
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(); } } }
protected void CopyTo(TSStream stream) { stream.PID = PID; stream.StreamType = StreamType; stream.IsVBR = IsVBR; stream.BitRate = BitRate; stream.IsInitialized = IsInitialized; stream.LanguageCode = _languageCode; if (Descriptors != null) { stream.Descriptors = new List<TSDescriptor>(); foreach (TSDescriptor descriptor in Descriptors) { stream.Descriptors.Add(descriptor.Clone()); } } }
private bool ScanStream( TSStream stream, TSStreamState streamState, TSStreamBuffer buffer) { streamState.StreamTag = null; long bitrate = 0; if (stream.IsAudioStream && streamState.PTSTransfer > 0) { bitrate = (long)Math.Round( (buffer.TransferLength * 8.0) / ((double)streamState.PTSTransfer / 90000)); if (bitrate > streamState.PeakTransferRate) { streamState.PeakTransferRate = bitrate; } } if (buffer.TransferLength > streamState.PeakTransferLength) { streamState.PeakTransferLength = buffer.TransferLength; } buffer.BeginRead(); switch (stream.StreamType) { case TSStreamType.MPEG2_VIDEO: TSCodecMPEG2.Scan( (TSVideoStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.AVC_VIDEO: TSCodecAVC.Scan( (TSVideoStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.MVC_VIDEO: TSCodecMVC.Scan( (TSVideoStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.VC1_VIDEO: TSCodecVC1.Scan( (TSVideoStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.AC3_AUDIO: TSCodecAC3.Scan( (TSAudioStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.AC3_PLUS_AUDIO: case TSStreamType.AC3_PLUS_SECONDARY_AUDIO: TSCodecAC3.Scan( (TSAudioStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.AC3_TRUE_HD_AUDIO: TSCodecTrueHD.Scan( (TSAudioStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.LPCM_AUDIO: TSCodecLPCM.Scan( (TSAudioStream)stream, buffer, ref streamState.StreamTag); break; case TSStreamType.DTS_AUDIO: TSCodecDTS.Scan( (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag); break; case TSStreamType.DTS_HD_AUDIO: case TSStreamType.DTS_HD_MASTER_AUDIO: case TSStreamType.DTS_HD_SECONDARY_AUDIO: TSCodecDTSHD.Scan( (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag); break; default: stream.IsInitialized = true; break; } buffer.EndRead(); streamState.StreamBuffer.Reset(); bool isAVC = false; bool isMVC = false; foreach (TSStream finishedStream in Streams.Values) { if (!finishedStream.IsInitialized) { return false; } if (finishedStream.StreamType == TSStreamType.AVC_VIDEO) { isAVC = true; } if (finishedStream.StreamType == TSStreamType.MVC_VIDEO) { isMVC = true; } } if (isMVC && !isAVC) { return false; } return true; }
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); } }
public void Scan( Dictionary <string, TSStreamFile> streamFiles, Dictionary <string, TSStreamClipFile> streamClipFiles) { FileStream fileStream = null; BinaryReader fileReader = null; try { Streams.Clear(); StreamClips.Clear(); fileStream = File.OpenRead(FileInfo.FullName); fileReader = new BinaryReader(fileStream); byte[] data = new byte[fileStream.Length]; int dataLength = fileReader.Read(data, 0, data.Length); int pos = 0; FileType = ReadString(data, 8, ref pos); if (FileType != "MPLS0100" && FileType != "MPLS0200") { throw new Exception(string.Format( "Playlist {0} has an unknown file type {1}.", FileInfo.Name, FileType)); } int playlistOffset = ReadInt32(data, ref pos); int chaptersOffset = ReadInt32(data, ref pos); int extensionsOffset = ReadInt32(data, ref pos); pos = playlistOffset; int playlistLength = ReadInt32(data, ref pos); int playlistReserved = ReadInt16(data, ref pos); int itemCount = ReadInt16(data, ref pos); int subitemCount = ReadInt16(data, ref pos); List <TSStreamClip> chapterClips = new List <TSStreamClip>(); for (int itemIndex = 0; itemIndex < itemCount; itemIndex++) { int itemStart = pos; int itemLength = ReadInt16(data, ref pos); string itemName = ReadString(data, 5, ref pos); string itemType = ReadString(data, 4, ref pos); TSStreamFile streamFile = null; string streamFileName = null; foreach (string ext in BDROM.EXT_M2TS) { streamFileName = string.Format("{0}.{1}", itemName, ext); if (streamFiles.TryGetValue(streamFileName, out streamFile)) { break; } } if (streamFile == null) { Debug.WriteLine(string.Format("Playlist {0} referenced missing file {1}.", FileInfo.Name, streamFileName)); } TSStreamClipFile streamClipFile = null; foreach (string ext in BDROM.EXT_CLPI) { string streamClipFileName = string.Format("{0}.{1}", itemName, ext); if (streamClipFiles.TryGetValue(streamClipFileName, out streamClipFile)) { break; } } if (streamClipFile == null) { throw new Exception(string.Format("Playlist {0} referenced missing file {1}.", FileInfo.Name, streamFileName)); } pos += 1; int multiangle = (data[pos] >> 4) & 0x01; int condition = data[pos] & 0x0F; pos += 2; int inTime = ReadInt32(data, ref pos); if (inTime < 0) { inTime &= 0x7FFFFFFF; } double timeIn = (double)inTime / 45000; int outTime = ReadInt32(data, ref pos); if (outTime < 0) { outTime &= 0x7FFFFFFF; } double timeOut = (double)outTime / 45000; TSStreamClip streamClip = new TSStreamClip(streamFile, streamClipFile); streamClip.Name = streamFileName; //TODO streamClip.TimeIn = timeIn; streamClip.TimeOut = timeOut; streamClip.Length = streamClip.TimeOut - streamClip.TimeIn; streamClip.RelativeTimeIn = TotalLength; streamClip.RelativeTimeOut = streamClip.RelativeTimeIn + streamClip.Length; StreamClips.Add(streamClip); chapterClips.Add(streamClip); pos += 12; if (multiangle > 0) { int angles = data[pos]; pos += 2; for (int angle = 0; angle < angles - 1; angle++) { string angleName = ReadString(data, 5, ref pos); string angleType = ReadString(data, 4, ref pos); pos += 1; TSStreamFile angleFile = null; string angleFileName = string.Empty; foreach (string ext in BDROM.EXT_M2TS) { angleFileName = string.Format("{0}.{1}", itemName, ext); if (streamFiles.TryGetValue(angleFileName, out angleFile)) { break; } } if (angleFile == null) { throw new Exception(string.Format("Playlist {0} referenced missing angle file {1}.", FileInfo.Name, angleFileName)); } TSStreamClipFile angleClipFile = null; string angleClipFileName = string.Empty; foreach (string ext in BDROM.EXT_CLPI) { angleClipFileName = string.Format("{0}.{1}", itemName, ext); if (streamClipFiles.TryGetValue(angleClipFileName, out angleClipFile)) { break; } } if (angleClipFile == null) { throw new Exception(string.Format("Playlist {0} referenced missing angle file {1}.", FileInfo.Name, angleClipFileName)); } TSStreamClip angleClip = new TSStreamClip(angleFile, angleClipFile); angleClip.AngleIndex = angle + 1; angleClip.TimeIn = streamClip.TimeIn; angleClip.TimeOut = streamClip.TimeOut; angleClip.RelativeTimeIn = streamClip.RelativeTimeIn; angleClip.RelativeTimeOut = streamClip.RelativeTimeOut; angleClip.Length = streamClip.Length; StreamClips.Add(angleClip); } if (angles - 1 > AngleCount) { AngleCount = angles - 1; } } int streamInfoLength = ReadInt16(data, ref pos); pos += 2; int streamCountVideo = data[pos++]; int streamCountAudio = data[pos++]; int streamCountPG = data[pos++]; int streamCountIG = data[pos++]; int streamCountSecondaryAudio = data[pos++]; int streamCountSecondaryVideo = data[pos++]; int streamCountPIP = data[pos++]; pos += 5; #if DEBUG Debug.WriteLine(string.Format( "{0} : {1} -> V:{2} A:{3} PG:{4} IG:{5} 2A:{6} 2V:{7} PIP:{8}", Name, streamFileName, streamCountVideo, streamCountAudio, streamCountPG, streamCountIG, streamCountSecondaryAudio, streamCountSecondaryVideo, streamCountPIP)); #endif for (int i = 0; i < streamCountVideo; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } } for (int i = 0; i < streamCountAudio; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } } for (int i = 0; i < streamCountPG; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } } for (int i = 0; i < streamCountIG; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } } for (int i = 0; i < streamCountSecondaryAudio; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } pos += 2; } for (int i = 0; i < streamCountSecondaryVideo; i++) { TSStream stream = CreatePlaylistStream(data, ref pos); if (stream != null) { PlaylistStreams[stream.PID] = stream; } pos += 6; } /* * TODO * * for (int i = 0; i < streamCountPIP; i++) * { * TSStream stream = CreatePlaylistStream(data, ref pos); * if (stream != null) PlaylistStreams[stream.PID] = stream; * } */ pos += itemLength - (pos - itemStart) + 2; } pos = chaptersOffset + 4; int chapterCount = ReadInt16(data, ref pos); for (int chapterIndex = 0; chapterIndex < chapterCount; chapterIndex++) { int chapterType = data[pos + 1]; if (chapterType == 1) { int streamFileIndex = ((int)data[pos + 2] << 8) + data[pos + 3]; long chapterTime = ((long)data[pos + 4] << 24) + ((long)data[pos + 5] << 16) + ((long)data[pos + 6] << 8) + ((long)data[pos + 7]); TSStreamClip streamClip = chapterClips[streamFileIndex]; double chapterSeconds = (double)chapterTime / 45000; double relativeSeconds = chapterSeconds - streamClip.TimeIn + streamClip.RelativeTimeIn; // TODO: Ignore short last chapter? if (TotalLength - relativeSeconds > 1.0) { streamClip.Chapters.Add(chapterSeconds); this.Chapters.Add(relativeSeconds); } } else { // TODO: Handle other chapter types? } pos += 14; } } finally { if (fileReader != null) { fileReader.Close(); } if (fileStream != null) { fileStream.Close(); } } }
private static bool IsDefaultAngle(TSStream tsStream) { return tsStream.AngleIndex == 0; }
public static StreamInfo FromStream(TSStream stream) { var r = new StreamInfo() { Description = stream.Description, PID = stream.PID, BitRate = stream.BitRate, ActiveBitRate = stream.ActiveBitRate, IsVBR = stream.IsVBR, LanguageName = stream.LanguageName, IsHidden = stream.IsHidden, PayloadBytes = stream.PayloadBytes, PacketCount = stream.PacketCount, PacketSeconds = stream.PacketSeconds, AngleIndex = stream.AngleIndex, BaseView = stream.BaseView, CodecName = stream.CodecName, CodecAltName = stream.CodecAltName, CodecShortName = stream.CodecShortName }; if (stream.IsVideoStream) { r.Width = ((TSVideoStream)stream).Width; r.Height = ((TSVideoStream)stream).Height; r.IsInterlaced = ((TSVideoStream)stream).IsInterlaced; r.FrameRateEnumerator = ((TSVideoStream)stream).FrameRateEnumerator; r.FrameRateDenominator = ((TSVideoStream)stream).FrameRateDenominator; switch (((TSVideoStream)stream).AspectRatio) { case TSAspectRatio.ASPECT_4_3: r.AspectRatio = "4:3"; break; case TSAspectRatio.ASPECT_16_9: r.AspectRatio = "16:9"; break; } r.EncodingProfile = ((TSVideoStream)stream).EncodingProfile; r.ExtendedData = ((TSVideoStream)stream).ExtendedData; } else if (stream.IsAudioStream) { r.SampleRate = ((TSAudioStream)stream).SampleRate; r.ChannelCount = ((TSAudioStream)stream).ChannelCount; r.BitDepth = ((TSAudioStream)stream).BitDepth; r.LFE = ((TSAudioStream)stream).LFE; r.DialNorm = ((TSAudioStream)stream).DialNorm; switch (((TSAudioStream)stream).AudioMode) { case TSAudioMode.Unknown: r.AudioMode = "Unknown"; break; case TSAudioMode.DualMono: r.AudioMode = "DualMono"; break; case TSAudioMode.Stereo: r.AudioMode = "Stereo"; break; case TSAudioMode.Surround: r.AudioMode = "Surround"; break; case TSAudioMode.Extended: r.AudioMode = "Extended"; break; } if (((TSAudioStream)stream).CoreStream != null) { r.CoreStream = StreamInfo.FromStream(((TSAudioStream)stream).CoreStream); } switch (((TSAudioStream)stream).ChannelLayout) { case TSChannelLayout.Unknown: r.ChannelLayout = "Unknown"; break; case TSChannelLayout.CHANNELLAYOUT_MONO: r.ChannelLayout = "Mono"; break; case TSChannelLayout.CHANNELLAYOUT_STEREO: r.ChannelLayout = "Stereo"; break; case TSChannelLayout.CHANNELLAYOUT_MULTI: r.ChannelLayout = "Multi"; break; case TSChannelLayout.CHANNELLAYOUT_COMBO: r.ChannelLayout = "Combo"; break; } r.ChannelDescription = ((TSAudioStream)stream).ChannelDescription; } return(r); }
public static string Generate(BDROM BDROM, List <TSPlaylistFile> playlists, ScanBDROMResult scanResult) { var report = new StringBuilder(); var protection = BDROM.IsBDPlus ? "BD+" : BDROM.IsUHD ? "AACS2" : "AACS"; if (!string.IsNullOrEmpty(BDROM.DiscTitle)) { report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Disc Title:", BDROM.DiscTitle)); } report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Disc Label:", BDROM.VolumeLabel)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1:N0} bytes\r\n", "Disc Size:", BDROM.Size)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Protection:", protection)); var extraFeatures = new List <string>(); if (BDROM.IsUHD) { extraFeatures.Add("Ultra HD"); } if (BDROM.IsBDJava) { extraFeatures.Add("BD-Java"); } 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.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray()))); } /*report.Append(string.Format( CultureInfo.InvariantCulture, * "{0,-16}{1}\r\n", "BDInfo:", * Application.ProductVersion);*/ report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Notes:", "")); report.Append("\r\n"); report.Append("BDINFO HOME:\r\n"); report.Append(" Cinema Squid (old)\r\n"); report.Append(" http://www.cinemasquid.com/blu-ray/tools/bdinfo\r\n"); report.Append(" UniqProject GitHub (new)\r\n"); report.Append(" https://github.com/UniqProject/BDInfo\r\n"); report.Append("\r\n"); report.Append("INCLUDES FORUMS REPORT FOR:\r\n"); report.Append(" AVS Forum Blu-ray Audio and Video Specifications Thread\r\n"); report.Append(" http://www.avsforum.com/avs-vb/showthread.php?t=1155731\r\n"); report.Append("\r\n"); if (scanResult.ScanException != null) { report.Append(string.Format(CultureInfo.InvariantCulture, "WARNING: Report is incomplete because: {0}\r\n", scanResult.ScanException.Message)); } if (scanResult.FileExceptions.Count > 0) { report.Append("WARNING: File errors were encountered during scan:\r\n"); foreach (var fileName in scanResult.FileExceptions.Keys) { var fileException = scanResult.FileExceptions[fileName]; report.Append(string.Format(CultureInfo.InvariantCulture, "\r\n{0}\t{1}\r\n", fileName, fileException.Message)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0}\r\n", fileException.StackTrace)); } } foreach (var playlist in playlists) { var summary = ""; // comboBoxPlaylist.Items.Add(playlist); var title = playlist.Name; var discSize = string.Format(CultureInfo.InvariantCulture, "{0:N0}", BDROM.Size); var playlistTotalLength = new TimeSpan((long)(playlist.TotalLength * 10000000)); var totalLength = string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds, playlistTotalLength.Milliseconds); var totalLengthShort = string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}", playlistTotalLength.Hours, playlistTotalLength.Minutes, playlistTotalLength.Seconds); var totalSize = string.Format(CultureInfo.InvariantCulture, "{0:N0}", playlist.TotalSize); var totalBitrate = string.Format(CultureInfo.InvariantCulture, "{0:F2}", Math.Round((double)playlist.TotalBitRate / 10000) / 100); var playlistAngleLength = new TimeSpan((long)(playlist.TotalAngleLength * 10000000)); var totalAngleLength = string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", playlistAngleLength.Hours, playlistAngleLength.Minutes, playlistAngleLength.Seconds, playlistAngleLength.Milliseconds); var totalAngleSize = string.Format(CultureInfo.InvariantCulture, "{0:N0}", playlist.TotalAngleSize); var totalAngleBitrate = string.Format(CultureInfo.InvariantCulture, "{0:F2}", Math.Round((double)playlist.TotalAngleBitRate / 10000) / 100); var angleLengths = new List <string>(); var angleSizes = new List <string>(); var angleBitrates = new List <string>(); var angleTotalLengths = new List <string>(); var angleTotalSizes = new List <string>(); var angleTotalBitrates = new List <string>(); if (playlist.AngleCount > 0) { for (var 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 (var clip in playlist.AngleClips[angleIndex].Values) { angleTotalSize += clip.PacketSize; if (clip.AngleIndex == angleIndex + 1) { angleSize += clip.PacketSize; angleLength += clip.Length; } } } angleSizes.Add(string.Format(CultureInfo.InvariantCulture, "{0:N0}", angleSize)); var angleTimeSpan = new TimeSpan((long)(angleLength * 10000000)); angleLengths.Add(string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", angleTimeSpan.Hours, angleTimeSpan.Minutes, angleTimeSpan.Seconds, angleTimeSpan.Milliseconds)); angleTotalSizes.Add(string.Format(CultureInfo.InvariantCulture, "{0:N0}", angleTotalSize)); angleTotalLengths.Add(totalLength); double angleBitrate = 0; if (angleLength > 0) { angleBitrate = Math.Round(angleSize * 8 / angleLength / 10000) / 100; } angleBitrates.Add(string.Format(CultureInfo.InvariantCulture, "{0:F2}", angleBitrate)); double angleTotalBitrate = 0; if (playlist.TotalLength > 0) { angleTotalBitrate = Math.Round(angleTotalSize * 8 / playlist.TotalLength / 10000) / 100; } angleTotalBitrates.Add(string.Format(CultureInfo.InvariantCulture, "{0:F2}", angleTotalBitrate)); } } var videoCodec = ""; var videoBitrate = ""; if (playlist.VideoStreams.Count > 0) { TSStream videoStream = playlist.VideoStreams[0]; videoCodec = videoStream.CodecAltName; videoBitrate = string.Format(CultureInfo.InvariantCulture, "{0:F2}", Math.Round((double)videoStream.BitRate / 10000) / 100); } var audio1 = ""; var languageCode1 = ""; if (playlist.AudioStreams.Count > 0) { var audioStream = playlist.AudioStreams[0]; languageCode1 = audioStream.LanguageCode; audio1 = string.Format(CultureInfo.InvariantCulture, "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio1 += string.Format(CultureInfo.InvariantCulture, " {0}Kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio1 += string.Format(CultureInfo.InvariantCulture, " ({0}kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } } var audio2 = ""; if (playlist.AudioStreams.Count > 1) { for (var i = 1; i < playlist.AudioStreams.Count; i++) { var 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(CultureInfo.InvariantCulture, "{0} {1}", audioStream.CodecAltName, audioStream.ChannelDescription); if (audioStream.BitRate > 0) { audio2 += string.Format(CultureInfo.InvariantCulture, " {0}Kbps", (int)Math.Round((double)audioStream.BitRate / 1000)); } if (audioStream.SampleRate > 0 && audioStream.BitDepth > 0) { audio2 += string.Format(CultureInfo.InvariantCulture, " ({0}kHz/{1}-bit)", (int)Math.Round((double)audioStream.SampleRate / 1000), audioStream.BitDepth); } break; } } } report.Append("\r\n"); report.Append("********************\r\n"); report.Append("PLAYLIST: " + playlist.Name + "\r\n"); report.Append("********************\r\n"); report.Append("\r\n"); report.Append("<--- BEGIN FORUMS PASTE --->\r\n"); report.Append("[code]\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", "", "", "", "", "", "Total", "Video", "", "")); report.Append(string.Format(CultureInfo.InvariantCulture, "{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.Append(string.Format(CultureInfo.InvariantCulture, "{0,-64}{1,-8}{2,-8}{3,-16}{4,-16}{5,-8}{6,-8}{7,-42}{8}\r\n", "-----", "------", "-------", "--------------", "--------------", "-------", "-------", "------------------", "---------------------")); report.Append(string.Format(CultureInfo.InvariantCulture, "{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.Append("[/code]\r\n"); report.Append("\r\n"); report.Append("[code]\r\n"); report.Append("\r\n"); report.Append("DISC INFO:\r\n"); report.Append("\r\n"); if (!string.IsNullOrEmpty(BDROM.DiscTitle)) { report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Disc Title:", BDROM.DiscTitle)); } report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Disc Label:", BDROM.VolumeLabel)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1:N0} bytes\r\n", "Disc Size:", BDROM.Size)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Protection:", protection)); if (extraFeatures.Count > 0) { report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1}\r\n", "Extras:", string.Join(", ", extraFeatures.ToArray()))); } /*report.Append(string.Format(CultureInfo.InvariantCulture, * "{0,-16}{1}\r\n", "BDInfo:", Application.ProductVersion);*/ report.Append("\r\n"); report.Append("PLAYLIST REPORT:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1}\r\n", "Name:", title)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} (h:m:s.ms)\r\n", "Length:", totalLength)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1:N0} bytes\r\n", "Size:", totalSize)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} Mbps\r\n", "Total Bitrate:", totalBitrate)); if (playlist.AngleCount > 0) { for (var angleIndex = 0; angleIndex < playlist.AngleCount; angleIndex++) { report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} (h:m:s.ms) / {2} (h:m:s.ms)\r\n", string.Format(CultureInfo.InvariantCulture, "Angle {0} Length:", angleIndex + 1), angleLengths[angleIndex], angleTotalLengths[angleIndex])); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1:N0} bytes / {2:N0} bytes\r\n", string.Format(CultureInfo.InvariantCulture, "Angle {0} Size:", angleIndex + 1), angleSizes[angleIndex], angleTotalSizes[angleIndex])); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} Mbps / {2} Mbps\r\n", string.Format(CultureInfo.InvariantCulture, "Angle {0} Total Bitrate:", angleIndex + 1), angleBitrates[angleIndex], angleTotalBitrates[angleIndex], angleIndex)); } report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} (h:m:s.ms)\r\n", "All Angles Length:", totalAngleLength)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} bytes\r\n", "All Angles Size:", totalAngleSize)); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1} Mbps\r\n", "All Angles Bitrate:", totalAngleBitrate)); } /* * report.Append(string.Format( * "{0,-24}{1}\r\n", "Description:", ""); */ if (!string.IsNullOrEmpty(BDROM.DiscTitle)) { summary += string.Format(CultureInfo.InvariantCulture, "Disc Title: {0}\r\n", BDROM.DiscTitle); } summary += string.Format(CultureInfo.InvariantCulture, "Disc Label: {0}\r\n", BDROM.VolumeLabel); summary += string.Format(CultureInfo.InvariantCulture, "Disc Size: {0:N0} bytes\r\n", BDROM.Size); summary += string.Format(CultureInfo.InvariantCulture, "Protection: {0}\r\n", protection); summary += string.Format(CultureInfo.InvariantCulture, "Playlist: {0}\r\n", title); summary += string.Format(CultureInfo.InvariantCulture, "Size: {0:N0} bytes\r\n", totalSize); summary += string.Format(CultureInfo.InvariantCulture, "Length: {0}\r\n", totalLength); summary += string.Format(CultureInfo.InvariantCulture, "Total Bitrate: {0} Mbps\r\n", totalBitrate); if (playlist.HasHiddenTracks) { report.Append("\r\n(*) Indicates included stream hidden by this playlist.\r\n"); } if (playlist.VideoStreams.Count > 0) { report.Append("\r\n"); report.Append("VIDEO:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1,-20}{2,-16}\r\n", "Codec", "Bitrate", "Description")); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1,-20}{2,-16}\r\n", "-----", "-------", "-----------")); foreach (var stream in playlist.SortedStreams) { if (!stream.IsVideoStream) { continue; } var streamName = stream.CodecName; if (stream.AngleIndex > 0) { streamName += string.Format(CultureInfo.InvariantCulture, " ({0})", stream.AngleIndex); } var streamBitrate = string.Format(CultureInfo.InvariantCulture, "{0:D}", (int)Math.Round((double)stream.BitRate / 1000)); if (stream.AngleIndex > 0) { streamBitrate += string.Format(CultureInfo.InvariantCulture, " ({0:D})", (int)Math.Round((double)stream.ActiveBitRate / 1000)); } streamBitrate += " kbps"; report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-24}{1,-20}{2,-16}\r\n", (stream.IsHidden ? "* " : "") + streamName, streamBitrate, stream.Description)); summary += string.Format(CultureInfo.InvariantCulture, (stream.IsHidden ? "* " : "") + "Video: {0} / {1} / {2}\r\n", streamName, streamBitrate, stream.Description); } } if (playlist.AudioStreams.Count > 0) { report.Append("\r\n"); report.Append("AUDIO:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description")); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------")); foreach (var stream in playlist.SortedStreams) { if (!stream.IsAudioStream) { continue; } var streamBitrate = string.Format(CultureInfo.InvariantCulture, "{0:D} kbps", (int)Math.Round((double)stream.BitRate / 1000)); report.Append(string.Format(CultureInfo.InvariantCulture, "{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.Append("\r\n"); report.Append("SUBTITLES:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description")); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------")); foreach (var stream in playlist.SortedStreams) { if (!stream.IsGraphicsStream) { continue; } var streamBitrate = string.Format(CultureInfo.InvariantCulture, "{0:F3} kbps", (double)stream.BitRate / 1000); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description)); summary += string.Format(CultureInfo.InvariantCulture, (stream.IsHidden ? "* " : "") + "Subtitle: {0} / {1}\r\n", stream.LanguageName, streamBitrate, stream.Description); } } if (playlist.TextStreams.Count > 0) { report.Append("\r\n"); report.Append("TEXT:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "Codec", "Language", "Bitrate", "Description")); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", "-----", "--------", "-------", "-----------")); foreach (var stream in playlist.SortedStreams) { if (!stream.IsTextStream) { continue; } var streamBitrate = string.Format(CultureInfo.InvariantCulture, "{0:F3} kbps", (double)stream.BitRate / 1000); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-32}{1,-16}{2,-16}{3,-16}\r\n", (stream.IsHidden ? "* " : "") + stream.CodecName, stream.LanguageName, streamBitrate, stream.Description)); } } report.Append("\r\n"); report.Append("FILES:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", "Name", "Time In", "Length", "Size", "Total Bitrate")); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", "----", "-------", "------", "----", "-------------")); foreach (var clip in playlist.StreamClips) { var clipName = clip.DisplayName; if (clip.AngleIndex > 0) { clipName += string.Format(CultureInfo.InvariantCulture, " ({0})", clip.AngleIndex); } var clipSize = string.Format(CultureInfo.InvariantCulture, "{0:N0}", clip.PacketSize); var clipInSpan = new TimeSpan((long)(clip.RelativeTimeIn * 10000000)); var clipOutSpan = new TimeSpan((long)(clip.RelativeTimeOut * 10000000)); var clipLengthSpan = new TimeSpan((long)(clip.Length * 10000000)); var clipTimeIn = string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", clipInSpan.Hours, clipInSpan.Minutes, clipInSpan.Seconds, clipInSpan.Milliseconds); var clipLength = string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", clipLengthSpan.Hours, clipLengthSpan.Minutes, clipLengthSpan.Seconds, clipLengthSpan.Milliseconds); var clipBitrate = Math.Round((double)clip.PacketBitRate / 1000).ToString("N0", CultureInfo.InvariantCulture); report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1,-16}{2,-16}{3,-16}{4,-16}\r\n", clipName, clipTimeIn, clipLength, clipSize, clipBitrate)); } report.Append("\r\n"); report.Append("CHAPTERS:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{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.Append(string.Format(CultureInfo.InvariantCulture, "{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", "------", "-------", "------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------", "--------------")); var window1Bits = new Queue <double>(); var window1Seconds = new Queue <double>(); double window1BitsSum = 0; double window1SecondsSum = 0; double window1PeakBitrate = 0; double window1PeakLocation = 0; var window5Bits = new Queue <double>(); var window5Seconds = new Queue <double>(); double window5BitsSum = 0; double window5SecondsSum = 0; double window5PeakBitrate = 0; double window5PeakLocation = 0; var window10Bits = new Queue <double>(); var 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; var diagPID = playlist.VideoStreams[0].PID; var chapterIndex = 0; var clipIndex = 0; var 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; } var chapterStart = playlist.Chapters[chapterIndex]; double chapterEnd; if (chapterIndex < playlist.Chapters.Count - 1) { chapterEnd = playlist.Chapters[chapterIndex + 1]; } else { chapterEnd = playlist.TotalLength; } var 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) { var diag = diagList[diagIndex++]; if (diag.Marker < clip.TimeIn) { continue; } chapterPosition = diag.Marker - clip.TimeIn + clip.RelativeTimeIn; var seconds = diag.Interval; var 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) { var bitrate = window1BitsSum / window1SecondsSum; if (bitrate > window1PeakBitrate && chapterPosition - window1SecondsSum > 0) { window1PeakBitrate = bitrate; window1PeakLocation = chapterPosition - window1SecondsSum; } window1BitsSum -= window1Bits.Dequeue(); window1SecondsSum -= window1Seconds.Dequeue(); } if (window5SecondsSum > 5.0) { var 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) { var 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; var window1PeakSpan = new TimeSpan((long)(window1PeakLocation * 10000000)); var window5PeakSpan = new TimeSpan((long)(window5PeakLocation * 10000000)); var window10PeakSpan = new TimeSpan((long)(window10PeakLocation * 10000000)); var chapterMaxFrameSpan = new TimeSpan((long)(chapterMaxFrameLocation * 10000000)); var chapterStartSpan = new TimeSpan((long)(chapterStart * 10000000)); var chapterEndSpan = new TimeSpan((long)(chapterEnd * 10000000)); var 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.Append(string.Format(CultureInfo.InvariantCulture, "{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(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", chapterStartSpan.Hours, chapterStartSpan.Minutes, chapterStartSpan.Seconds, chapterStartSpan.Milliseconds), string.Format(CultureInfo.InvariantCulture, "{0:D1}:{1:D2}:{2:D2}.{3:D3}", chapterLengthSpan.Hours, chapterLengthSpan.Minutes, chapterLengthSpan.Seconds, chapterLengthSpan.Milliseconds), string.Format(CultureInfo.InvariantCulture, "{0:N0} kbps", Math.Round(chapterBitrate / 1000)), string.Format(CultureInfo.InvariantCulture, "{0:N0} kbps", Math.Round(window1PeakBitrate / 1000)), string.Format(CultureInfo.InvariantCulture, "{0:D2}:{1:D2}:{2:D2}.{3:D3}", window1PeakSpan.Hours, window1PeakSpan.Minutes, window1PeakSpan.Seconds, window1PeakSpan.Milliseconds), string.Format(CultureInfo.InvariantCulture, "{0:N0} kbps", Math.Round(window5PeakBitrate / 1000)), string.Format(CultureInfo.InvariantCulture, "{0:D2}:{1:D2}:{2:D2}.{3:D3}", window5PeakSpan.Hours, window5PeakSpan.Minutes, window5PeakSpan.Seconds, window5PeakSpan.Milliseconds), string.Format(CultureInfo.InvariantCulture, "{0:N0} kbps", Math.Round(window10PeakBitrate / 1000)), string.Format(CultureInfo.InvariantCulture, "{0:D2}:{1:D2}:{2:D2}.{3:D3}", window10PeakSpan.Hours, window10PeakSpan.Minutes, window10PeakSpan.Seconds, window10PeakSpan.Milliseconds), string.Format(CultureInfo.InvariantCulture, "{0:N0} bytes", chapterAvgFrameSize), string.Format(CultureInfo.InvariantCulture, "{0:N0} bytes", chapterMaxFrameSize), string.Format(CultureInfo.InvariantCulture, "{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.Append("\r\n"); report.Append("STREAM DIAGNOSTICS:\r\n"); report.Append("\r\n"); report.Append(string.Format(CultureInfo.InvariantCulture, "{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.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1,-16}{2,-16}{3,-16}{4,-24}{5,-24}{6,-24}{7,-16}{8,-16}\r\n", "----", "---", "----", "-----", "--------", "--------------", "--------------", "-------------", "-----", "-------")); var reportedClips = new Dictionary <string, TSStreamClip>(); foreach (var clip in playlist.StreamClips) { if (clip.StreamFile == null) { continue; } if (reportedClips.ContainsKey(clip.Name)) { continue; } reportedClips[clip.Name] = clip; var clipName = clip.DisplayName; if (clip.AngleIndex > 0) { clipName += string.Format(CultureInfo.InvariantCulture, " ({0})", clip.AngleIndex); } foreach (var clipStream in clip.StreamFile.Streams.Values) { if (!playlist.Streams.ContainsKey(clipStream.PID)) { continue; } var playlistStream = playlist.Streams[clipStream.PID]; var clipBitRate = "0"; var clipSeconds = "0"; if (clip.StreamFile.Length > 0) { clipSeconds = clip.StreamFile.Length.ToString("F3", CultureInfo.InvariantCulture); clipBitRate = Math.Round((double)clipStream.PayloadBytes * 8 / clip.StreamFile.Length / 1000) .ToString("N0", CultureInfo.InvariantCulture); } var language = ""; if (!string.IsNullOrEmpty(playlistStream.LanguageCode)) { language = string.Format(CultureInfo.InvariantCulture, "{0} ({1})", playlistStream.LanguageCode, playlistStream.LanguageName); } report.Append(string.Format(CultureInfo.InvariantCulture, "{0,-16}{1,-16}{2,-16}{3,-16}{4,-24}{5,-24}{6,-24}{7,-16}{8,-16}\r\n", clipName, string.Format(CultureInfo.InvariantCulture, "{0} (0x{1:X})", clipStream.PID, clipStream.PID), string.Format(CultureInfo.InvariantCulture, "0x{0:X2}", (byte)clipStream.StreamType), clipStream.CodecShortName, language, clipSeconds, clipBitRate, clipStream.PayloadBytes.ToString("N0", CultureInfo.InvariantCulture), clipStream.PacketCount.ToString("N0", CultureInfo.InvariantCulture))); } } } report.Append("\r\n"); report.Append("[/code]\r\n"); report.Append("<---- END FORUMS PASTE ---->\r\n"); report.Append("\r\n"); if (BDInfoSettings.GenerateTextSummary) { report.Append("QUICK SUMMARY:\r\n\r\n"); report.Append(summary); report.Append("\r\n"); } } return(report.ToString()); }
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; }