├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── dotnet.yml
├── .gitignore
├── BDInfo.Core
├── BDCommon
│ ├── BDCommon.csproj
│ ├── Cloner.cs
│ ├── Properties
│ │ └── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ ├── ScanBDROMResult.cs
│ ├── ScanBDROMState.cs
│ ├── ToolBox.cs
│ └── rom
│ │ ├── BDInfoSettings.cs
│ │ ├── BDROM.cs
│ │ ├── IO
│ │ ├── DirectoryInfo.cs
│ │ ├── DiscDirectoryInfo.cs
│ │ ├── DiscFileInfo.cs
│ │ ├── FileInfo.cs
│ │ ├── IDirectoryInfo.cs
│ │ └── IFileInfo.cs
│ │ ├── LanguageCodes.cs
│ │ ├── TSCodecAAC.cs
│ │ ├── TSCodecAC3.cs
│ │ ├── TSCodecAVC.cs
│ │ ├── TSCodecDTS.cs
│ │ ├── TSCodecDTSHD.cs
│ │ ├── TSCodecHEVC.cs
│ │ ├── TSCodecLPCM.cs
│ │ ├── TSCodecMPA.cs
│ │ ├── TSCodecMPEG2.cs
│ │ ├── TSCodecMVC.cs
│ │ ├── TSCodecPGS.cs
│ │ ├── TSCodecTrueHD.cs
│ │ ├── TSCodecVC1.cs
│ │ ├── TSInterleavedFile.cs
│ │ ├── TSPlaylistFile.cs
│ │ ├── TSStream.cs
│ │ ├── TSStreamBuffer.cs
│ │ ├── TSStreamClip.cs
│ │ ├── TSStreamClipFile.cs
│ │ └── TSStreamFile.cs
├── BDExtractor
│ ├── BDExtractor.csproj
│ ├── CmdOptions.cs
│ ├── FileCopier.cs
│ ├── FolderUtility.cs
│ ├── Program.cs
│ ├── Properties
│ │ ├── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ │ └── launchSettings.json
│ └── SizeConverter.cs
├── BDInfo.Core.sln
├── BDInfo
│ ├── BDInfo.csproj
│ ├── BDSettings.cs
│ ├── CmdOptions.cs
│ ├── Program.cs
│ └── Properties
│ │ ├── PublishProfiles
│ │ └── FolderProfile.pubxml
│ │ └── launchSettings.json
└── BDInfoDataSubstractor
│ ├── BDInfoDataSubstractor.csproj
│ ├── BdInfoDataModel.cs
│ ├── DataContentManager.cs
│ └── Program.cs
├── Nuget.config
├── README.md
└── docs
├── _config.yml
└── index.md
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet.yml:
--------------------------------------------------------------------------------
1 | name: Build x64
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | tags:
7 | - 'v*'
8 |
9 | env:
10 | version: 2.0.6
11 | dotnetfolder: 'net9.0'
12 | bdinfo_key: "bdinfo"
13 | bdextract_key: "bdextractor"
14 | bdsubstractor_key: "bdinfodatasubstractor"
15 |
16 |
17 | jobs:
18 | build_linux:
19 |
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v4
23 | - name: Setup .NET
24 | uses: actions/setup-dotnet@v4
25 | with:
26 | dotnet-version: 9.x
27 | - name: Remove organization git
28 | run: dotnet nuget remove source github
29 | continue-on-error: true
30 | #- name: Add organization git
31 | # env:
32 | # NUGET_REPO_SECRET: ${{ secrets.NUGET_REPO_SECRET }}
33 | # #run: dotnet nuget add source --username Sonic3R --password ${{ secrets.NUGET_REPO_SECRET }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/dotnetcorecorner/index.json"
34 | # run: dotnet nuget add source "https://nuget.pkg.github.com/dotnetcorecorner/index.json" --name github --username Sonic3R --password ${{ env.NUGET_REPO_SECRET }} --store-password-in-clear-text
35 | - name: Restore dependencies
36 | run: dotnet restore BDInfo.Core/BDInfo.Core.sln
37 | - name: Build against errors
38 | run: dotnet build BDInfo.Core/BDInfo.Core.sln --no-restore
39 | - name: Create self-contained binary for BDInfo
40 | run: dotnet publish BDInfo.Core/BDInfo/BDInfo.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
41 | - name: Create self-contained binary for BDExtractor
42 | run: dotnet publish BDInfo.Core/BDExtractor/BDExtractor.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
43 | - name: Create self-contained binary for BDInfoDataSubstractor
44 | run: dotnet publish BDInfo.Core/BDInfoDataSubstractor/BDInfoDataSubstractor.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
45 |
46 | - name: BDInfo Zip Release
47 | # You may pin to the exact commit or the version.
48 | # uses: TheDoctor0/zip-release@591e9b128012d3328db6043d0d0266c3ac27f9b5
49 | uses: TheDoctor0/zip-release@0.7.6
50 | with:
51 | # Filename for archive
52 | filename: ${{ env.bdinfo_key }}_linux_v${{ env.version }}.zip
53 | # Base path for archive files
54 | path: .
55 | # Working directory before zipping
56 | directory: BDInfo.Core/BDInfo/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/
57 | # List of excluded files / directories
58 | #exclusions: # optional, default is
59 | # Tool to use for archiving
60 | type: zip
61 |
62 | - name: BDExtractor ZIP release
63 | uses: TheDoctor0/zip-release@0.7.6
64 | with:
65 | # Filename for archive
66 | filename: ${{ env.bdextract_key }}_linux_v${{ env.version }}.zip
67 | # Base path for archive files
68 | path: .
69 | # Working directory before zipping
70 | directory: BDInfo.Core/BDExtractor/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/
71 | # List of excluded files / directories
72 | #exclusions: # optional, default is
73 | # Tool to use for archiving
74 | type: zip
75 |
76 | - name: BDInfoDataSubstractor ZIP release
77 | uses: TheDoctor0/zip-release@0.7.6
78 | with:
79 | # Filename for archive
80 | filename: ${{ env.bdsubstractor_key }}_linux_v${{ env.version }}.zip
81 | # Base path for archive files
82 | path: .
83 | # Working directory before zipping
84 | directory: BDInfo.Core/BDInfoDataSubstractor/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/
85 | # List of excluded files / directories
86 | #exclusions: # optional, default is
87 | # Tool to use for archiving
88 | type: zip
89 |
90 | - name: Create Release
91 | id: create_release
92 | uses: actions/create-release@v1
93 | env:
94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95 | with:
96 | tag_name: linux-${{ env.version }}
97 | release_name: Release Linux x64 ${{ env.version }}
98 | draft: false
99 | prerelease: false
100 |
101 | - name: Upload BDInfo
102 | id: upload-release-asset-bdinfo
103 | uses: actions/upload-release-asset@v1
104 | env:
105 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106 | with:
107 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
108 | asset_path: BDInfo.Core/BDInfo/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/${{ env.bdinfo_key }}_linux_v${{ env.version }}.zip
109 | asset_name: ${{ env.bdinfo_key }}_linux_v${{ env.version }}.zip
110 | asset_content_type: application/zip
111 |
112 | - name: Upload BDExtractor
113 | id: upload-release-asset-bdextractor
114 | uses: actions/upload-release-asset@v1
115 | env:
116 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117 | with:
118 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
119 | asset_path: BDInfo.Core/BDExtractor/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/${{ env.bdextract_key }}_linux_v${{ env.version }}.zip
120 | asset_name: ${{ env.bdextract_key }}_linux_v${{ env.version }}.zip
121 | asset_content_type: application/zip
122 |
123 | - name: Upload BDInfoDataSubstractor
124 | id: upload-release-asset-bdinfodatasubstractor
125 | uses: actions/upload-release-asset@v1
126 | env:
127 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
128 | with:
129 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
130 | asset_path: BDInfo.Core/BDInfoDataSubstractor/bin/Release/${{ env.dotnetfolder }}/linux-x64/publish/${{ env.bdsubstractor_key }}_linux_v${{ env.version }}.zip
131 | asset_name: ${{ env.bdsubstractor_key }}_linux_v${{ env.version }}.zip
132 | asset_content_type: application/zip
133 |
134 |
135 | build_windows:
136 |
137 | runs-on: windows-latest
138 | needs: [build_linux]
139 | steps:
140 | - uses: actions/checkout@v4
141 | - name: Setup .NET
142 | uses: actions/setup-dotnet@v4
143 | with:
144 | dotnet-version: 9.x
145 | - name: Remove organization git
146 | run: dotnet nuget remove source github
147 | continue-on-error: true
148 | #- name: Add organization git
149 | # env:
150 | # NUGET_REPO_SECRET: ${{ secrets.NUGET_REPO_SECRET }}
151 | # run: dotnet nuget add source "https://nuget.pkg.github.com/dotnetcorecorner/index.json" --name github --username Sonic3R --password ${{ env.NUGET_REPO_SECRET }} --store-password-in-clear-text
152 | - name: Restore dependencies
153 | run: dotnet restore BDInfo.Core/BDInfo.Core.sln
154 | - name: Build against errors
155 | run: dotnet build BDInfo.Core/BDInfo.Core.sln --no-restore
156 | - name: Create self-contained binary for BDInfo
157 | run: dotnet publish BDInfo.Core/BDInfo/BDInfo.csproj -c Release -r win-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
158 | - name: Create self-contained binary for BDExtractor
159 | run: dotnet publish BDInfo.Core/BDExtractor/BDExtractor.csproj -c Release -r win-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
160 | - name: Create self-contained binary for BDInfoDataSubstractor
161 | run: dotnet publish BDInfo.Core/BDInfoDataSubstractor/BDInfoDataSubstractor.csproj -c Release -r win-x64 -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false --self-contained
162 |
163 | - name: BDInfo Zip Release
164 | # You may pin to the exact commit or the version.
165 | # uses: TheDoctor0/zip-release@591e9b128012d3328db6043d0d0266c3ac27f9b5
166 | uses: TheDoctor0/zip-release@0.7.6
167 | with:
168 | # Filename for archive
169 | filename: ${{ env.bdinfo_key }}_win_v${{ env.version }}.zip
170 | # Base path for archive files
171 | path: .
172 | # Working directory before zipping
173 | directory: BDInfo.Core/BDInfo/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/
174 | # List of excluded files / directories
175 | #exclusions: # optional, default is
176 | # Tool to use for archiving
177 | type: zip
178 |
179 | - name: BDExtractor ZIP release
180 | uses: TheDoctor0/zip-release@0.7.6
181 | with:
182 | # Filename for archive
183 | filename: ${{ env.bdextract_key }}_win_v${{ env.version }}.zip
184 | # Base path for archive files
185 | path: .
186 | # Working directory before zipping
187 | directory: BDInfo.Core/BDExtractor/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/
188 | # List of excluded files / directories
189 | #exclusions: # optional, default is
190 | # Tool to use for archiving
191 | type: zip
192 |
193 | - name: BDInfoDataSubstractor ZIP release
194 | uses: TheDoctor0/zip-release@0.7.6
195 | with:
196 | # Filename for archive
197 | filename: ${{ env.bdsubstractor_key }}_win_v${{ env.version }}.zip
198 | # Base path for archive files
199 | path: .
200 | # Working directory before zipping
201 | directory: BDInfo.Core/BDInfoDataSubstractor/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/
202 | # List of excluded files / directories
203 | #exclusions: # optional, default is
204 | # Tool to use for archiving
205 | type: zip
206 |
207 | - name: Create Release
208 | id: create_release
209 | uses: actions/create-release@v1
210 | env:
211 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
212 | with:
213 | tag_name: win-${{ env.version }}
214 | release_name: Release Windows x64 ${{ env.version }}
215 | draft: false
216 | prerelease: false
217 |
218 | - name: Upload BDInfo
219 | id: upload-release-asset-bdinfo
220 | uses: actions/upload-release-asset@v1
221 | env:
222 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
223 | with:
224 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
225 | asset_path: BDInfo.Core/BDInfo/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/${{ env.bdinfo_key }}_win_v${{ env.version }}.zip
226 | asset_name: ${{ env.bdinfo_key }}_win_v${{ env.version }}.zip
227 | asset_content_type: application/zip
228 |
229 | - name: Upload BDExtractor
230 | id: upload-release-asset-bdextractor
231 | uses: actions/upload-release-asset@v1
232 | env:
233 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
234 | with:
235 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
236 | asset_path: BDInfo.Core/BDExtractor/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/${{ env.bdextract_key }}_win_v${{ env.version }}.zip
237 | asset_name: ${{ env.bdextract_key }}_win_v${{ env.version }}.zip
238 | asset_content_type: application/zip
239 |
240 | - name: Upload BDInfoDataSubstractor
241 | id: upload-release-asset-bdinfodatasubstractor
242 | uses: actions/upload-release-asset@v1
243 | env:
244 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
245 | with:
246 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
247 | asset_path: BDInfo.Core/BDInfoDataSubstractor/bin/Release/${{ env.dotnetfolder }}/win-x64/publish/${{ env.bdsubstractor_key }}_win_v${{ env.version }}.zip
248 | asset_name: ${{ env.bdsubstractor_key }}_win_v${{ env.version }}.zip
249 | asset_content_type: application/zip
250 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | .vs
6 | bin
7 | obj
8 | packages
9 | *.user
10 | /BDInfo.Core/BDInfoDataSubstractor/Properties/launchSettings.json
11 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/BDCommon.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | win-x64;linux-x64
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/Cloner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.Json;
3 |
4 | namespace BDCommon
5 | {
6 | public static class Cloner
7 | {
8 | ///
9 | /// Perform a deep copy of the object via serialization.
10 | ///
11 | /// The type of object being copied.
12 | /// The object instance to copy.
13 | /// A deep copy of the object.
14 | public static T Clone(T source)
15 | {
16 | if (!typeof(T).IsSerializable)
17 | {
18 | throw new ArgumentException("The type must be serializable.", nameof(source));
19 | }
20 |
21 | var serializedData = JsonSerializer.Serialize(source);
22 | return JsonSerializer.Deserialize(serializedData);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Release
8 | Any CPU
9 | bin\Release\netstandard2.0\publish\linux-x64
10 | FileSystem
11 | netstandard2.0
12 | linux-x64
13 |
14 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/ScanBDROMResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace BDCommon
5 | {
6 | public class ScanBDROMResult
7 | {
8 | public Exception ScanException = new Exception("Scan has not been run.");
9 | public Dictionary FileExceptions = new Dictionary();
10 | }
11 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/ScanBDROMState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace BDCommon
5 | {
6 | public class ScanBDROMState
7 | {
8 | public long TotalBytes { get { return _tb; } set { _tb = value; OnReportChange?.Invoke(this); } }
9 | public long FinishedBytes { get { return _fb; } set { _fb = value; OnReportChange?.Invoke(this); } }
10 | public DateTime TimeStarted = DateTime.Now;
11 | public TSStreamFile StreamFile = null;
12 | public Dictionary> PlaylistMap = new Dictionary>();
13 | public Exception Exception = null;
14 |
15 | private long _tb;
16 | private long _fb;
17 |
18 | public event Action OnReportChange;
19 | }
20 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/ToolBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace BDCommon
5 | {
6 | public class ToolBox
7 | {
8 | public static string FormatFileSize(double fSize, bool formatHR = false)
9 | {
10 | if (fSize <= 0) return "0";
11 | var units = new[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
12 |
13 | var digitGroups = 0;
14 | if (formatHR)
15 | digitGroups = (int)(Math.Log10(fSize) / Math.Log10(1024));
16 |
17 | return FormattableString.Invariant($"{fSize / Math.Pow(1024, digitGroups):N2} {units[digitGroups]}");
18 | }
19 |
20 | public static string ReadString(byte[] data, int count, ref int pos)
21 | {
22 | string val = Encoding.ASCII.GetString(data, pos, count);
23 | pos += count;
24 | return val;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/BDInfoSettings.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon
21 | {
22 | public abstract class BDInfoSettings
23 | {
24 | public abstract bool GenerateStreamDiagnostics { get; }
25 |
26 | public abstract bool ExtendedStreamDiagnostics { get; }
27 |
28 | public abstract bool EnableSSIF { get; }
29 |
30 | public abstract bool FilterLoopingPlaylists { get; }
31 |
32 | public abstract bool FilterShortPlaylists { get; }
33 |
34 | public abstract int FilterShortPlaylistsValue { get; }
35 |
36 | public abstract bool KeepStreamOrder { get; }
37 |
38 | public abstract bool GenerateTextSummary { get; }
39 |
40 | public abstract string ReportFileName { get; }
41 |
42 | public abstract bool IncludeVersionAndNotes { get; }
43 |
44 | public abstract bool GroupByTime { get; }
45 | }
46 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/BDROM.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 | using System.Collections.Generic;
22 | using System.IO;
23 | using System.Linq;
24 | using System.Xml;
25 | using BDCommon;
26 | using BDCommon.IO;
27 | using DiscUtils.Udf;
28 |
29 | namespace BDCommon;
30 |
31 | public class BDROM
32 | {
33 | public IDirectoryInfo DirectoryRoot;
34 | public IDirectoryInfo DirectoryBDMV;
35 |
36 | public IDirectoryInfo DirectoryBDJO;
37 | public IDirectoryInfo DirectoryCLIPINF;
38 | public IDirectoryInfo DirectoryPLAYLIST;
39 | public IDirectoryInfo DirectorySNP;
40 | public IDirectoryInfo DirectorySSIF;
41 | public IDirectoryInfo DirectorySTREAM;
42 | public IDirectoryInfo DirectoryMeta;
43 |
44 | public string VolumeLabel;
45 | public string DiscTitle;
46 | public ulong Size;
47 | public bool IsBDPlus;
48 | public bool IsBDJava;
49 | public bool IsDBOX;
50 | public bool IsPSP;
51 | public bool Is3D;
52 | public bool Is50Hz;
53 | public bool IsUHD;
54 |
55 | public Dictionary PlaylistFiles = new();
56 | public Dictionary StreamClipFiles = new();
57 | public Dictionary StreamFiles = new();
58 | public Dictionary InterleavedFiles = new();
59 |
60 | private static List _excludeDirs = new() { "ANY!", "AACS", "BDSVM", "ANYVM", "SLYVM" };
61 | private readonly BDInfoSettings _settings;
62 |
63 | public delegate bool OnStreamClipFileScanError(TSStreamClipFile streamClipFile, Exception ex);
64 |
65 | public event OnStreamClipFileScanError StreamClipFileScanError;
66 |
67 | public delegate bool OnStreamFileScanError(TSStreamFile streamClipFile, Exception ex);
68 |
69 | public event OnStreamFileScanError StreamFileScanError;
70 |
71 | public delegate bool OnPlaylistFileScanError(TSPlaylistFile playlistFile, Exception ex);
72 |
73 | public event OnPlaylistFileScanError PlaylistFileScanError;
74 |
75 | public BDROM(string path, BDInfoSettings bDInfoSettings)
76 | {
77 | _settings = bDInfoSettings;
78 |
79 | //
80 | // Locate BDMV directories.
81 | //
82 | var pathInfo = BDCommon.IO.FileInfo.FromFullName(path);
83 | IDirectoryInfo tempPath;
84 | if (pathInfo.IsDir)
85 | tempPath = BDCommon.IO.DirectoryInfo.FromDirectoryName(pathInfo.FullName);
86 | else
87 | {
88 | Stream fileStream = File.OpenRead(pathInfo.FullName);
89 | var cdReader = new UdfReader(fileStream);
90 | tempPath = DiscDirectoryInfo.FromImage(cdReader, "BDMV");
91 | }
92 | DirectoryBDMV = GetDirectoryBDMV(tempPath);
93 |
94 | if (DirectoryBDMV == null)
95 | {
96 | throw new Exception("Unable to locate BD structure.");
97 | }
98 |
99 | DirectoryRoot = DirectoryBDMV.Parent;
100 |
101 | DirectoryBDJO = GetDirectory("BDJO", DirectoryBDMV, 0);
102 | DirectoryCLIPINF = GetDirectory("CLIPINF", DirectoryBDMV, 0);
103 | DirectoryPLAYLIST = GetDirectory("PLAYLIST", DirectoryBDMV, 0);
104 | DirectorySNP = GetDirectory("SNP", DirectoryRoot, 0);
105 | DirectorySTREAM = GetDirectory("STREAM", DirectoryBDMV, 0);
106 | DirectorySSIF = GetDirectory("SSIF", DirectorySTREAM, 0);
107 | DirectoryMeta = GetDirectory("META", DirectoryBDMV, 0);
108 |
109 | if (DirectoryCLIPINF == null || DirectoryPLAYLIST == null)
110 | {
111 | throw new Exception("Unable to locate BD structure.");
112 | }
113 |
114 | VolumeLabel = DirectoryRoot.GetVolumeLabel();
115 | Size = (ulong)GetDirectorySize(DirectoryRoot);
116 |
117 | var indexFiles = DirectoryBDMV?.GetFiles();
118 | var indexFile = indexFiles?.FirstOrDefault(t => t.Name.ToLower() == "index.bdmv");
119 |
120 | if (indexFile != null)
121 | {
122 | using var indexStream = indexFile.OpenRead();
123 | ReadIndexVersion(indexStream);
124 | }
125 |
126 | if (null != GetDirectory("BDSVM", DirectoryRoot, 0))
127 | {
128 | IsBDPlus = true;
129 | }
130 | if (null != GetDirectory("SLYVM", DirectoryRoot, 0))
131 | {
132 | IsBDPlus = true;
133 | }
134 | if (null != GetDirectory("ANYVM", DirectoryRoot, 0))
135 | {
136 | IsBDPlus = true;
137 | }
138 |
139 | if (DirectoryBDJO?.GetFiles().Length > 0)
140 | {
141 | IsBDJava = true;
142 | }
143 |
144 | if (DirectorySNP != null &&
145 | (DirectorySNP.GetFiles("*.mnv").Length > 0 || DirectorySNP.GetFiles("*.MNV").Length > 0))
146 | {
147 | IsPSP = true;
148 | }
149 |
150 | if (DirectorySSIF?.GetFiles().Length > 0)
151 | {
152 | Is3D = true;
153 | }
154 |
155 | var fullName = DirectoryRoot.FullName;
156 | if (fullName != null && File.Exists(Path.Combine(fullName, "FilmIndex.xml")))
157 | {
158 | IsDBOX = true;
159 | }
160 |
161 | var metaFiles = DirectoryMeta?.GetFiles("bdmt_eng.xml", SearchOption.AllDirectories);
162 | if (metaFiles is { Length: > 0 })
163 | {
164 | ReadDiscTitle(metaFiles.First().OpenText());
165 | }
166 |
167 | //
168 | // Initialize file lists.
169 | //
170 | if (DirectoryPLAYLIST != null)
171 | {
172 | var files = DirectoryPLAYLIST.GetFiles("*.mpls");
173 | if (files.Length == 0)
174 | {
175 | files = DirectoryPLAYLIST.GetFiles("*.MPLS");
176 | }
177 | foreach (var file in files)
178 | {
179 | PlaylistFiles.Add(file.Name.ToUpper(), new TSPlaylistFile(this, file, _settings));
180 | }
181 | }
182 |
183 | if (DirectorySTREAM != null)
184 | {
185 | var files = DirectorySTREAM.GetFiles("*.m2ts");
186 | if (files.Length == 0)
187 | {
188 | files = DirectorySTREAM.GetFiles("*.M2TS");
189 | }
190 | foreach (var file in files)
191 | {
192 | StreamFiles.Add(file.Name.ToUpper(), new TSStreamFile(file, _settings));
193 | }
194 | }
195 |
196 | if (DirectoryCLIPINF != null)
197 | {
198 | var files = DirectoryCLIPINF.GetFiles("*.clpi");
199 | if (files.Length == 0)
200 | {
201 | files = DirectoryCLIPINF.GetFiles("*.CLPI");
202 | }
203 | foreach (var file in files)
204 | {
205 | StreamClipFiles.Add(file.Name.ToUpper(), new TSStreamClipFile(file));
206 | }
207 | }
208 |
209 | if (DirectorySSIF != null)
210 | {
211 | var files = DirectorySSIF.GetFiles("*.ssif");
212 | if (files.Length == 0)
213 | {
214 | files = DirectorySSIF.GetFiles("*.SSIF");
215 | }
216 | foreach (var file in files)
217 | {
218 | InterleavedFiles.Add(file.Name.ToUpper(), new TSInterleavedFile(file));
219 | }
220 | }
221 | }
222 |
223 | private void ReadDiscTitle(StreamReader fileStream)
224 | {
225 | try
226 | {
227 | var xDoc = new XmlDocument();
228 | xDoc.Load(fileStream);
229 | var xNsMgr = new XmlNamespaceManager(xDoc.NameTable);
230 | xNsMgr.AddNamespace("di", "urn:BDA:bdmv;discinfo");
231 | var xNode = xDoc.DocumentElement?.SelectSingleNode("di:discinfo/di:title/di:name", xNsMgr);
232 | DiscTitle = xNode?.InnerText;
233 |
234 | if (!string.IsNullOrEmpty(DiscTitle) && DiscTitle.ToLowerInvariant() == "blu-ray")
235 | DiscTitle = null;
236 | }
237 | catch (Exception)
238 | {
239 | DiscTitle = null;
240 | }
241 | finally
242 | {
243 | fileStream.Close();
244 | }
245 |
246 | }
247 |
248 | public void Scan()
249 | {
250 | var errorStreamClipFiles = new List();
251 | foreach (var streamClipFile in StreamClipFiles.Values)
252 | {
253 | try
254 | {
255 | streamClipFile.Scan();
256 | }
257 | catch (Exception ex)
258 | {
259 | errorStreamClipFiles.Add(streamClipFile);
260 | if (StreamClipFileScanError != null)
261 | {
262 | if (!StreamClipFileScanError(streamClipFile, ex))
263 | {
264 | break;
265 | }
266 | }
267 | else throw;
268 | }
269 | }
270 |
271 | foreach (var streamFile in StreamFiles.Values)
272 | {
273 | var ssifName = Path.GetFileNameWithoutExtension(streamFile.Name) + ".SSIF";
274 | if (InterleavedFiles.ContainsKey(ssifName))
275 | {
276 | streamFile.InterleavedFile = InterleavedFiles[ssifName];
277 | }
278 | }
279 |
280 | var streamFiles = new TSStreamFile[StreamFiles.Count];
281 | StreamFiles.Values.CopyTo(streamFiles, 0);
282 | Array.Sort(streamFiles, CompareStreamFiles);
283 |
284 | var errorPlaylistFiles = new List();
285 | foreach (var playlistFile in PlaylistFiles.Values)
286 | {
287 | try
288 | {
289 | playlistFile.Scan(StreamFiles, StreamClipFiles);
290 | }
291 | catch (Exception ex)
292 | {
293 | errorPlaylistFiles.Add(playlistFile);
294 | if (PlaylistFileScanError != null)
295 | {
296 | if (!PlaylistFileScanError(playlistFile, ex))
297 | {
298 | break;
299 | }
300 | }
301 | else throw;
302 | }
303 | }
304 |
305 | var errorStreamFiles = new List();
306 | foreach (var streamFile in streamFiles)
307 | {
308 | try
309 | {
310 | var playlists = PlaylistFiles.Values.Where(playlist =>
311 | playlist.StreamClips.Any(streamClip => streamClip.Name == streamFile.Name))
312 | .ToList();
313 | streamFile.Scan(playlists, false);
314 | }
315 | catch (Exception ex)
316 | {
317 | errorStreamFiles.Add(streamFile);
318 | if (StreamFileScanError != null)
319 | {
320 | if (!StreamFileScanError(streamFile, ex))
321 | {
322 | break;
323 | }
324 | }
325 | else throw;
326 | }
327 | }
328 |
329 | foreach (var playlistFile in PlaylistFiles.Values)
330 | {
331 | playlistFile.Initialize();
332 |
333 | if (Is50Hz) continue;
334 |
335 | var vidStreamCount = playlistFile.VideoStreams.Count;
336 | foreach (var videoStream in playlistFile.VideoStreams)
337 | {
338 | if (videoStream.FrameRate is TSFrameRate.FRAMERATE_25 or TSFrameRate.FRAMERATE_50)
339 | {
340 | Is50Hz = true;
341 | }
342 |
343 | if (vidStreamCount <= 1 || !Is3D) continue;
344 |
345 | switch (videoStream.StreamType)
346 | {
347 | case TSStreamType.AVC_VIDEO when playlistFile.MVCBaseViewR:
348 | case TSStreamType.MVC_VIDEO when !playlistFile.MVCBaseViewR:
349 | videoStream.BaseView = true;
350 | break;
351 | case TSStreamType.AVC_VIDEO:
352 | case TSStreamType.MVC_VIDEO:
353 | videoStream.BaseView = false;
354 | break;
355 | default:
356 | videoStream.BaseView = false;
357 | break;
358 | }
359 |
360 | }
361 | }
362 | }
363 |
364 | private IDirectoryInfo GetDirectoryBDMV(IDirectoryInfo path)
365 | {
366 | var dir = path;
367 |
368 | while (dir != null)
369 | {
370 | if (dir.Name == "BDMV")
371 | {
372 | return dir;
373 | }
374 | dir = dir.Parent;
375 | }
376 |
377 | return GetDirectory("BDMV", path, 0);
378 | }
379 |
380 | private static IDirectoryInfo GetDirectory(string name, IDirectoryInfo dir, int searchDepth)
381 | {
382 | if (dir == null) return null;
383 |
384 | var children = dir.GetDirectories();
385 | foreach (var child in children)
386 | {
387 | if (child.Name == name)
388 | {
389 | return child;
390 | }
391 | }
392 |
393 | if (searchDepth <= 0) return null;
394 | foreach (var child in children)
395 | {
396 | GetDirectory(
397 | name, child, searchDepth - 1);
398 | }
399 |
400 | return null;
401 | }
402 |
403 | private static long GetDirectorySize(IDirectoryInfo directoryInfo)
404 | {
405 | var pathFiles = directoryInfo.GetFiles();
406 | var size = pathFiles.Where(pathFile => pathFile.Extension.ToUpper() != ".SSIF").Sum(pathFile => pathFile.Length);
407 |
408 | var pathChildren = directoryInfo.GetDirectories();
409 | size += pathChildren.Sum(GetDirectorySize);
410 | return size;
411 | }
412 |
413 | public static int CompareStreamFiles(TSStreamFile x, TSStreamFile y)
414 | {
415 | // TODO: Use interleaved file sizes
416 |
417 | if (x.FileInfo == null && y.FileInfo == null)
418 | {
419 | return 0;
420 | }
421 |
422 | if (x.FileInfo == null && y.FileInfo != null)
423 | {
424 | return 1;
425 | }
426 |
427 | if (y.FileInfo == null && x.FileInfo != null)
428 | {
429 | return -1;
430 | }
431 |
432 | if (x.FileInfo.Length > y.FileInfo.Length)
433 | {
434 | return 1;
435 | }
436 |
437 | if (y.FileInfo.Length > x.FileInfo.Length)
438 | {
439 | return -1;
440 | }
441 |
442 | return 0;
443 | }
444 |
445 | private void ReadIndexVersion(Stream indexStream)
446 | {
447 | var buffer = new byte[8];
448 | var count = indexStream.Read(buffer, 0, 8);
449 | var pos = 0;
450 | if (count <= 0) return;
451 |
452 | var indexVer = ToolBox.ReadString(buffer, count, ref pos);
453 | IsUHD = indexVer == "INDX0300";
454 | }
455 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/DirectoryInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 | using System.IO;
22 |
23 | namespace BDCommon.IO;
24 |
25 | public class DirectoryInfo : IDirectoryInfo
26 | {
27 | private readonly System.IO.DirectoryInfo _impl;
28 | public string Name => _impl.Name;
29 |
30 | public string FullName => _impl.FullName;
31 |
32 | public IDirectoryInfo Parent => _impl.Parent != null ? new DirectoryInfo(_impl.Parent) : null;
33 |
34 | public DirectoryInfo(string path)
35 | {
36 | _impl = new System.IO.DirectoryInfo(path);
37 | }
38 |
39 | public DirectoryInfo(System.IO.DirectoryInfo impl)
40 | {
41 | _impl = impl;
42 | }
43 |
44 | public IDirectoryInfo[] GetDirectories()
45 | {
46 | return Array.ConvertAll(_impl.GetDirectories(), x => new DirectoryInfo(x));
47 | }
48 |
49 | public IFileInfo[] GetFiles()
50 | {
51 | return Array.ConvertAll(_impl.GetFiles(), x => new FileInfo(x));
52 | }
53 |
54 | public IFileInfo[] GetFiles(string searchPattern)
55 | {
56 | return Array.ConvertAll(_impl.GetFiles(searchPattern), x => new FileInfo(x));
57 | }
58 |
59 | public IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption)
60 | {
61 | return Array.ConvertAll(_impl.GetFiles(searchPattern, searchOption), x => new FileInfo(x));
62 | }
63 |
64 | public string GetVolumeLabel()
65 | {
66 | try
67 | {
68 | var driveInfo = new DriveInfo(_impl.FullName);
69 | return _impl.Root.FullName == _impl.FullName ? driveInfo.VolumeLabel : Name;
70 | }
71 | catch (Exception)
72 | {
73 | return Name;
74 | }
75 | }
76 |
77 | public static IDirectoryInfo FromDirectoryName(string path)
78 | {
79 | return new DirectoryInfo(path);
80 | }
81 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/DiscDirectoryInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 | using System.IO;
22 |
23 | namespace BDCommon.IO;
24 |
25 | public class DiscDirectoryInfo : IDirectoryInfo
26 | {
27 | private readonly DiscUtils.DiscDirectoryInfo _impl;
28 | public string Name => _impl.Name;
29 |
30 | public string FullName => _impl.FullName;
31 |
32 | public IDirectoryInfo Parent => _impl.Parent != null ? new DiscDirectoryInfo(_impl.Parent) : null;
33 |
34 | public DiscDirectoryInfo(DiscUtils.DiscDirectoryInfo impl)
35 | {
36 | _impl = impl;
37 | }
38 |
39 | public IDirectoryInfo[] GetDirectories()
40 | {
41 | return Array.ConvertAll(_impl.GetDirectories(), x => new DiscDirectoryInfo(x));
42 | }
43 |
44 | public IFileInfo[] GetFiles()
45 | {
46 | return Array.ConvertAll(_impl.GetFiles(), x => new DiscFileInfo(x));
47 | }
48 |
49 | public IFileInfo[] GetFiles(string searchPattern)
50 | {
51 | return Array.ConvertAll(_impl.GetFiles(searchPattern), x => new DiscFileInfo(x));
52 | }
53 |
54 | public IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption)
55 | {
56 | return Array.ConvertAll(_impl.GetFiles(searchPattern, searchOption), x => new DiscFileInfo(x));
57 | }
58 | public string GetVolumeLabel()
59 | {
60 | return _impl.FileSystem.VolumeLabel;
61 | }
62 |
63 | public static IDirectoryInfo FromImage(DiscUtils.Udf.UdfReader reader, string path)
64 | {
65 | return new DiscDirectoryInfo(reader.GetDirectoryInfo(path));
66 | }
67 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/DiscFileInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System.IO;
21 |
22 | namespace BDCommon.IO;
23 |
24 | public class DiscFileInfo : IFileInfo
25 | {
26 | private readonly DiscUtils.DiscFileInfo _impl;
27 | public string Name => _impl.Name;
28 |
29 | public string FullName => _impl.FullName;
30 |
31 | public string Extension => _impl.Extension;
32 |
33 | public long Length => _impl.Length;
34 |
35 | public bool IsDir => _impl.Attributes.HasFlag(FileAttributes.Directory);
36 |
37 | public bool IsImage => true;
38 |
39 | public DiscFileInfo(DiscUtils.DiscFileInfo impl)
40 | {
41 | _impl = impl;
42 | }
43 |
44 | public Stream OpenRead()
45 | {
46 | return _impl.OpenRead();
47 | }
48 |
49 | public StreamReader OpenText()
50 | {
51 | return _impl.OpenText();
52 | }
53 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/FileInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System.IO;
21 |
22 | namespace BDCommon.IO;
23 |
24 | public class FileInfo : IFileInfo
25 | {
26 | private readonly System.IO.FileInfo _impl;
27 | public string Name => _impl.Name;
28 |
29 | public string FullName => _impl.FullName;
30 |
31 | public string Extension => _impl.Extension;
32 |
33 | public long Length => _impl.Length;
34 |
35 | public bool IsDir => _impl.Attributes.HasFlag(FileAttributes.Directory);
36 |
37 | public bool IsImage => false;
38 |
39 | public FileInfo(System.IO.FileInfo impl)
40 | {
41 | _impl = impl;
42 | }
43 |
44 | public Stream OpenRead()
45 | {
46 | return _impl.OpenRead();
47 | }
48 |
49 | public System.IO.StreamReader OpenText()
50 | {
51 | return _impl.OpenText();
52 | }
53 |
54 | public static IFileInfo FromFullName(string path)
55 | {
56 | return new FileInfo(new System.IO.FileInfo(path));
57 | }
58 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/IDirectoryInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System.IO;
21 |
22 | namespace BDCommon.IO;
23 |
24 | public interface IDirectoryInfo
25 | {
26 | string Name { get; }
27 | string FullName { get; }
28 | IDirectoryInfo Parent { get; }
29 | IFileInfo[] GetFiles();
30 | IFileInfo[] GetFiles(string searchPattern);
31 | IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption);
32 | string GetVolumeLabel();
33 | IDirectoryInfo[] GetDirectories();
34 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/IO/IFileInfo.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System.IO;
21 |
22 | namespace BDCommon.IO;
23 |
24 | public interface IFileInfo
25 | {
26 | string Name { get; }
27 | string FullName { get; }
28 | string Extension { get; }
29 | long Length { get; }
30 | bool IsDir { get; }
31 | bool IsImage { get; }
32 |
33 | Stream OpenRead();
34 | StreamReader OpenText();
35 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/LanguageCodes.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class LanguageCodes
23 | {
24 | public static string GetName(string code)
25 | {
26 | return code switch
27 | {
28 | "abk" => "Abkhazian",
29 | "ace" => "Achinese",
30 | "ach" => "Acoli",
31 | "ada" => "Adangme",
32 | "aar" => "Afar",
33 | "afh" => "Afrihili",
34 | "afr" => "Afrikaans",
35 | "afa" => "Afro-Asiatic (Other)",
36 | "aka" => "Akan",
37 | "akk" => "Akkadian",
38 | "alb" => "Albanian",
39 | "sqi" => "Albanian",
40 | "ale" => "Aleut",
41 | "alg" => "Algonquian languages",
42 | "tut" => "Altaic (Other)",
43 | "amh" => "Amharic",
44 | "apa" => "Apache languages",
45 | "ara" => "Arabic",
46 | "arc" => "Aramaic",
47 | "arp" => "Arapaho",
48 | "arn" => "Araucanian",
49 | "arw" => "Arawak",
50 | "arm" => "Armenian",
51 | "hye" => "Armenian",
52 | "art" => "Artificial (Other)",
53 | "asm" => "Assamese",
54 | "ath" => "Athapascan languages",
55 | "aus" => "Australian languages",
56 | "map" => "Austronesian (Other)",
57 | "ava" => "Avaric",
58 | "ave" => "Avestan",
59 | "awa" => "Awadhi",
60 | "aym" => "Aymara",
61 | "aze" => "Azerbaijani",
62 | "ban" => "Balinese",
63 | "bat" => "Baltic (Other)",
64 | "bal" => "Baluchi",
65 | "bam" => "Bambara",
66 | "bai" => "Bamileke languages",
67 | "bad" => "Banda",
68 | "bnt" => "Bantu (Other)",
69 | "bas" => "Basa",
70 | "bak" => "Bashkir",
71 | "baq" => "Basque",
72 | "eus" => "Basque",
73 | "btk" => "Batak (Indonesia)",
74 | "bej" => "Beja",
75 | "bel" => "Belarusian",
76 | "bem" => "Bemba",
77 | "ben" => "Bengali",
78 | "ber" => "Berber (Other)",
79 | "bho" => "Bhojpuri",
80 | "bih" => "Bihari",
81 | "bik" => "Bikol",
82 | "bin" => "Bini",
83 | "bis" => "Bislama",
84 | "bos" => "Bosnian",
85 | "bra" => "Braj",
86 | "bre" => "Breton",
87 | "bug" => "Buginese",
88 | "bul" => "Bulgarian",
89 | "bua" => "Buriat",
90 | "bur" => "Burmese",
91 | "mya" => "Burmese",
92 | "cad" => "Caddo",
93 | "car" => "Carib",
94 | "cat" => "Catalan",
95 | "cau" => "Caucasian (Other)",
96 | "ceb" => "Cebuano",
97 | "cel" => "Celtic (Other)",
98 | "cai" => "Central American Indian (Other)",
99 | "chg" => "Chagatai",
100 | "cmc" => "Chamic languages",
101 | "cha" => "Chamorro",
102 | "che" => "Chechen",
103 | "chr" => "Cherokee",
104 | "chy" => "Cheyenne",
105 | "chb" => "Chibcha",
106 | "chi" => "Chinese",
107 | "zho" => "Chinese",
108 | "chn" => "Chinook jargon",
109 | "chp" => "Chipewyan",
110 | "cho" => "Choctaw",
111 | "chu" => "Church Slavic",
112 | "chk" => "Chuukese",
113 | "chv" => "Chuvash",
114 | "cop" => "Coptic",
115 | "cor" => "Cornish",
116 | "cos" => "Corsican",
117 | "cre" => "Cree",
118 | "mus" => "Creek",
119 | "crp" => "Creoles and pidgins (Other)",
120 | "cpe" => "Creoles and pidgins,",
121 | "cpf" => "Creoles and pidgins,",
122 | "cpp" => "Creoles and pidgins,",
123 | "scr" => "Croatian",
124 | "hrv" => "Croatian",
125 | "cus" => "Cushitic (Other)",
126 | "cze" => "Czech",
127 | "ces" => "Czech",
128 | "dak" => "Dakota",
129 | "dan" => "Danish",
130 | "day" => "Dayak",
131 | "del" => "Delaware",
132 | "din" => "Dinka",
133 | "div" => "Divehi",
134 | "doi" => "Dogri",
135 | "dgr" => "Dogrib",
136 | "dra" => "Dravidian (Other)",
137 | "dua" => "Duala",
138 | "dut" => "Dutch",
139 | "nld" => "Dutch",
140 | "dum" => "Dutch, Middle (ca. 1050-1350)",
141 | "dyu" => "Dyula",
142 | "dzo" => "Dzongkha",
143 | "efi" => "Efik",
144 | "egy" => "Egyptian (Ancient)",
145 | "eka" => "Ekajuk",
146 | "elx" => "Elamite",
147 | "eng" => "English",
148 | "enm" => "English, Middle (1100-1500)",
149 | "ang" => "English, Old (ca.450-1100)",
150 | "epo" => "Esperanto",
151 | "est" => "Estonian",
152 | "ewe" => "Ewe",
153 | "ewo" => "Ewondo",
154 | "fan" => "Fang",
155 | "fat" => "Fanti",
156 | "fao" => "Faroese",
157 | "fij" => "Fijian",
158 | "fin" => "Finnish",
159 | "fiu" => "Finno-Ugrian (Other)",
160 | "fon" => "Fon",
161 | "fre" => "French",
162 | "fra" => "French",
163 | "frm" => "French, Middle (ca.1400-1600)",
164 | "fro" => "French, Old (842-ca.1400)",
165 | "fry" => "Frisian",
166 | "fur" => "Friulian",
167 | "ful" => "Fulah",
168 | "gaa" => "Ga",
169 | "glg" => "Gallegan",
170 | "lug" => "Ganda",
171 | "gay" => "Gayo",
172 | "gba" => "Gbaya",
173 | "gez" => "Geez",
174 | "geo" => "Georgian",
175 | "kat" => "Georgian",
176 | "ger" => "German",
177 | "deu" => "German",
178 | "nds" => "Saxon",
179 | "gmh" => "German, Middle High (ca.1050-1500)",
180 | "goh" => "German, Old High (ca.750-1050)",
181 | "gem" => "Germanic (Other)",
182 | "gil" => "Gilbertese",
183 | "gon" => "Gondi",
184 | "gor" => "Gorontalo",
185 | "got" => "Gothic",
186 | "grb" => "Grebo",
187 | "grc" => "Greek, Ancient (to 1453)",
188 | "gre" => "Greek",
189 | "ell" => "Greek",
190 | "grn" => "Guarani",
191 | "guj" => "Gujarati",
192 | "gwi" => "Gwich´in",
193 | "hai" => "Haida",
194 | "hau" => "Hausa",
195 | "haw" => "Hawaiian",
196 | "heb" => "Hebrew",
197 | "her" => "Herero",
198 | "hil" => "Hiligaynon",
199 | "him" => "Himachali",
200 | "hin" => "Hindi",
201 | "hmo" => "Hiri Motu",
202 | "hit" => "Hittite",
203 | "hmn" => "Hmong",
204 | "hun" => "Hungarian",
205 | "hup" => "Hupa",
206 | "iba" => "Iban",
207 | "ice" => "Icelandic",
208 | "isl" => "Icelandic",
209 | "ibo" => "Igbo",
210 | "ijo" => "Ijo",
211 | "ilo" => "Iloko",
212 | "inc" => "Indic (Other)",
213 | "ine" => "Indo-European (Other)",
214 | "ind" => "Indonesian",
215 | "ina" => "Interlingua (International",
216 | "ile" => "Interlingue",
217 | "iku" => "Inuktitut",
218 | "ipk" => "Inupiaq",
219 | "ira" => "Iranian (Other)",
220 | "gle" => "Irish",
221 | "mga" => "Irish, Middle (900-1200)",
222 | "sga" => "Irish, Old (to 900)",
223 | "iro" => "Iroquoian languages",
224 | "ita" => "Italian",
225 | "jpn" => "Japanese",
226 | "jav" => "Javanese",
227 | "jrb" => "Judeo-Arabic",
228 | "jpr" => "Judeo-Persian",
229 | "kab" => "Kabyle",
230 | "kac" => "Kachin",
231 | "kal" => "Kalaallisut",
232 | "kam" => "Kamba",
233 | "kan" => "Kannada",
234 | "kau" => "Kanuri",
235 | "kaa" => "Kara-Kalpak",
236 | "kar" => "Karen",
237 | "kas" => "Kashmiri",
238 | "kaw" => "Kawi",
239 | "kaz" => "Kazakh",
240 | "kha" => "Khasi",
241 | "khm" => "Khmer",
242 | "khi" => "Khoisan (Other)",
243 | "kho" => "Khotanese",
244 | "kik" => "Kikuyu",
245 | "kmb" => "Kimbundu",
246 | "kin" => "Kinyarwanda",
247 | "kir" => "Kirghiz",
248 | "kom" => "Komi",
249 | "kon" => "Kongo",
250 | "kok" => "Konkani",
251 | "kor" => "Korean",
252 | "kos" => "Kosraean",
253 | "kpe" => "Kpelle",
254 | "kro" => "Kru",
255 | "kua" => "Kuanyama",
256 | "kum" => "Kumyk",
257 | "kur" => "Kurdish",
258 | "kru" => "Kurukh",
259 | "kut" => "Kutenai",
260 | "lad" => "Ladino",
261 | "lah" => "Lahnda",
262 | "lam" => "Lamba",
263 | "lao" => "Lao",
264 | "lat" => "Latin",
265 | "lav" => "Latvian",
266 | "ltz" => "Letzeburgesch",
267 | "lez" => "Lezghian",
268 | "lin" => "Lingala",
269 | "lit" => "Lithuanian",
270 | "loz" => "Lozi",
271 | "lub" => "Luba-Katanga",
272 | "lua" => "Luba-Lulua",
273 | "lui" => "Luiseno",
274 | "lun" => "Lunda",
275 | "luo" => "Luo (Kenya and Tanzania)",
276 | "lus" => "Lushai",
277 | "mac" => "Macedonian",
278 | "mkd" => "Macedonian",
279 | "mad" => "Madurese",
280 | "mag" => "Magahi",
281 | "mai" => "Maithili",
282 | "mak" => "Makasar",
283 | "mlg" => "Malagasy",
284 | "may" => "Malay",
285 | "msa" => "Malay",
286 | "mal" => "Malayalam",
287 | "mlt" => "Maltese",
288 | "mnc" => "Manchu",
289 | "mdr" => "Mandar",
290 | "man" => "Mandingo",
291 | "mni" => "Manipuri",
292 | "mno" => "Manobo languages",
293 | "glv" => "Manx",
294 | "mao" => "Maori",
295 | "mri" => "Maori",
296 | "mar" => "Marathi",
297 | "chm" => "Mari",
298 | "mah" => "Marshall",
299 | "mwr" => "Marwari",
300 | "mas" => "Masai",
301 | "myn" => "Mayan languages",
302 | "men" => "Mende",
303 | "mic" => "Micmac",
304 | "min" => "Minangkabau",
305 | "mis" => "Miscellaneous languages",
306 | "moh" => "Mohawk",
307 | "mol" => "Moldavian",
308 | "mkh" => "Mon-Khmer (Other)",
309 | "lol" => "Mongo",
310 | "mon" => "Mongolian",
311 | "mos" => "Mossi",
312 | "mul" => "Multiple languages",
313 | "mun" => "Munda languages",
314 | "nah" => "Nahuatl",
315 | "nau" => "Nauru",
316 | "nav" => "Navajo",
317 | "nde" => "Ndebele, North",
318 | "nbl" => "Ndebele, South",
319 | "ndo" => "Ndonga",
320 | "nep" => "Nepali",
321 | "new" => "Newari",
322 | "nia" => "Nias",
323 | "nic" => "Niger-Kordofanian (Other)",
324 | "ssa" => "Nilo-Saharan (Other)",
325 | "niu" => "Niuean",
326 | "non" => "Norse, Old",
327 | "nai" => "North American Indian (Other)",
328 | "sme" => "Northern Sami",
329 | "nor" => "Norwegian",
330 | "nob" => "Norwegian Bokmål",
331 | "nno" => "Norwegian Nynorsk",
332 | "nub" => "Nubian languages",
333 | "nym" => "Nyamwezi",
334 | "nya" => "Nyanja",
335 | "nyn" => "Nyankole",
336 | "nyo" => "Nyoro",
337 | "nzi" => "Nzima",
338 | "oci" => "Occitan",
339 | "oji" => "Ojibwa",
340 | "ori" => "Oriya",
341 | "orm" => "Oromo",
342 | "osa" => "Osage",
343 | "oss" => "Ossetian",
344 | "oto" => "Otomian languages",
345 | "pal" => "Pahlavi",
346 | "pau" => "Palauan",
347 | "pli" => "Pali",
348 | "pam" => "Pampanga",
349 | "pag" => "Pangasinan",
350 | "pan" => "Panjabi",
351 | "pap" => "Papiamento",
352 | "paa" => "Papuan (Other)",
353 | "per" => "Persian",
354 | "fas" => "Persian",
355 | "peo" => "Persian, Old (ca.600-400 B.C.)",
356 | "phi" => "Philippine (Other)",
357 | "phn" => "Phoenician",
358 | "pon" => "Pohnpeian",
359 | "pol" => "Polish",
360 | "por" => "Portuguese",
361 | "pra" => "Prakrit languages",
362 | "pro" => "Provençal",
363 | "pus" => "Pushto",
364 | "que" => "Quechua",
365 | "roh" => "Raeto-Romance",
366 | "raj" => "Rajasthani",
367 | "rap" => "Rapanui",
368 | "rar" => "Rarotongan",
369 | "roa" => "Romance (Other)",
370 | "rum" => "Romanian",
371 | "ron" => "Romanian",
372 | "rom" => "Romany",
373 | "run" => "Rundi",
374 | "rus" => "Russian",
375 | "sal" => "Salishan languages",
376 | "sam" => "Samaritan Aramaic",
377 | "smi" => "Sami languages (Other)",
378 | "smo" => "Samoan",
379 | "sad" => "Sandawe",
380 | "sag" => "Sango",
381 | "san" => "Sanskrit",
382 | "sat" => "Santali",
383 | "srd" => "Sardinian",
384 | "sas" => "Sasak",
385 | "sco" => "Scots",
386 | "gla" => "Gaelic",
387 | "sel" => "Selkup",
388 | "sem" => "Semitic (Other)",
389 | "scc" => "Serbian",
390 | "srp" => "Serbian",
391 | "srr" => "Serer",
392 | "shn" => "Shan",
393 | "sna" => "Shona",
394 | "sid" => "Sidamo",
395 | "sgn" => "Sign languages",
396 | "bla" => "Siksika",
397 | "snd" => "Sindhi",
398 | "sin" => "Sinhalese",
399 | "sit" => "Sino-Tibetan (Other)",
400 | "sio" => "Siouan languages",
401 | "den" => "Slave (Athapascan)",
402 | "sla" => "Slavic (Other)",
403 | "slo" => "Slovak",
404 | "slk" => "Slovak",
405 | "slv" => "Slovenian",
406 | "sog" => "Sogdian",
407 | "som" => "Somali",
408 | "son" => "Songhai",
409 | "snk" => "Soninke",
410 | "wen" => "Sorbian languages",
411 | "nso" => "Sotho, Northern",
412 | "sot" => "Sotho, Southern",
413 | "sai" => "South American Indian (Other)",
414 | "spa" => "Spanish",
415 | "suk" => "Sukuma",
416 | "sux" => "Sumerian",
417 | "sun" => "Sundanese",
418 | "sus" => "Susu",
419 | "swa" => "Swahili",
420 | "ssw" => "Swati",
421 | "swe" => "Swedish",
422 | "syr" => "Syriac",
423 | "tgl" => "Tagalog",
424 | "tah" => "Tahitian",
425 | "tai" => "Tai (Other)",
426 | "tgk" => "Tajik",
427 | "tmh" => "Tamashek",
428 | "tam" => "Tamil",
429 | "tat" => "Tatar",
430 | "tel" => "Telugu",
431 | "ter" => "Tereno",
432 | "tet" => "Tetum",
433 | "tha" => "Thai",
434 | "tib" => "Tibetan",
435 | "bod" => "Tibetan",
436 | "tig" => "Tigre",
437 | "tir" => "Tigrinya",
438 | "tem" => "Timne",
439 | "tiv" => "Tiv",
440 | "tli" => "Tlingit",
441 | "tpi" => "Tok Pisin",
442 | "tkl" => "Tokelau",
443 | "tog" => "Tonga (Nyasa)",
444 | "ton" => "Tonga (Tonga Islands)",
445 | "tsi" => "Tsimshian",
446 | "tso" => "Tsonga",
447 | "tsn" => "Tswana",
448 | "tum" => "Tumbuka",
449 | "tur" => "Turkish",
450 | "ota" => "Turkish, Ottoman (1500-1928)",
451 | "tuk" => "Turkmen",
452 | "tvl" => "Tuvalu",
453 | "tyv" => "Tuvinian",
454 | "twi" => "Twi",
455 | "uga" => "Ugaritic",
456 | "uig" => "Uighur",
457 | "ukr" => "Ukrainian",
458 | "umb" => "Umbundu",
459 | "und" => "Undetermined",
460 | "urd" => "Urdu",
461 | "uzb" => "Uzbek",
462 | "vai" => "Vai",
463 | "ven" => "Venda",
464 | "vie" => "Vietnamese",
465 | "vol" => "Volapük",
466 | "vot" => "Votic",
467 | "wak" => "Wakashan languages",
468 | "wal" => "Walamo",
469 | "war" => "Waray",
470 | "was" => "Washo",
471 | "wel" => "Welsh",
472 | "cym" => "Welsh",
473 | "wol" => "Wolof",
474 | "xho" => "Xhosa",
475 | "sah" => "Yakut",
476 | "yao" => "Yao",
477 | "yap" => "Yapese",
478 | "yid" => "Yiddish",
479 | "yor" => "Yoruba",
480 | "ypk" => "Yupik languages",
481 | "znd" => "Zande",
482 | "zap" => "Zapotec",
483 | "zen" => "Zenaga",
484 | "zha" => "Zhuang",
485 | "zul" => "Zulu",
486 | "zun" => "Zuni",
487 | _ => code
488 | };
489 | }
490 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecAAC.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecAAC
23 | {
24 | private static readonly string[] AacID =
25 | {
26 | "MPEG-4",
27 | "MPEG-2",
28 | };
29 |
30 | private static string GetAacProfile(int profileType)
31 | {
32 | return profileType switch
33 | {
34 | 0 => "AAC Main",
35 | 1 => "AAC LC",
36 | 2 => "AAC SSR",
37 | 3 => "AAC LTP",
38 | 16 => "ER AAC LC",
39 | 18 => "ER AAC LTP",
40 | 36 => "SLS",
41 | _ => ""
42 | };
43 | }
44 |
45 | public static readonly int[] AacSampleRates =
46 | {
47 | 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
48 | 16000, 12000, 11025, 8000, 7350, 0, 0, 57600,
49 | 51200, 40000, 38400, 34150, 28800, 25600, 20000, 19200,
50 | 17075, 14400, 12800, 9600, 0, 0, 0
51 | };
52 |
53 | private const int AacChannelsSize = 8;
54 |
55 | public static readonly int[] AacChannels = { 0, 1, 2, 3, 4, 5, 6, 8 };
56 |
57 | private static readonly byte[] AacChannelModes =
58 | {
59 | (byte)TSAudioMode.Unknown,
60 | (byte)TSAudioMode.Mono,
61 | (byte)TSAudioMode.Stereo,
62 | (byte)TSAudioMode.Extended,
63 | (byte)TSAudioMode.Surround,
64 | (byte)TSAudioMode.Surround,
65 | (byte)TSAudioMode.Surround,
66 | (byte)TSAudioMode.Surround,
67 | };
68 |
69 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag)
70 | {
71 | if (stream.IsInitialized) return;
72 |
73 | int syncWord = buffer.ReadBits2(12);
74 | if (syncWord != 0b1111_1111_1111) return;
75 |
76 | // fixed header
77 | int audioVersionID = buffer.ReadBits2(1);
78 | int layerIndex = buffer.ReadBits2(2);
79 | bool protectionAbsent = buffer.ReadBool();
80 | int profileObjectType = buffer.ReadBits2(2);
81 | int samplingRateIndex = buffer.ReadBits2(4);
82 | bool privateBit = buffer.ReadBool();
83 | int channelMode = buffer.ReadBits2(3);
84 | bool originalBit = buffer.ReadBool();
85 | bool home = buffer.ReadBool();
86 |
87 |
88 | stream.SampleRate = samplingRateIndex <= 13 ? AacSampleRates[samplingRateIndex] : 0;
89 |
90 |
91 | if (channelMode <= AacChannelsSize)
92 | {
93 | stream.AudioMode = (TSAudioMode)AacChannelModes[channelMode];
94 | stream.ChannelCount = AacChannels[channelMode];
95 | }
96 | else
97 | {
98 | stream.ChannelCount = 0;
99 | stream.AudioMode = TSAudioMode.Unknown;
100 | }
101 |
102 | if (channelMode is >= 7 and <= 8)
103 | {
104 | stream.ChannelCount--;
105 | stream.LFE = 1;
106 | }
107 | else
108 | stream.LFE = 0;
109 |
110 | stream.ExtendedData = $"{AacID[audioVersionID]} {GetAacProfile(profileObjectType)}";
111 |
112 | stream.IsVBR = true;
113 | stream.IsInitialized = true;
114 | }
115 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecAC3.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System.IO;
21 |
22 | namespace BDCommon;
23 |
24 | public abstract class TSCodecAC3
25 | {
26 | private static readonly int[] AC3Bitrate =
27 | {
28 | 32,
29 | 40,
30 | 48,
31 | 56,
32 | 64,
33 | 80,
34 | 96,
35 | 112,
36 | 128,
37 | 160,
38 | 192,
39 | 224,
40 | 256,
41 | 320,
42 | 384,
43 | 448,
44 | 512,
45 | 576,
46 | 640,
47 | };
48 |
49 | private static readonly byte[] AC3Channels = { 2, 1, 2, 3, 3, 4, 4, 5 };
50 |
51 | public static byte AC3ChanMap(int chanMap)
52 | {
53 | byte channels = 0;
54 |
55 | for (byte i = 0; i < 16; i++)
56 | {
57 | if ((chanMap & 1 << 15 - i) != 0)
58 | switch (i)
59 | {
60 | case 5:
61 | case 6:
62 | case 9:
63 | case 10:
64 | case 11:
65 | channels += 2; break;
66 | }
67 | }
68 | return channels;
69 | }
70 |
71 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag)
72 | {
73 | if (stream.IsInitialized) return;
74 |
75 | var sync = buffer.ReadBytes(2);
76 | if (sync != null && (sync[0] != 0x0B || sync[1] != 0x77))
77 | {
78 | return;
79 | }
80 |
81 | var secondFrame = stream.ChannelCount > 0;
82 |
83 | uint srCode;
84 | uint frameSize = 0;
85 | uint frameSizeCode = 0;
86 | uint channelMode;
87 | uint lfeOn;
88 | uint dialNorm = 0;
89 | uint dialNormExt = 0;
90 | uint numBlocks = 0;
91 |
92 | var hdr = buffer.ReadBytes(4);
93 |
94 | if (hdr == null) return;
95 |
96 | var bsid = (uint)((hdr[3] & 0xF8) >> 3);
97 | buffer.Seek(-4, SeekOrigin.Current);
98 | if (bsid <= 10)
99 | {
100 | buffer.BSSkipBytes(2);
101 | srCode = buffer.ReadBits2(2);
102 | frameSizeCode = buffer.ReadBits2(6);
103 | bsid = buffer.ReadBits2(5);
104 | buffer.BSSkipBits(3);
105 |
106 | channelMode = buffer.ReadBits2(3);
107 | if ((channelMode & 0x1) > 0 && channelMode != 0x1)
108 | {
109 | buffer.BSSkipBits(2);
110 | }
111 | if ((channelMode & 0x4) > 0)
112 | {
113 | buffer.BSSkipBits(2);
114 | }
115 | if (channelMode == 0x2)
116 | {
117 | var dsurmod = buffer.ReadBits2(2);
118 | if (dsurmod == 0x2)
119 | {
120 | stream.AudioMode = TSAudioMode.Surround;
121 | }
122 | }
123 | lfeOn = buffer.ReadBits2(1);
124 | dialNorm = buffer.ReadBits2(5);
125 | if (buffer.ReadBool())
126 | {
127 | buffer.BSSkipBits(8);
128 | }
129 | if (buffer.ReadBool())
130 | {
131 | buffer.BSSkipBits(8);
132 | }
133 | if (buffer.ReadBool())
134 | {
135 | buffer.BSSkipBits(7);
136 | }
137 | if (channelMode == 0)
138 | {
139 | buffer.BSSkipBits(5);
140 | if (buffer.ReadBool())
141 | {
142 | buffer.BSSkipBits(8);
143 | }
144 | if (buffer.ReadBool())
145 | {
146 | buffer.BSSkipBits(8);
147 | }
148 | if (buffer.ReadBool())
149 | {
150 | buffer.BSSkipBits(7);
151 | }
152 | }
153 | buffer.BSSkipBits(2);
154 | if (bsid == 6)
155 | {
156 | if (buffer.ReadBool())
157 | {
158 | buffer.BSSkipBits(14);
159 | }
160 | if (buffer.ReadBool())
161 | {
162 | uint dsurexmod = buffer.ReadBits2(2);
163 | uint dheadphonmod = buffer.ReadBits2(2);
164 | if (dheadphonmod == 0x2)
165 | {
166 | // TODO
167 | }
168 | buffer.BSSkipBits(10);
169 | if (dsurexmod == 2)
170 | {
171 | stream.AudioMode = TSAudioMode.Extended;
172 | }
173 | }
174 | }
175 | }
176 | else
177 | {
178 | uint frameType = buffer.ReadBits2(2);
179 | buffer.BSSkipBits(3);
180 |
181 | frameSize = buffer.ReadBits4(11) + 1 << 1;
182 |
183 | srCode = buffer.ReadBits2(2);
184 | if (srCode == 3)
185 | {
186 | srCode = buffer.ReadBits2(2);
187 | numBlocks = 3;
188 | }
189 | else
190 | {
191 | numBlocks = buffer.ReadBits2(2);
192 | }
193 | channelMode = buffer.ReadBits2(3);
194 | lfeOn = buffer.ReadBits2(1);
195 | bsid = buffer.ReadBits2(5);
196 | dialNormExt = buffer.ReadBits2(5);
197 |
198 | if (buffer.ReadBool())
199 | {
200 | buffer.BSSkipBits(8);
201 | }
202 | if (channelMode == 0) // 1+1
203 | {
204 | buffer.BSSkipBits(5);
205 | if (buffer.ReadBool())
206 | {
207 | buffer.BSSkipBits(8);
208 | }
209 | }
210 | if (frameType == 1) //dependent stream
211 | {
212 | stream.CoreStream = (TSAudioStream)stream.Clone();
213 | stream.CoreStream.StreamType = TSStreamType.AC3_AUDIO;
214 |
215 | if (buffer.ReadBool()) //channel remapping
216 | {
217 | var chanmap = buffer.ReadBits4(16);
218 |
219 | stream.ChannelCount = stream.CoreStream.ChannelCount;
220 | stream.ChannelCount += AC3ChanMap((int)chanmap);
221 | lfeOn = (uint)stream.CoreStream.LFE;
222 | }
223 | }
224 |
225 | var emdfFound = false;
226 |
227 | do
228 | {
229 | var emdfSync = buffer.ReadBits4(16);
230 | if (emdfSync == 0x5838)
231 | {
232 | emdfFound = true;
233 | break;
234 | }
235 | buffer.Seek(-2, SeekOrigin.Current);
236 | buffer.BSSkipBits(1); // skip 1 bit
237 | } while (buffer.Position < buffer.Length);
238 |
239 | if (emdfFound)
240 | {
241 | var emdfContainerSize = buffer.ReadBits4(16);
242 | var remainAfterEmdf = buffer.DataBitStreamRemain() - emdfContainerSize * 8;
243 |
244 | uint emdfVersion = buffer.ReadBits2(2); //emdf_version
245 | if (emdfVersion == 3)
246 | emdfVersion += buffer.ReadBits2(2);
247 |
248 | if (emdfVersion > 0)
249 | {
250 | buffer.BSSkipBits((int)(buffer.DataBitStreamRemain() - remainAfterEmdf));
251 | }
252 | else
253 | {
254 | var temp = buffer.ReadBits2(3);
255 | if (temp == 0x7)
256 | buffer.BSSkipBits(2); //skip 3 bits
257 |
258 | var emdfPayloadID = buffer.ReadBits2(5);
259 |
260 | if (emdfPayloadID is > 0 and < 16)
261 | {
262 | if (emdfPayloadID == 0x1F)
263 | buffer.BSSkipBits(5); //skip 5 bits
264 |
265 | EmdfPayloadConfig(buffer);
266 |
267 | var emdfPayloadSize = buffer.ReadBits2(8) * 8;
268 | buffer.BSSkipBits(emdfPayloadSize + 1);
269 | }
270 |
271 | while ((emdfPayloadID = buffer.ReadBits2(5)) != 14 && buffer.Position < buffer.Length)
272 | {
273 | if (emdfPayloadID == 0x1F)
274 | buffer.BSSkipBits(5); //skip 5 bits
275 |
276 | EmdfPayloadConfig(buffer);
277 |
278 | var emdfPayloadSize = buffer.ReadBits2(8) * 8;
279 | buffer.ReadBits4(emdfPayloadSize + 1);
280 | }
281 |
282 | if (buffer.Position < buffer.Length && emdfPayloadID == 14)
283 | {
284 | EmdfPayloadConfig(buffer);
285 |
286 | buffer.BSSkipBits(12);
287 |
288 | uint jocNumObjectsBits = buffer.ReadBits2(6);
289 |
290 | if (jocNumObjectsBits > 0)
291 | stream.HasExtensions = true;
292 | }
293 | }
294 | }
295 | }
296 |
297 | if (channelMode < 8 && stream.ChannelCount == 0)
298 | stream.ChannelCount = AC3Channels[channelMode];
299 |
300 | if (stream.AudioMode == TSAudioMode.Unknown)
301 | {
302 | stream.AudioMode = channelMode switch
303 | {
304 | 0 => // 1+1
305 | TSAudioMode.DualMono,
306 | 2 => // 2/0
307 | TSAudioMode.Stereo,
308 | _ => TSAudioMode.Unknown
309 | };
310 | }
311 |
312 | stream.SampleRate = srCode switch
313 | {
314 | 0 => 48000,
315 | 1 => 44100,
316 | 2 => 32000,
317 | _ => 0
318 | };
319 |
320 | if (bsid <= 10)
321 | {
322 |
323 | var fSize = frameSizeCode >> 1;
324 | if (fSize < 19)
325 | stream.BitRate = AC3Bitrate[fSize] * 1000;
326 | }
327 | else
328 | {
329 | stream.BitRate = (long)(4.0 * frameSize * stream.SampleRate / (numBlocks * 256));
330 | if (stream.CoreStream != null)
331 | stream.BitRate += stream.CoreStream.BitRate;
332 | }
333 |
334 | stream.LFE = (int)lfeOn;
335 | if (stream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO)
336 | {
337 | switch (stream.StreamType)
338 | {
339 | case TSStreamType.AC3_PLUS_AUDIO when bsid == 6:
340 | case TSStreamType.AC3_AUDIO:
341 | stream.DialNorm = (int)dialNorm * -1;
342 | break;
343 | case TSStreamType.AC3_PLUS_AUDIO when secondFrame:
344 | stream.DialNorm = (int)dialNormExt * -1;
345 | break;
346 | }
347 | }
348 | stream.IsVBR = false;
349 | if (stream.StreamType == TSStreamType.AC3_PLUS_AUDIO && bsid == 6 && !secondFrame)
350 | stream.IsInitialized = false;
351 | else
352 | stream.IsInitialized = true;
353 | }
354 |
355 | private static void EmdfPayloadConfig(TSStreamBuffer buffer)
356 | {
357 | var sampleOffsetE = buffer.ReadBool();
358 | if (sampleOffsetE)
359 | buffer.BSSkipBits(12);
360 |
361 | if (buffer.ReadBool()) //duratione
362 | buffer.BSSkipBits(11); //duration
363 |
364 | if (buffer.ReadBool()) //groupide
365 | buffer.BSSkipBits(2); //groupid
366 |
367 | if (buffer.ReadBool())
368 | buffer.BSSkipBits(8); // reserved
369 |
370 | if (buffer.ReadBool()) return; //discard_unknown_payload
371 |
372 | buffer.BSSkipBits(1);
373 |
374 | if (sampleOffsetE) return;
375 |
376 | if (buffer.ReadBool()) //payload_frame_aligned
377 | buffer.BSSkipBits(9);
378 | }
379 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecAVC.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | // ReSharper disable NotAccessedVariable
21 | // ReSharper disable RedundantAssignment
22 |
23 | namespace BDCommon;
24 |
25 | public abstract class TSCodecAVC
26 | {
27 | public static void Scan(TSVideoStream stream, TSStreamBuffer buffer, ref string tag)
28 | {
29 | uint parse = 0;
30 | byte accessUnitDelimiterParse = 0;
31 | byte sequenceParameterSetParse = 0;
32 | string profile = null;
33 | byte constraintSet0Flag = 0;
34 | byte constraintSet1Flag = 0;
35 | byte constraintSet2Flag = 0;
36 | byte constraintSet3Flag = 0;
37 |
38 | for (var i = 0; i < buffer.Length; i++)
39 | {
40 | parse = (parse << 8) + buffer.ReadByte(true);
41 |
42 | if (parse == 0x00000109)
43 | {
44 | accessUnitDelimiterParse = 1;
45 | }
46 | else if (accessUnitDelimiterParse > 0)
47 | {
48 | --accessUnitDelimiterParse;
49 |
50 | if (accessUnitDelimiterParse != 0) continue;
51 |
52 | switch ((parse & 0xFF) >> 5)
53 | {
54 | case 0: // I
55 | case 3: // SI
56 | case 5: // I, SI
57 | tag = "I";
58 | break;
59 |
60 | case 1: // I, P
61 | case 4: // SI, SP
62 | case 6: // I, SI, P, SP
63 | tag = "P";
64 | break;
65 |
66 | case 2: // I, P, B
67 | case 7: // I, SI, P, SP, B
68 | tag = "B";
69 | break;
70 | }
71 | if (stream.IsInitialized) return;
72 | }
73 | else if (parse is 0x00000127 or 0x00000167)
74 | {
75 | sequenceParameterSetParse = 3;
76 | }
77 | else if (sequenceParameterSetParse > 0)
78 | {
79 | --sequenceParameterSetParse;
80 | if (!stream.IsInitialized)
81 | switch (sequenceParameterSetParse)
82 | {
83 | case 2:
84 | profile = (parse & 0xFF) switch
85 | {
86 | 66 => "Baseline Profile",
87 | 77 => "Main Profile",
88 | 88 => "Extended Profile",
89 | 100 => "High Profile",
90 | 110 => "High 10 Profile",
91 | 122 => "High 4:2:2 Profile",
92 | 144 => "High 4:4:4 Profile",
93 | _ => "Unknown Profile"
94 | };
95 | break;
96 |
97 | case 1:
98 | constraintSet0Flag = (byte)((parse & 0x80) >> 7);
99 | constraintSet1Flag = (byte)((parse & 0x40) >> 6);
100 | constraintSet2Flag = (byte)((parse & 0x20) >> 5);
101 | constraintSet3Flag = (byte)((parse & 0x10) >> 4);
102 | break;
103 |
104 | case 0:
105 | var b = (byte)(parse & 0xFF);
106 | string level;
107 | if (b == 11 && constraintSet3Flag == 1)
108 | {
109 | level = "1b";
110 | }
111 | else
112 | {
113 | level = $"{b / 10:D}.{b - b / 10 * 10:D}";
114 | }
115 | stream.EncodingProfile = $"{profile} {level}";
116 | stream.IsVBR = true;
117 | stream.IsInitialized = true;
118 | break;
119 | }
120 | }
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecDTS.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon
21 | {
22 | public abstract class TSCodecDTS
23 | {
24 | private static readonly int[] DcaSampleRates =
25 | {
26 | 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
27 | 12000, 24000, 48000, 96000, 192000
28 | };
29 |
30 | private static readonly int[] DcaBitRates =
31 | {
32 | 32000, 56000, 64000, 96000, 112000, 128000,
33 | 192000, 224000, 256000, 320000, 384000,
34 | 448000, 512000, 576000, 640000, 768000,
35 | 896000, 1024000, 1152000, 1280000, 1344000,
36 | 1408000, 1411200, 1472000, 1509000, 1920000,
37 | 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
38 | };
39 |
40 | private static readonly int[] DcaBitsPerSample =
41 | {
42 | 16, 16, 20, 20, 0, 24, 24
43 | };
44 |
45 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag)
46 | {
47 | if (stream.IsInitialized) return;
48 |
49 | var syncFound = false;
50 | uint sync = 0;
51 | for (var i = 0; i < buffer.Length; i++)
52 | {
53 | sync = (sync << 8) + buffer.ReadByte();
54 | if (sync != 0x7FFE8001) continue;
55 |
56 | syncFound = true;
57 | break;
58 | }
59 | if (!syncFound) return;
60 |
61 | buffer.BSSkipBits(6);
62 | var crcPresent = buffer.ReadBits4(1);
63 | buffer.BSSkipBits(7);
64 | var frameSize = buffer.ReadBits4(14);
65 | if (frameSize < 95)
66 | {
67 | return;
68 | }
69 | buffer.BSSkipBits(6);
70 | var sampleRate = buffer.ReadBits4(4);
71 | if (sampleRate >= DcaSampleRates.Length)
72 | {
73 | return;
74 | }
75 | var bitRate = buffer.ReadBits4(5);
76 | if (bitRate >= DcaBitRates.Length)
77 | {
78 | return;
79 | }
80 | buffer.BSSkipBits(8);
81 | var extCoding = buffer.ReadBits4(1);
82 | buffer.BSSkipBits(1);
83 | var lfe = buffer.ReadBits4(2);
84 | buffer.BSSkipBits(1);
85 | if (crcPresent == 1)
86 | {
87 | buffer.BSSkipBits(16);
88 | }
89 | buffer.BSSkipBits(7);
90 | var sourcePcmRes = buffer.ReadBits4(3);
91 | buffer.BSSkipBits(2);
92 | var dialogNorm = buffer.ReadBits4(4);
93 | if (sourcePcmRes >= DcaBitsPerSample.Length)
94 | {
95 | return;
96 | }
97 | buffer.BSSkipBits(4);
98 | var totalChannels = buffer.ReadBits4(3) + 1 + extCoding;
99 |
100 | stream.SampleRate = DcaSampleRates[sampleRate];
101 | stream.ChannelCount = (int)totalChannels;
102 | stream.LFE = lfe > 0 ? 1 : 0;
103 | stream.BitDepth = DcaBitsPerSample[sourcePcmRes];
104 | stream.DialNorm = (int)-dialogNorm;
105 | if ((sourcePcmRes & 0x1) == 0x1)
106 | {
107 | stream.AudioMode = TSAudioMode.Extended;
108 | }
109 |
110 | stream.BitRate = (uint)DcaBitRates[bitRate];
111 | switch (stream.BitRate)
112 | {
113 | case 1:
114 | if (bitrate > 0)
115 | {
116 | stream.BitRate = bitrate;
117 | stream.IsVBR = false;
118 | stream.IsInitialized = true;
119 | }
120 | else
121 | {
122 | stream.BitRate = 0;
123 | }
124 | break;
125 |
126 | case 2:
127 | case 3:
128 | stream.IsVBR = true;
129 | stream.IsInitialized = true;
130 | break;
131 |
132 | default:
133 | stream.IsVBR = false;
134 | stream.IsInitialized = true;
135 | break;
136 | }
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecDTSHD.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecDTSHD
23 | {
24 | private static readonly int[] SampleRates =
25 | {
26 | 0x1F40, 0x3E80, 0x7D00, 0x0FA00, 0x1F400, 0x5622, 0x0AC44, 0x15888, 0x2B110, 0x56220, 0x2EE0, 0x5DC0, 0x0BB80,
27 | 0x17700, 0x2EE00, 0x5DC00
28 | };
29 |
30 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, long bitrate, ref string tag)
31 | {
32 | if (stream.IsInitialized &&
33 | (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO ||
34 | stream.CoreStream is { IsInitialized: true })) return;
35 |
36 | var syncFound = false;
37 | uint sync = 0;
38 | for (var i = 0; i < buffer.Length; i++)
39 | {
40 | sync = (sync << 8) + buffer.ReadByte();
41 | if (sync != 0x64582025) continue;
42 |
43 | syncFound = true;
44 | break;
45 | }
46 |
47 | if (!syncFound)
48 | {
49 | tag = "CORE";
50 | stream.CoreStream ??= new TSAudioStream { StreamType = TSStreamType.DTS_AUDIO };
51 |
52 | if (stream.CoreStream.IsInitialized) return;
53 |
54 | buffer.BeginRead();
55 | TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag);
56 | return;
57 | }
58 |
59 | tag = "HD";
60 | buffer.BSSkipBits(8);
61 | var nuSubStreamIndex = buffer.ReadBits4(2);
62 | var bBlownUpHeader = buffer.ReadBool();
63 |
64 | buffer.BSSkipBits(bBlownUpHeader ? 32 : 24);
65 |
66 | var nuNumAssets = 1;
67 | var bStaticFieldsPresent = buffer.ReadBool();
68 | if (bStaticFieldsPresent)
69 | {
70 | buffer.BSSkipBits(5);
71 |
72 | if (buffer.ReadBool())
73 | {
74 | buffer.BSSkipBits(36);
75 | }
76 | var nuNumAudioPresent = buffer.ReadBits2(3) + 1;
77 | nuNumAssets = buffer.ReadBits2(3) + 1;
78 | var nuActiveExSsMask = new uint[nuNumAudioPresent];
79 | for (var i = 0; i < nuNumAudioPresent; i++)
80 | {
81 | nuActiveExSsMask[i] = buffer.ReadBits4((int)(nuSubStreamIndex + 1)); //?
82 | }
83 | for (var i = 0; i < nuNumAudioPresent; i++)
84 | {
85 | for (var j = 0; j < nuSubStreamIndex + 1; j++)
86 | {
87 | if ((j + 1) % 2 == 1)
88 | {
89 | buffer.BSSkipBits(8);
90 | }
91 | }
92 | }
93 | if (buffer.ReadBool())
94 | {
95 | buffer.BSSkipBits(2);
96 | var nuBits4MixOutMask = buffer.ReadBits2(2) * 4 + 4;
97 | var nuNumMixOutConfigs = buffer.ReadBits2(2) + 1;
98 | var nuMixOutChMask = new uint[nuNumMixOutConfigs];
99 | for (var i = 0; i < nuNumMixOutConfigs; i++)
100 | {
101 | nuMixOutChMask[i] = buffer.ReadBits4(nuBits4MixOutMask);
102 | }
103 | }
104 | }
105 | var assetSizes = new uint[nuNumAssets];
106 | for (var i = 0; i < nuNumAssets; i++)
107 | {
108 | if (bBlownUpHeader)
109 | {
110 | assetSizes[i] = buffer.ReadBits4(20) + 1;
111 | }
112 | else
113 | {
114 | assetSizes[i] = buffer.ReadBits4(16) + 1;
115 | }
116 | }
117 | for (var i = 0; i < nuNumAssets; i++)
118 | {
119 | buffer.BSSkipBits(12);
120 | if (bStaticFieldsPresent)
121 | {
122 | if (buffer.ReadBool())
123 | {
124 | buffer.BSSkipBits(4);
125 | }
126 | if (buffer.ReadBool())
127 | {
128 | buffer.BSSkipBits(24);
129 | }
130 | if (buffer.ReadBool())
131 | {
132 | var nuInfoTextByteSize = buffer.ReadBits2(10) + 1;
133 | var infoText = new ushort[nuInfoTextByteSize];
134 | for (var j = 0; j < nuInfoTextByteSize; j++)
135 | {
136 | infoText[j] = buffer.ReadBits2(8);
137 | }
138 | }
139 | var nuBitResolution = buffer.ReadBits2(5) + 1;
140 | int nuMaxSampleRate = buffer.ReadBits2(4);
141 | var nuTotalNumChs = buffer.ReadBits2(8) + 1;
142 | uint nuSpkrActivityMask = 0;
143 | if (buffer.ReadBool())
144 | {
145 | if (nuTotalNumChs > 2)
146 | {
147 | buffer.BSSkipBits(1);
148 | }
149 | if (nuTotalNumChs > 6)
150 | {
151 | buffer.BSSkipBits(1);
152 | }
153 | if (buffer.ReadBool())
154 | {
155 | int nuNumBits4SAMask = buffer.ReadBits2(2);
156 | nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4;
157 | nuSpkrActivityMask = buffer.ReadBits4(nuNumBits4SAMask);
158 | }
159 | // TODO...
160 | }
161 | stream.SampleRate = SampleRates[nuMaxSampleRate];
162 | stream.BitDepth = nuBitResolution;
163 |
164 | stream.LFE = 0;
165 | if ((nuSpkrActivityMask & 0x8) == 0x8)
166 | {
167 | ++stream.LFE;
168 | }
169 | if ((nuSpkrActivityMask & 0x1000) == 0x1000)
170 | {
171 | ++stream.LFE;
172 | }
173 | stream.ChannelCount = nuTotalNumChs - stream.LFE;
174 | }
175 | if (nuNumAssets > 1)
176 | {
177 | // TODO...
178 | break;
179 | }
180 | }
181 |
182 | uint temp2 = 0;
183 |
184 | while (buffer.Position < buffer.Length)
185 | {
186 | temp2 = (temp2 << 8) + buffer.ReadByte();
187 | switch (temp2)
188 | {
189 | case 0x41A29547: // XLL Extended data
190 | case 0x655E315E: // XBR Extended data
191 | case 0x0A801921: // XSA Extended data
192 | case 0x1D95F262: // X96k
193 | case 0x47004A03: // XXch
194 | case 0x5A5A5A5A: // Xch
195 | var temp3 = 0;
196 | for (var i = (int)buffer.Position; i < buffer.Length; i++)
197 | {
198 | temp3 = (temp3 << 8) + buffer.ReadByte();
199 |
200 | if (temp3 != 0x02000850) continue; //DTS:X Pattern
201 |
202 | stream.HasExtensions = true;
203 | break;
204 | }
205 | break;
206 | }
207 |
208 | if (stream.HasExtensions) break;
209 | }
210 |
211 | // TODO
212 | if (stream.CoreStream != null)
213 | {
214 | var coreStream = stream.CoreStream;
215 | if (coreStream.AudioMode == TSAudioMode.Extended &&
216 | stream.ChannelCount == 5)
217 | {
218 | stream.AudioMode = TSAudioMode.Extended;
219 | }
220 | /*
221 | if (coreStream.DialNorm != 0)
222 | {
223 | stream.DialNorm = coreStream.DialNorm;
224 | }
225 | */
226 | }
227 |
228 | if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO)
229 | {
230 | stream.IsVBR = true;
231 | stream.IsInitialized = true;
232 | }
233 | else if (bitrate > 0)
234 | {
235 | stream.IsVBR = false;
236 | stream.BitRate = bitrate;
237 | if (stream.CoreStream != null)
238 | {
239 | stream.BitRate += stream.CoreStream.BitRate;
240 | stream.IsInitialized = true;
241 | }
242 | stream.IsInitialized = stream.BitRate > 0;
243 | }
244 | }
245 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecLPCM.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecLPCM
23 | {
24 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag)
25 | {
26 | if (stream.IsInitialized) return;
27 |
28 | var header = buffer.ReadBytes(4);
29 | if (header != null)
30 | {
31 | var flags = (header[2] << 8) + header[3];
32 |
33 | switch ((flags & 0xF000) >> 12)
34 | {
35 | case 1: // 1/0/0
36 | stream.ChannelCount = 1;
37 | stream.LFE = 0;
38 | break;
39 | case 3: // 2/0/0
40 | stream.ChannelCount = 2;
41 | stream.LFE = 0;
42 | break;
43 | case 4: // 3/0/0
44 | stream.ChannelCount = 3;
45 | stream.LFE = 0;
46 | break;
47 | case 5: // 2/1/0
48 | stream.ChannelCount = 3;
49 | stream.LFE = 0;
50 | break;
51 | case 6: // 3/1/0
52 | stream.ChannelCount = 4;
53 | stream.LFE = 0;
54 | break;
55 | case 7: // 2/2/0
56 | stream.ChannelCount = 4;
57 | stream.LFE = 0;
58 | break;
59 | case 8: // 3/2/0
60 | stream.ChannelCount = 5;
61 | stream.LFE = 0;
62 | break;
63 | case 9: // 3/2/1
64 | stream.ChannelCount = 5;
65 | stream.LFE = 1;
66 | break;
67 | case 10: // 3/4/0
68 | stream.ChannelCount = 7;
69 | stream.LFE = 0;
70 | break;
71 | case 11: // 3/4/1
72 | stream.ChannelCount = 7;
73 | stream.LFE = 1;
74 | break;
75 | default:
76 | stream.ChannelCount = 0;
77 | stream.LFE = 0;
78 | break;
79 | }
80 |
81 | stream.BitDepth = ((flags & 0xC0) >> 6) switch
82 | {
83 | 1 => 16,
84 | 2 => 20,
85 | 3 => 24,
86 | _ => 0
87 | };
88 |
89 | stream.SampleRate = ((flags & 0xF00) >> 8) switch
90 | {
91 | 1 => 48000,
92 | 4 => 96000,
93 | 5 => 192000,
94 | _ => 0
95 | };
96 | }
97 |
98 | stream.BitRate = (uint)(stream.SampleRate * stream.BitDepth * (stream.ChannelCount + stream.LFE));
99 |
100 | stream.IsVBR = false;
101 | stream.IsInitialized = true;
102 | }
103 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecMPA.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecMPA
23 | {
24 | private static readonly int[][][] MPABitrate =
25 | {
26 | /*
27 | * Audio version ID (see table 3.2 also)
28 | 00 - MPEG Version 2.5 (unofficial extension of MPEG 2)
29 | 01 - reserved
30 | 10 - MPEG Version 2 (ISO/IEC 13818-3)
31 | 11 - MPEG Version 1 (ISO/IEC 11172-3)
32 | -------------
33 | Layer index
34 | 00 - reserved
35 | 01 - Layer III
36 | 10 - Layer II
37 | 11 - Layer I
38 | -----
39 | * // Bitrate Index MPEG 1 MPEG 2, 2.5 (LSF)
40 | Layer I Layer II Layer III Layer I Layer II & III
41 | 0000 free
42 | 0001 32 32 32 32 8
43 | 0010 64 48 40 48 16
44 | 0011 96 56 48 56 24
45 | 0100 128 64 56 64 32
46 | 0101 160 80 64 80 40
47 | 0110 192 96 80 96 48
48 | 0111 224 112 96 112 56
49 | 1000 256 128 112 128 64
50 | 1001 288 160 128 144 80
51 | 1010 320 192 160 160 96
52 | 1011 352 224 192 176 112
53 | 1100 384 256 224 192 128
54 | 1101 416 320 256 224 144
55 | 1110 448 384 320 256 160
56 | 1111 reserved
57 | */
58 | new [] // MPEG Version 2.5
59 | {
60 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // MPEG Version 2.5 Layer 0
61 | new[] {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, // MPEG Version 2.5 Layer III
62 | new[] {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, // MPEG Version 2.5 Layer II
63 | new[] {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}, // MPEG Version 2.5 Layer I
64 | },
65 | new [] // reserved
66 | {
67 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // reserved
68 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // reserved
69 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // reserved
70 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // reserved
71 | },
72 | new [] // MPEG Version 2
73 | {
74 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // MPEG Version 2 Layer 0
75 | new[] {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, // MPEG Version 2 Layer III
76 | new[] {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, // MPEG Version 2 Layer II
77 | new[] {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}, // MPEG Version 2 Layer I
78 | },
79 | new [] // MPEG Version 1
80 | {
81 | new[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // MPEG Version 1 Layer 0
82 | new[] {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}, // MPEG Version 1 Layer III
83 | new[] {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, // MPEG Version 1 Layer II
84 | new[] {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}, // MPEG Version 1 Layer I
85 | }
86 | };
87 |
88 | private static readonly int[][] MPASampleRate =
89 | {
90 | new[] {11025, 12000, 8000, 0}, // MPEG Version 2.5
91 | new[] { 0, 0, 0, 0}, // reserved
92 | new[] {22050, 24000, 16000, 0}, // MPEG Version 2
93 | new[] {44100, 48000, 32000, 0} // MPEG Version 1
94 | };
95 |
96 | private static readonly byte[] MPAChannelModes =
97 | {
98 | (byte)TSAudioMode.Stereo,
99 | (byte)TSAudioMode.JointStereo,
100 | (byte)TSAudioMode.DualMono,
101 | (byte)TSAudioMode.Mono
102 | };
103 |
104 | private static readonly string[] MPAVersion =
105 | {
106 | "MPEG 2.5",
107 | "Unknown MPEG",
108 | "MPEG 2",
109 | "MPEG 1"
110 | };
111 |
112 | private static readonly string[] MPALayer =
113 | {
114 | "Unknown Layer",
115 | "Layer III",
116 | "Layer II",
117 | "Layer I"
118 | };
119 |
120 | private static readonly byte[] MPAChannels = { 2, 2, 2, 1 };
121 |
122 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag)
123 | {
124 | if (stream.IsInitialized) return;
125 |
126 | int syncWord = buffer.ReadBits2(11) << 5;
127 | if (syncWord != 0b1111_1111_1110_0000) return;
128 |
129 | int audioVersionID = buffer.ReadBits2(2);
130 | int layerIndex = buffer.ReadBits2(2);
131 | bool protectionBit = buffer.ReadBool();
132 | int bitrateIndex = buffer.ReadBits2(4);
133 | int samplingRateIndex = buffer.ReadBits2(2);
134 | bool padding = buffer.ReadBool();
135 | bool privateBit = buffer.ReadBool();
136 | int channelMode = buffer.ReadBits2(2);
137 | int modeExtension = buffer.ReadBits2(2);
138 | bool copyrightBit = buffer.ReadBool();
139 | bool originalBit = buffer.ReadBool();
140 | int emphasis = buffer.ReadBits2(2);
141 |
142 | stream.BitRate = MPABitrate[audioVersionID][layerIndex][bitrateIndex] * 1000;
143 | stream.SampleRate = MPASampleRate[audioVersionID][samplingRateIndex];
144 | stream.AudioMode = (TSAudioMode)MPAChannelModes[channelMode];
145 |
146 | stream.ChannelCount = MPAChannels[channelMode];
147 | stream.LFE = 0;
148 |
149 | stream.ExtendedData = $"{MPAVersion[audioVersionID]} {MPALayer[layerIndex]}";
150 |
151 | stream.IsVBR = false;
152 | stream.IsInitialized = true;
153 | }
154 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecMPEG2.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecMPEG2
23 | {
24 | public static void Scan(TSVideoStream stream, TSStreamBuffer buffer, ref string tag)
25 | {
26 | var parse = 0;
27 | var pictureParse = 0;
28 | var sequenceHeaderParse = 0;
29 | var extensionParse = 0;
30 | var sequenceExtensionParse = 0;
31 |
32 | for (var i = 0; i < buffer.Length; i++)
33 | {
34 | parse = (parse << 8) + buffer.ReadByte();
35 |
36 | if (parse == 0x00000100)
37 | {
38 | pictureParse = 2;
39 | }
40 | else if (parse == 0x000001B3)
41 | {
42 | sequenceHeaderParse = 7;
43 | }
44 | else if (sequenceHeaderParse > 0)
45 | {
46 | --sequenceHeaderParse;
47 | switch (sequenceHeaderParse)
48 | {
49 | #if DEBUG
50 | case 6:
51 | break;
52 |
53 | case 5:
54 | break;
55 |
56 | case 4:
57 | stream.Width = (int)((parse & 0xFFF000) >> 12);
58 | stream.Height = (int)(parse & 0xFFF);
59 | break;
60 |
61 | case 3:
62 | stream.AspectRatio = (TSAspectRatio)((parse & 0xF0) >> 4);
63 |
64 | switch ((parse & 0xF0) >> 4)
65 | {
66 | case 0: // Forbidden
67 | break;
68 | case 1: // Square
69 | break;
70 | case 2: // 4:3
71 | break;
72 | case 3: // 16:9
73 | break;
74 | case 4: // 2.21:1
75 | break;
76 | }
77 |
78 | switch (parse & 0xF)
79 | {
80 | case 0: // Forbidden
81 | break;
82 | case 1: // 23.976
83 | stream.FrameRateEnumerator = 24000;
84 | stream.FrameRateDenominator = 1001;
85 | break;
86 | case 2: // 24
87 | stream.FrameRateEnumerator = 24000;
88 | stream.FrameRateDenominator = 1000;
89 | break;
90 | case 3: // 25
91 | stream.FrameRateEnumerator = 25000;
92 | stream.FrameRateDenominator = 1000;
93 | break;
94 | case 4: // 29.97
95 | stream.FrameRateEnumerator = 30000;
96 | stream.FrameRateDenominator = 1001;
97 | break;
98 | case 5: // 30
99 | stream.FrameRateEnumerator = 30000;
100 | stream.FrameRateDenominator = 1000;
101 | break;
102 | case 6: // 50
103 | stream.FrameRateEnumerator = 50000;
104 | stream.FrameRateDenominator = 1000;
105 | break;
106 | case 7: // 59.94
107 | stream.FrameRateEnumerator = 60000;
108 | stream.FrameRateDenominator = 1001;
109 | break;
110 | case 8: // 60
111 | stream.FrameRateEnumerator = 60000;
112 | stream.FrameRateDenominator = 1000;
113 | break;
114 | default: // Reserved
115 | stream.FrameRateEnumerator = 0;
116 | stream.FrameRateDenominator = 0;
117 | break;
118 | }
119 | break;
120 |
121 | case 2:
122 | break;
123 |
124 | case 1:
125 | break;
126 | #endif
127 |
128 | case 0:
129 | #if DEBUG
130 | stream.BitRate = (((parse & 0xFFFFC0) >> 6) * 200);
131 | #endif
132 | stream.IsVBR = true;
133 | stream.IsInitialized = true;
134 | break;
135 | }
136 | }
137 | else if (pictureParse > 0)
138 | {
139 | --pictureParse;
140 | if (pictureParse != 0) continue;
141 | tag = ((parse & 0x38) >> 3) switch
142 | {
143 | 1 => "I",
144 | 2 => "P",
145 | 3 => "B",
146 | _ => tag
147 | };
148 | if (stream.IsInitialized) return;
149 | }
150 | else if (parse == 0x000001B5)
151 | {
152 | extensionParse = 1;
153 | }
154 | else if (extensionParse > 0)
155 | {
156 | --extensionParse;
157 | if (extensionParse != 0) continue;
158 |
159 | if ((parse & 0xF0) == 0x10)
160 | {
161 | sequenceExtensionParse = 1;
162 | }
163 | }
164 | else if (sequenceExtensionParse > 0)
165 | {
166 | --sequenceExtensionParse;
167 | #if DEBUG
168 | if (sequenceExtensionParse != 0) continue;
169 |
170 | var sequenceExtension = ((uint)((parse & 0x8) >> 3));
171 | stream.IsInterlaced = sequenceExtension == 0;
172 | #endif
173 | }
174 | }
175 | }
176 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecMVC.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 | // TODO: Do something more interesting here...
22 |
23 | public abstract class TSCodecMVC
24 | {
25 | public static void Scan(TSVideoStream stream, TSStreamBuffer buffer, ref string tag)
26 | {
27 | stream.IsVBR = true;
28 | stream.IsInitialized = true;
29 | }
30 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecPGS.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecPGS
23 | {
24 |
25 | public struct Frame
26 | {
27 | public bool Started;
28 | public bool Forced;
29 | public bool Finished;
30 | }
31 |
32 | public static void Scan(TSGraphicsStream stream, TSStreamBuffer buffer, ref string tag)
33 | {
34 | var segmentType = buffer.ReadByte(false);
35 |
36 | switch (segmentType)
37 | {
38 | case 0x15: // ODS: Object Definition Segment
39 | tag = ReadODS(stream, buffer);
40 | break;
41 | case 0x16: // PCS: Presentation Composition Segment
42 | ReadPCS(stream, buffer);
43 | break;
44 | case 0x80:
45 | if (!stream.LastFrame.Finished)
46 | stream.LastFrame.Finished = true;
47 | break;
48 | default:
49 | break;
50 | }
51 | stream.IsVBR = true;
52 | }
53 |
54 | private static string ReadODS(TSGraphicsStream stream, TSStreamBuffer buffer)
55 | {
56 | var tag = string.Empty;
57 | int segmentSize = buffer.ReadBits2(16, false);
58 | int objectID = buffer.ReadBits2(16, false); // object ID
59 |
60 | if (stream.LastFrame.Finished) return tag;
61 |
62 | if (stream.LastFrame.Forced)
63 | {
64 | stream.ForcedCaptions++;
65 | tag = "F";
66 | }
67 | else
68 | {
69 | stream.Captions++;
70 | tag = "N";
71 | }
72 |
73 | return tag;
74 | }
75 |
76 | private static void ReadPCS(TSGraphicsStream stream, TSStreamBuffer buffer)
77 | {
78 | int segmentSize = buffer.ReadBits2(16, false);
79 | if (!stream.IsInitialized)
80 | {
81 | stream.Width = buffer.ReadBits2(16, false);
82 | stream.Height = buffer.ReadBits2(16, false);
83 | stream.IsInitialized = true;
84 | }
85 | else
86 | {
87 | buffer.ReadBits2(16, false);
88 | buffer.ReadBits2(16, false);
89 | }
90 |
91 | buffer.ReadByte();
92 | int compositionNumber = buffer.ReadBits2(16, false);
93 | int compositionState = buffer.ReadByte(false);
94 | buffer.ReadBits2(16, false);
95 | int numCompositionObjects = buffer.ReadByte(false);
96 |
97 | for (var i = 0; i < numCompositionObjects; i++)
98 | {
99 | int objectID = buffer.ReadBits2(16, false); // object ID
100 | buffer.ReadByte(false); // Window ID
101 | var forced = buffer.ReadByte(false); // Object Cropped Flag
102 | buffer.ReadBits2(16, false); // Object Horizontal Position
103 | buffer.ReadBits2(16, false); // Object Vertical Position
104 | buffer.ReadBits2(16, false); // Object Cropping Horizontal Position
105 | buffer.ReadBits2(16, false); // Object Cropping Vertical Position
106 | buffer.ReadBits2(16, false); // Object Cropping Width
107 | buffer.ReadBits2(16, false); // Object Cropping Height Position
108 |
109 | stream.LastFrame = new Frame { Started = true, Forced = (forced & 0x40) == 0x40, Finished = false };
110 |
111 | if (!stream.CaptionIDs.ContainsKey(compositionNumber))
112 | {
113 | stream.CaptionIDs[compositionNumber] = stream.LastFrame;
114 | }
115 | }
116 | }
117 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecTrueHD.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 |
22 | namespace BDCommon;
23 |
24 | public abstract class TSCodecTrueHD
25 | {
26 | public static void Scan(TSAudioStream stream, TSStreamBuffer buffer, ref string tag)
27 | {
28 | if (stream.IsInitialized &&
29 | stream.CoreStream is { IsInitialized: true }) return;
30 |
31 | var syncFound = false;
32 | uint sync = 0;
33 | for (var i = 0; i < buffer.Length; i++)
34 | {
35 | sync = (sync << 8) + buffer.ReadByte();
36 | if (sync != 0xF8726FBA) continue;
37 |
38 | syncFound = true;
39 | break;
40 | }
41 |
42 | if (!syncFound)
43 | {
44 | tag = "CORE";
45 | stream.CoreStream ??= new TSAudioStream { StreamType = TSStreamType.AC3_AUDIO };
46 |
47 | if (stream.CoreStream.IsInitialized) return;
48 |
49 | buffer.BeginRead();
50 | TSCodecAC3.Scan(stream.CoreStream, buffer, ref tag);
51 | return;
52 | }
53 |
54 | tag = "HD";
55 | int ratebits = buffer.ReadBits2(4);
56 | if (ratebits != 0xF)
57 | {
58 | stream.SampleRate = ((ratebits & 8) > 0 ? 44100 : 48000) << (ratebits & 7);
59 | }
60 | buffer.BSSkipBits(15);
61 |
62 | stream.ChannelCount = 0;
63 | stream.LFE = 0;
64 | if (buffer.ReadBool())
65 | {
66 | stream.LFE += 1;
67 | }
68 | if (buffer.ReadBool())
69 | {
70 | stream.ChannelCount += 1;
71 | }
72 | if (buffer.ReadBool())
73 | {
74 | stream.ChannelCount += 2;
75 | }
76 | if (buffer.ReadBool())
77 | {
78 | stream.ChannelCount += 2;
79 | }
80 | if (buffer.ReadBool())
81 | {
82 | stream.ChannelCount += 1;
83 | }
84 | if (buffer.ReadBool())
85 | {
86 | stream.ChannelCount += 1;
87 | }
88 | if (buffer.ReadBool())
89 | {
90 | stream.ChannelCount += 2;
91 | }
92 | if (buffer.ReadBool())
93 | {
94 | stream.ChannelCount += 2;
95 | }
96 | if (buffer.ReadBool())
97 | {
98 | stream.ChannelCount += 2;
99 | }
100 | if (buffer.ReadBool())
101 | {
102 | stream.ChannelCount += 2;
103 | }
104 | if (buffer.ReadBool())
105 | {
106 | stream.LFE += 1;
107 | }
108 | if (buffer.ReadBool())
109 | {
110 | stream.ChannelCount += 1;
111 | }
112 | if (buffer.ReadBool())
113 | {
114 | stream.ChannelCount += 2;
115 | }
116 |
117 | buffer.BSSkipBits(49);
118 |
119 | var peakBitrate = buffer.ReadBits4(15);
120 | peakBitrate = (uint)(peakBitrate * stream.SampleRate >> 4);
121 |
122 | var peakBitdepth = (double)peakBitrate / (stream.ChannelCount + stream.LFE) / stream.SampleRate;
123 |
124 | stream.BitDepth = peakBitdepth > 14 ? 24 : 16;
125 |
126 | buffer.BSSkipBits(79);
127 |
128 | var hasExtensions = buffer.ReadBool();
129 | var numExtensions = buffer.ReadBits2(4) * 2 + 1;
130 | var hasContent = Convert.ToBoolean(buffer.ReadBits4(4));
131 |
132 | if (hasExtensions)
133 | {
134 | for (var idx = 0; idx < numExtensions; ++idx)
135 | {
136 | if (Convert.ToBoolean(buffer.ReadBits2(8)))
137 | hasContent = true;
138 | }
139 |
140 | if (hasContent)
141 | stream.HasExtensions = true;
142 | }
143 |
144 | #if DEBUG
145 | System.Diagnostics.Debug.WriteLine($"{stream.PID}\t{peakBitrate}\t{peakBitdepth:F2}");
146 | #endif
147 | /*
148 | // TODO: Get THD dialnorm from metadata
149 | if (stream.CoreStream != null)
150 | {
151 | TSAudioStream coreStream = (TSAudioStream)stream.CoreStream;
152 | if (coreStream.DialNorm != 0)
153 | {
154 | stream.DialNorm = coreStream.DialNorm;
155 | }
156 | }
157 | */
158 |
159 | stream.IsVBR = true;
160 | if (stream.CoreStream is { IsInitialized: true })
161 | stream.IsInitialized = true;
162 | }
163 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSCodecVC1.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | namespace BDCommon;
21 |
22 | public abstract class TSCodecVC1
23 | {
24 | public static void Scan(TSVideoStream stream, TSStreamBuffer buffer, ref string tag)
25 | {
26 | var parse = 0;
27 | byte frameHeaderParse = 0;
28 | byte sequenceHeaderParse = 0;
29 | var isInterlaced = false;
30 |
31 | for (var i = 0; i < buffer.Length; i++)
32 | {
33 | parse = (parse << 8) + buffer.ReadByte();
34 |
35 | if (parse == 0x0000010D)
36 | {
37 | frameHeaderParse = 4;
38 | }
39 | else if (frameHeaderParse > 0)
40 | {
41 | --frameHeaderParse;
42 |
43 | if (frameHeaderParse != 0) continue;
44 |
45 | uint pictureType;
46 | if (isInterlaced)
47 | {
48 | if ((parse & 0x80000000) == 0)
49 | {
50 | pictureType = (uint)((parse & 0x78000000) >> 13);
51 | }
52 | else
53 | {
54 | pictureType = (uint)((parse & 0x3c000000) >> 12);
55 | }
56 | }
57 | else
58 | {
59 | pictureType =
60 | (uint)((parse & 0xf0000000) >> 14);
61 | }
62 |
63 | if ((pictureType & 0x20000) == 0)
64 | {
65 | tag = "P";
66 | }
67 | else if ((pictureType & 0x10000) == 0)
68 | {
69 | tag = "B";
70 | }
71 | else if ((pictureType & 0x8000) == 0)
72 | {
73 | tag = "I";
74 | }
75 | else if ((pictureType & 0x4000) == 0)
76 | {
77 | tag = "BI";
78 | }
79 | else
80 | {
81 | tag = null;
82 | }
83 | if (stream.IsInitialized) return;
84 | }
85 | else if (parse == 0x0000010F)
86 | {
87 | sequenceHeaderParse = 6;
88 | }
89 | else if (sequenceHeaderParse > 0)
90 | {
91 | --sequenceHeaderParse;
92 | switch (sequenceHeaderParse)
93 | {
94 | case 5:
95 | var profileLevel = (parse & 0x38) >> 3;
96 | stream.EncodingProfile = (parse & 0xC0) >> 6 == 3
97 | ? $"Advanced Profile {profileLevel}"
98 | : $"Main Profile {profileLevel}";
99 | break;
100 |
101 | case 0:
102 | isInterlaced = (parse & 0x40) >> 6 > 0;
103 | break;
104 | }
105 | stream.IsVBR = true;
106 | stream.IsInitialized = true;
107 | }
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSInterleavedFile.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | // TODO: Do more interesting things here...
21 |
22 | using BDCommon.IO;
23 |
24 | namespace BDCommon;
25 |
26 | public class TSInterleavedFile
27 | {
28 | public IFileInfo FileInfo;
29 | public string Name;
30 |
31 | public TSInterleavedFile(IFileInfo fileInfo)
32 | {
33 | FileInfo = fileInfo;
34 | Name = fileInfo.Name.ToUpper();
35 | }
36 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSStreamBuffer.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 | using System.Collections;
22 | using System.Collections.Specialized;
23 | using System.IO;
24 |
25 | namespace BDCommon;
26 |
27 | public class TSStreamBuffer
28 | {
29 | private readonly MemoryStream _stream;
30 | private int _skipBits;
31 | private int _skippedBytes;
32 | private readonly byte[] _buffer;
33 | private int _bufferLength;
34 | public int TransferLength;
35 |
36 | public TSStreamBuffer()
37 | {
38 | _buffer = new byte[5242880];
39 | _stream = new MemoryStream(_buffer);
40 | }
41 |
42 | public long Length => _bufferLength;
43 |
44 | public long Position => _stream.Position;
45 |
46 | public void Add(byte[] buffer, int offset, int length)
47 | {
48 | TransferLength += length;
49 |
50 | if (_bufferLength + length >= _buffer.Length)
51 | {
52 | length = _buffer.Length - _bufferLength;
53 | }
54 |
55 | if (length <= 0) return;
56 |
57 | Array.Copy(buffer, offset, _buffer, _bufferLength, length);
58 | _bufferLength += length;
59 | }
60 |
61 | public void Seek(long offset, SeekOrigin loc)
62 | {
63 | _stream.Seek(offset, loc);
64 | }
65 |
66 | public void Reset()
67 | {
68 | _bufferLength = 0;
69 | TransferLength = 0;
70 | }
71 |
72 | public void BeginRead()
73 | {
74 | _skipBits = 0;
75 | _skippedBytes = 0;
76 | _stream.Seek(0, SeekOrigin.Begin);
77 | }
78 |
79 | public void EndRead()
80 | {
81 | }
82 |
83 | public byte[] ReadBytes(int bytes)
84 | {
85 | if (_stream.Position + bytes >= _bufferLength)
86 | {
87 | return null;
88 | }
89 |
90 | var value = new byte[bytes];
91 | _stream.Read(value, 0, bytes);
92 | return value;
93 | }
94 |
95 | public byte ReadByte(bool skipH26XEmulationByte)
96 | {
97 | var tempByte = (byte)_stream.ReadByte();
98 | var tempPosition = _stream.Position;
99 |
100 | if (!skipH26XEmulationByte || tempByte != 0x03) return tempByte;
101 |
102 | _stream.Seek(-3, SeekOrigin.Current);
103 | if (_stream.ReadByte() == 0x00 && _stream.ReadByte() == 0x00)
104 | {
105 | _stream.Seek(1, SeekOrigin.Current);
106 | tempByte = (byte)_stream.ReadByte();
107 | _skippedBytes++;
108 | }
109 | else
110 | {
111 | _stream.Seek(tempPosition, SeekOrigin.Begin);
112 | }
113 | return tempByte;
114 | }
115 |
116 | public byte ReadByte()
117 | {
118 | return ReadByte(false);
119 | }
120 |
121 |
122 | public bool ReadBool(bool skipH26XEmulationByte)
123 | {
124 | var pos = _stream.Position;
125 | _skippedBytes = 0;
126 | if (pos == _bufferLength) return false;
127 |
128 | var data = ReadByte(skipH26XEmulationByte);
129 | var vector = new BitVector32(data);
130 |
131 | var value = vector[1 << 8 - _skipBits - 1];
132 |
133 | _skipBits += 1;
134 | _stream.Seek(pos + (_skipBits >> 3) + _skippedBytes, SeekOrigin.Begin);
135 | _skipBits %= 8;
136 |
137 | return value;
138 | }
139 |
140 | public bool ReadBool()
141 | {
142 | return ReadBool(false);
143 | }
144 |
145 | public ushort ReadBits2(int bits, bool skipH26XEmulationByte)
146 | {
147 | var pos = _stream.Position;
148 | _skippedBytes = 0;
149 |
150 | var shift = 8;
151 | var data = 0;
152 | for (var i = 0; i < 2; i++)
153 | {
154 | if (pos + i >= _bufferLength) break;
155 | data += ReadByte(skipH26XEmulationByte) << shift;
156 | shift -= 8;
157 | }
158 | var vector = new BitVector32(data);
159 |
160 | ushort value = 0;
161 | for (var i = _skipBits; i < _skipBits + bits; i++)
162 | {
163 | value <<= 1;
164 | value += (ushort)(vector[1 << 16 - i - 1] ? 1 : 0);
165 | }
166 | _skipBits += bits;
167 | _stream.Seek(pos + (_skipBits >> 3) + _skippedBytes, SeekOrigin.Begin);
168 | _skipBits %= 8;
169 |
170 | return value;
171 | }
172 |
173 | public ushort ReadBits2(int bits)
174 | {
175 | return ReadBits2(bits, false);
176 | }
177 |
178 | public uint ReadBits4(int bits, bool skipH26XEmulationByte)
179 | {
180 | var pos = _stream.Position;
181 | _skippedBytes = 0;
182 |
183 | var shift = 24;
184 | var data = 0;
185 | for (var i = 0; i < 4; i++)
186 | {
187 | if (pos + i >= _bufferLength) break;
188 | data += ReadByte(skipH26XEmulationByte) << shift;
189 | shift -= 8;
190 | }
191 | var vector = new BitVector32(data);
192 |
193 | uint value = 0;
194 | for (var i = _skipBits; i < _skipBits + bits; i++)
195 | {
196 | value <<= 1;
197 | value += (uint)(vector[1 << 32 - i - 1] ? 1 : 0);
198 | }
199 | _skipBits += bits;
200 | _stream.Seek(pos + (_skipBits >> 3) + _skippedBytes, SeekOrigin.Begin);
201 | _skipBits %= 8;
202 |
203 | return value;
204 | }
205 |
206 | public uint ReadBits4(int bits)
207 | {
208 | return ReadBits4(bits, false);
209 | }
210 |
211 | public ulong ReadBits8(int bits, bool skipH26XEmulationByte)
212 | {
213 | var pos = _stream.Position;
214 | _skippedBytes = 0;
215 |
216 | var shift = 24;
217 | var data = 0;
218 | for (var i = 0; i < 4; i++)
219 | {
220 | if (pos + i >= _bufferLength) break;
221 | data += ReadByte(skipH26XEmulationByte) << shift;
222 | shift -= 8;
223 | }
224 |
225 | shift = 24;
226 | var data2 = 0;
227 | for (var i = 0; i < 4; i++)
228 | {
229 | if (pos + i >= _bufferLength) break;
230 | data2 += ReadByte(skipH26XEmulationByte) << shift;
231 | shift -= 8;
232 | }
233 | var vector = new BitArray(new[] { data2, data });
234 |
235 |
236 | ulong value = 0;
237 | for (var i = _skipBits; i < _skipBits + bits; i++)
238 | {
239 | value <<= 1;
240 | value += (ulong)(vector[64 - i - 1] ? 1 : 0);
241 | }
242 |
243 | _skipBits += bits;
244 | _stream.Seek(pos + (_skipBits >> 3) + _skippedBytes, SeekOrigin.Begin);
245 | _skipBits %= 8;
246 |
247 | return value;
248 | }
249 |
250 | public ulong ReadBits8(int bits)
251 | {
252 | return ReadBits8(bits, false);
253 | }
254 |
255 | public void BSSkipBits(int bits, bool skipH26XEmulationByte)
256 | {
257 | var count = bits / 16 + (bits % 16 > 0 ? 1 : 0);
258 | var bitsRead = 0;
259 | for (var i = 0; i < count; i++)
260 | {
261 | var bitsToRead = bits - bitsRead;
262 | bitsToRead = bitsToRead > 16 ? 16 : bitsToRead;
263 | ReadBits2(bitsToRead, skipH26XEmulationByte);
264 | bitsRead += bitsToRead;
265 | }
266 | }
267 |
268 | public void BSSkipBits(int bits)
269 | {
270 | BSSkipBits(bits, false);
271 | }
272 |
273 | public void BSSkipNextByte()
274 | {
275 | if (_skipBits > 0)
276 | BSSkipBits(8 - _skipBits);
277 | }
278 |
279 | public void BSResetBits()
280 | {
281 | _skipBits = 0;
282 | }
283 |
284 | public void BSSkipBytes(int bytes, bool skipH26XEmulationByte)
285 | {
286 | if (bytes > 0)
287 | {
288 | for (var i = 0; i < bytes; i++)
289 | ReadByte(skipH26XEmulationByte);
290 | }
291 | else
292 | {
293 | var pos = _stream.Position;
294 | _stream.Seek(pos + (_skipBits >> 3) + bytes, SeekOrigin.Begin);
295 | }
296 | }
297 |
298 | public void BSSkipBytes(int bytes)
299 | {
300 | BSSkipBytes(bytes, false);
301 | }
302 |
303 | public uint ReadExp(bool skipH26XEmulationByte)
304 | {
305 | byte leadingZeroes = 0;
306 | while (DataBitStreamRemain() > 0 && !ReadBool(skipH26XEmulationByte))
307 | leadingZeroes++;
308 |
309 | var infoD = Math.Pow(2, leadingZeroes);
310 | var result = (uint)infoD - 1 + ReadBits4(leadingZeroes, skipH26XEmulationByte);
311 |
312 | return result;
313 | }
314 |
315 | public uint ReadExp()
316 | {
317 | return ReadExp(false);
318 | }
319 |
320 | public void SkipExp(bool skipH26XEmulationByte)
321 | {
322 | byte leadingZeroes = 0;
323 | while (DataBitStreamRemain() > 0 && !ReadBool(skipH26XEmulationByte))
324 | leadingZeroes++;
325 |
326 | BSSkipBits(leadingZeroes, skipH26XEmulationByte);
327 | }
328 |
329 | public void SkipExp()
330 | {
331 | SkipExp(false);
332 | }
333 |
334 | public void SkipExpMulti(int num, bool skipH26XEmulationByte)
335 | {
336 | for (var i = 0; i < num; i++)
337 | {
338 | SkipExp(skipH26XEmulationByte);
339 | }
340 | }
341 |
342 | public void SkipExpMulti(int num)
343 | {
344 | SkipExpMulti(num, false);
345 | }
346 |
347 | public long DataBitStreamRemain()
348 | {
349 | var remain = (_bufferLength - _stream.Position) * 8 - _skipBits;
350 | return remain;
351 | }
352 |
353 | public long DataBitStreamRemainBytes()
354 | {
355 | return _bufferLength - _stream.Position;
356 | }
357 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSStreamClip.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using System;
21 | using System.Collections.Generic;
22 |
23 | namespace BDCommon;
24 |
25 | public class TSStreamClip
26 | {
27 | private readonly BDInfoSettings _settings;
28 | public int AngleIndex = 0;
29 | public string Name;
30 | public double TimeIn;
31 | public double TimeOut;
32 | public double RelativeTimeIn;
33 | public double RelativeTimeOut;
34 | public double Length;
35 | public double RelativeLength;
36 |
37 | public ulong FileSize;
38 | public ulong InterleavedFileSize;
39 | public ulong PayloadBytes = 0;
40 | public ulong PacketCount = 0;
41 | public double PacketSeconds = 0;
42 |
43 | public List Chapters = new();
44 |
45 | public TSStreamFile StreamFile;
46 | public TSStreamClipFile StreamClipFile;
47 |
48 | public TSStreamClip(TSStreamFile streamFile, TSStreamClipFile streamClipFile, BDInfoSettings settings)
49 | {
50 | _settings = settings;
51 | if (streamFile != null)
52 | {
53 | Name = streamFile.Name;
54 | StreamFile = streamFile;
55 |
56 | if (StreamFile.FileInfo != null)
57 | FileSize = (ulong)StreamFile.FileInfo.Length;
58 |
59 | if (StreamFile.InterleavedFile is { FileInfo: { } })
60 | InterleavedFileSize = (ulong)StreamFile.InterleavedFile.FileInfo.Length;
61 | }
62 | StreamClipFile = streamClipFile;
63 | }
64 |
65 | public string DisplayName
66 | {
67 | get
68 | {
69 | if (StreamFile is { InterleavedFile: { } } && _settings.EnableSSIF)
70 | {
71 | return StreamFile.InterleavedFile.Name;
72 | }
73 | return Name;
74 | }
75 | }
76 |
77 | public ulong PacketSize => PacketCount * 192;
78 |
79 | public ulong PacketBitRate
80 | {
81 | get
82 | {
83 | if (PacketSeconds > 0)
84 | {
85 | return (ulong)Math.Round(PacketSize * 8.0 / PacketSeconds);
86 | }
87 | return 0;
88 | }
89 | }
90 |
91 | public bool IsCompatible(TSStreamClip clip)
92 | {
93 | foreach (var stream1 in StreamFile.Streams.Values)
94 | {
95 | if (!clip.StreamFile.Streams.ContainsKey(stream1.PID)) continue;
96 |
97 | var stream2 = clip.StreamFile.Streams[stream1.PID];
98 | if (stream1.StreamType != stream2.StreamType)
99 | {
100 | return false;
101 | }
102 | }
103 | return true;
104 | }
105 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDCommon/rom/TSStreamClipFile.cs:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // BDInfo - Blu-ray Video and Audio Analysis Tool
3 | // Copyright © 2010 Cinema Squid
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) any later version.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library; if not, write to the Free Software
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 | //=============================================================================
19 |
20 | using BDCommon.IO;
21 | using System;
22 | using System.Collections.Generic;
23 | using System.Diagnostics;
24 | using System.IO;
25 | using System.Text;
26 |
27 | namespace BDCommon;
28 |
29 | public class TSStreamClipFile
30 | {
31 | public IFileInfo FileInfo;
32 | public string FileType;
33 | public bool IsValid;
34 | public string Name;
35 |
36 | public Dictionary Streams = new();
37 |
38 | public TSStreamClipFile(IFileInfo fileInfo)
39 | {
40 | FileInfo = fileInfo;
41 | Name = fileInfo.Name.ToUpper();
42 | }
43 |
44 | public void Scan()
45 | {
46 | Stream fileStream = null;
47 | BinaryReader fileReader = null;
48 | ulong streamLength = 0;
49 |
50 | try
51 | {
52 | #if DEBUG
53 | Debug.WriteLine($"Scanning {Name}...");
54 | #endif
55 | Streams.Clear();
56 |
57 | if (FileInfo != null)
58 | {
59 | fileStream = FileInfo.OpenRead();
60 | if (fileStream != null)
61 | {
62 | fileReader = new BinaryReader(fileStream);
63 | streamLength = (ulong)fileStream.Length;
64 | }
65 | }
66 |
67 | var data = new byte[streamLength];
68 | fileReader?.Read(data, 0, data.Length);
69 |
70 | var fileType = new byte[8];
71 | Array.Copy(data, 0, fileType, 0, fileType.Length);
72 |
73 | FileType = Encoding.ASCII.GetString(fileType);
74 | if (FileType != "HDMV0100" &&
75 | FileType != "HDMV0200" &&
76 | FileType != "HDMV0300")
77 | {
78 | throw new Exception($"Clip info file {FileInfo?.Name} has an unknown file type {FileType}.");
79 | }
80 | #if DEBUG
81 | Debug.WriteLine($"\tFileType: {FileType}");
82 | #endif
83 | var clipIndex = (data[12] << 24) +
84 | (data[13] << 16) +
85 | (data[14] << 8) +
86 | data[15];
87 |
88 | var clipLength = (data[clipIndex] << 24) +
89 | (data[clipIndex + 1] << 16) +
90 | (data[clipIndex + 2] << 8) +
91 | data[clipIndex + 3];
92 |
93 | var clipData = new byte[clipLength];
94 | Array.Copy(data, clipIndex + 4, clipData, 0, clipData.Length);
95 |
96 | int streamCount = clipData[8];
97 | #if DEBUG
98 | Debug.WriteLine($"\tStreamCount: {streamCount}");
99 | #endif
100 | var streamOffset = 10;
101 | for (var streamIndex = 0; streamIndex < streamCount; streamIndex++)
102 | {
103 | TSStream stream = null;
104 |
105 | var pid = (ushort)((clipData[streamOffset] << 8) +
106 | clipData[streamOffset + 1]);
107 |
108 | streamOffset += 2;
109 |
110 | var streamType = (TSStreamType)clipData[streamOffset + 1];
111 | switch (streamType)
112 | {
113 | case TSStreamType.MVC_VIDEO:
114 | // TODO
115 | break;
116 |
117 | case TSStreamType.HEVC_VIDEO:
118 | case TSStreamType.AVC_VIDEO:
119 | case TSStreamType.MPEG1_VIDEO:
120 | case TSStreamType.MPEG2_VIDEO:
121 | case TSStreamType.VC1_VIDEO:
122 | {
123 | var videoFormat = (TSVideoFormat)(clipData[streamOffset + 2] >> 4);
124 | var frameRate = (TSFrameRate)(clipData[streamOffset + 2] & 0xF);
125 | var aspectRatio = (TSAspectRatio)(clipData[streamOffset + 3] >> 4);
126 |
127 | stream = new TSVideoStream
128 | {
129 | VideoFormat = videoFormat,
130 | AspectRatio = aspectRatio,
131 | FrameRate = frameRate,
132 | };
133 | #if DEBUG
134 | Debug.WriteLine($"\t{pid} {streamType} {videoFormat} {frameRate} {aspectRatio}");
135 | #endif
136 | }
137 | break;
138 |
139 | case TSStreamType.AC3_AUDIO:
140 | case TSStreamType.AC3_PLUS_AUDIO:
141 | case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
142 | case TSStreamType.AC3_TRUE_HD_AUDIO:
143 | case TSStreamType.DTS_AUDIO:
144 | case TSStreamType.DTS_HD_AUDIO:
145 | case TSStreamType.DTS_HD_MASTER_AUDIO:
146 | case TSStreamType.DTS_HD_SECONDARY_AUDIO:
147 | case TSStreamType.LPCM_AUDIO:
148 | case TSStreamType.MPEG1_AUDIO:
149 | case TSStreamType.MPEG2_AUDIO:
150 | case TSStreamType.MPEG2_AAC_AUDIO:
151 | case TSStreamType.MPEG4_AAC_AUDIO:
152 | {
153 | var languageBytes = new byte[3];
154 | Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length);
155 |
156 | var languageCode = Encoding.ASCII.GetString(languageBytes);
157 | var channelLayout = (TSChannelLayout)(clipData[streamOffset + 2] >> 4);
158 | var sampleRate = (TSSampleRate)(clipData[streamOffset + 2] & 0xF);
159 |
160 | stream = new TSAudioStream
161 | {
162 | LanguageCode = languageCode,
163 | ChannelLayout = channelLayout,
164 | SampleRate = TSAudioStream.ConvertSampleRate(sampleRate)
165 | };
166 | #if DEBUG
167 | Debug.WriteLine($"\t{pid} {streamType} {languageCode} {channelLayout} {sampleRate}");
168 | #endif
169 | }
170 | break;
171 |
172 | case TSStreamType.INTERACTIVE_GRAPHICS:
173 | case TSStreamType.PRESENTATION_GRAPHICS:
174 | {
175 | var languageBytes = new byte[3];
176 | Array.Copy(clipData, streamOffset + 2, languageBytes, 0, languageBytes.Length);
177 |
178 | var languageCode = Encoding.ASCII.GetString(languageBytes);
179 |
180 | stream = new TSGraphicsStream
181 | {
182 | LanguageCode = languageCode
183 | };
184 | #if DEBUG
185 | Debug.WriteLine($"\t{pid} {streamType} {languageCode}");
186 | #endif
187 | }
188 | break;
189 |
190 | case TSStreamType.SUBTITLE:
191 | {
192 | var languageBytes = new byte[3];
193 | Array.Copy(clipData, streamOffset + 3, languageBytes, 0, languageBytes.Length);
194 | var languageCode = Encoding.ASCII.GetString(languageBytes);
195 | #if DEBUG
196 | Debug.WriteLine($"\t{pid} {streamType} {languageCode}");
197 | #endif
198 | stream = new TSTextStream
199 | {
200 | LanguageCode = languageCode
201 | };
202 | }
203 | break;
204 | }
205 |
206 | if (stream != null)
207 | {
208 | stream.PID = pid;
209 | stream.StreamType = streamType;
210 | Streams.Add(pid, stream);
211 | }
212 |
213 | streamOffset += clipData[streamOffset] + 1;
214 | }
215 | IsValid = true;
216 | }
217 | finally
218 | {
219 | fileReader?.Close();
220 | fileStream?.Close();
221 | }
222 | }
223 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/BDExtractor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | win-x64;linux-x64
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/CmdOptions.cs:
--------------------------------------------------------------------------------
1 | using CommandLine;
2 |
3 | namespace BDExtractor
4 | {
5 | public sealed class CmdOptions
6 | {
7 | [Option('p', "path", Required = true, HelpText = "The path to iso file")]
8 | public string Path { get; set; }
9 |
10 | [Option('o', "output", Required = false, HelpText = "The output folder. If not set then will extract in same folder as *.iso file")]
11 | public string Output { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/FileCopier.cs:
--------------------------------------------------------------------------------
1 | using DiscUtils;
2 | using System;
3 | using System.IO;
4 |
5 | namespace BDExtractor
6 | {
7 | public delegate void ProgressChangeDelegate(double percentage);
8 | public delegate void Completedelegate();
9 |
10 | internal sealed class FileCopier
11 | {
12 | private readonly DiscFileInfo _sourceFilePath;
13 | private readonly string _destFilePath;
14 | private readonly int _buffer;
15 | private const int DEFAULT_BUFFER = 1024 * 1024;
16 |
17 | public FileCopier(DiscFileInfo file, string destFile, int bufferBytes = DEFAULT_BUFFER)
18 | {
19 | if (string.IsNullOrWhiteSpace(destFile))
20 | {
21 | throw new ArgumentException($"'{nameof(destFile)}' cannot be null or whitespace.", nameof(destFile));
22 | }
23 |
24 | _sourceFilePath = file ?? throw new ArgumentNullException(nameof(file));
25 | _destFilePath = destFile;
26 | _buffer = bufferBytes;
27 |
28 | OnProgressChanged += delegate { };
29 | OnComplete += delegate { };
30 | }
31 |
32 | public event ProgressChangeDelegate OnProgressChanged;
33 | public event Completedelegate OnComplete;
34 |
35 | public void Copy()
36 | {
37 | byte[] buffer = new byte[_buffer];
38 | bool cancelFlag = false;
39 |
40 | using (Stream source = _sourceFilePath.OpenRead())
41 | {
42 | long fileLength = source.Length;
43 | using (FileStream dest = new FileStream(_destFilePath, FileMode.CreateNew, FileAccess.Write))
44 | {
45 | long totalBytes = 0;
46 | int currentBlockSize = 0;
47 |
48 | while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
49 | {
50 | totalBytes += currentBlockSize;
51 | double persentage = (double)totalBytes * 100.0 / fileLength;
52 |
53 | dest.Write(buffer, 0, currentBlockSize);
54 |
55 | cancelFlag = false;
56 | OnProgressChanged(persentage);
57 |
58 | if (cancelFlag == true)
59 | {
60 | break;
61 | }
62 | }
63 | }
64 | }
65 |
66 | if (cancelFlag)
67 | {
68 | try
69 | {
70 | File.Delete(_destFilePath);
71 | }
72 | catch { }
73 | }
74 |
75 | OnComplete();
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/FolderUtility.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace BDExtractor
5 | {
6 | internal static class FolderUtility
7 | {
8 | public static string Combine(string path1, params string[] paths)
9 | {
10 | string path = path1;
11 |
12 | foreach (var path2 in paths)
13 | {
14 | path = Path.Combine(path, path2);
15 | }
16 |
17 | if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
18 | {
19 | path = path.Replace('\\', '/');
20 | }
21 |
22 | return path;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/Program.cs:
--------------------------------------------------------------------------------
1 | using CommandLine;
2 | using DiscUtils;
3 | using DiscUtils.Udf;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 |
8 | namespace BDExtractor
9 | {
10 | class Program
11 | {
12 | private static string _log;
13 | private static string _space = new string(' ', 20);
14 |
15 | static void Main(string[] args)
16 | {
17 | Parser.Default.ParseArguments(args)
18 | .WithParsed(opts => Exec(opts))
19 | .WithNotParsed((errs) => HandleParseError(errs));
20 | }
21 |
22 | static void Exec(CmdOptions opts)
23 | {
24 | _log = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"log_{Path.GetFileName(opts.Path)}.log");
25 | var output = opts.Output;
26 | if (string.IsNullOrWhiteSpace(output))
27 | {
28 | output = Path.GetDirectoryName(opts.Path);
29 | }
30 |
31 | if (!Directory.Exists(output))
32 | {
33 | Directory.CreateDirectory(output);
34 | }
35 |
36 | try
37 | {
38 | DiscUtils.Complete.SetupHelper.SetupComplete();
39 | DiscUtils.Containers.SetupHelper.SetupContainers();
40 | DiscUtils.FileSystems.SetupHelper.SetupFileSystems();
41 | DiscUtils.Transports.SetupHelper.SetupTransports();
42 |
43 | using (FileStream isoStream = File.Open(opts.Path, FileMode.Open))
44 | {
45 | UdfReader cd = new UdfReader(isoStream);
46 | File.AppendAllText(_log, $"Exec cd root full::: {cd.Root.FullName + Environment.NewLine}");
47 | File.AppendAllText(_log, $"Exec cd root name::: {cd.Root.Name + Environment.NewLine}");
48 |
49 | var dirs = cd.Root.GetDirectories();
50 | var files = cd.Root.GetFiles();
51 |
52 | foreach (var dir in dirs)
53 | {
54 | CopyDir(dir, output);
55 | }
56 |
57 | foreach (var file in files)
58 | {
59 | File.AppendAllText(_log, $"Exec file fullname::: {file.FullName + Environment.NewLine}");
60 | File.AppendAllText(_log, $"Exec file name::: {file.Name + Environment.NewLine}");
61 |
62 | var path = FolderUtility.Combine(output, file.FullName);
63 | File.AppendAllText(_log, $"Exec file combined path::: {path + Environment.NewLine}");
64 |
65 | CopyFile(file, path);
66 | }
67 | }
68 | }
69 | catch (Exception ex)
70 | {
71 | var cl = Console.ForegroundColor;
72 |
73 | Console.ForegroundColor = ConsoleColor.Red;
74 | Console.Error.WriteLine(ex.Message);
75 |
76 | Console.ForegroundColor = cl;
77 |
78 | Environment.Exit(-1);
79 | }
80 | }
81 |
82 | static void HandleParseError(IEnumerable errs) { }
83 |
84 | static void CopyDir(DiscDirectoryInfo ddi, string outpath)
85 | {
86 | File.AppendAllText(_log, $"CopyDir dir fullname::: {ddi.FullName + Environment.NewLine}");
87 | File.AppendAllText(_log, $"CopyDir dir name::: {ddi.Name + Environment.NewLine}");
88 |
89 | string path = FolderUtility.Combine(outpath, ddi.FullName);
90 | File.AppendAllText(_log, $"CopyDir combined dir path::: {path + Environment.NewLine}");
91 | if (!Directory.Exists(path))
92 | {
93 | Console.WriteLine($"Creating directory {path}");
94 | Directory.CreateDirectory(path);
95 | }
96 |
97 | var files = ddi.GetFiles();
98 | if (files.Length > 0)
99 | {
100 | foreach (DiscFileInfo file in files)
101 | {
102 | File.AppendAllText(_log, $"CopyDir fullname::: {file.FullName + Environment.NewLine}");
103 | File.AppendAllText(_log, $"CopyDir name::: {file.Name + Environment.NewLine}");
104 |
105 | var filePath = FolderUtility.Combine(outpath, file.FullName);
106 | File.AppendAllText(_log, $"CopyDir combined file path::: {filePath + Environment.NewLine}");
107 |
108 | if (File.Exists(filePath))
109 | {
110 | File.Delete(filePath);
111 | }
112 |
113 | CopyFile(file, filePath);
114 | }
115 | }
116 |
117 | var dirs = ddi.GetDirectories();
118 | if (dirs.Length > 0)
119 | {
120 | foreach (DiscDirectoryInfo dir in dirs)
121 | {
122 | CopyDir(dir, outpath);
123 | }
124 | }
125 | }
126 |
127 | static void CopyFile(DiscFileInfo file, string destFilePath)
128 | {
129 | var fc = new FileCopier(file, destFilePath, 4096 * 1024); // 4MB
130 | Console.WriteLine($"Creating file {destFilePath} ( {SizeConverter.SizeToText(file.Length)} ) { _space }");
131 |
132 | fc.OnProgressChanged += (percentage) =>
133 | {
134 | Console.Write($"\rPercent: {percentage:0.00} %{_space}");
135 | };
136 |
137 | fc.OnComplete += () =>
138 | {
139 | Console.WriteLine();
140 | };
141 |
142 | fc.Copy();
143 |
144 | //using (FileStream fs = File.Create(filePath))
145 | //{
146 | // using (var fileStream = file.Open(FileMode.Open))
147 | // {
148 | // Console.WriteLine($"Creating file {filePath} ( {SizeConverter.SizeToText(file.Length)} ) { new string(' ', 10) }");
149 | // fileStream.CopyTo(fs);
150 | // }
151 | //}
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Release
8 | Any CPU
9 | bin\Release\netcoreapp3.1\publish\win-x64\
10 | FileSystem
11 | netcoreapp3.1
12 | win-x64
13 | true
14 | False
15 | False
16 |
17 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "BDExtractor": {
4 | "commandName": "Project",
5 | "commandLineArgs": "-p \"C:\\p\\frosty.iso\" -o \"C:\\p\\test\""
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDExtractor/SizeConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace BDExtractor
5 | {
6 | internal static class SizeConverter
7 | {
8 | public static string SizeToText(double size)
9 | {
10 | var units = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
11 | const ushort divide = 1000;
12 |
13 | int power = size > 0 ? (int)Math.Floor(Math.Log(size, divide)) : 0;
14 |
15 | return $"{Math.Round(size / Math.Pow(divide, power), 2).ToString(CultureInfo.InvariantCulture)} {units[power]}";
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo.Core.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.12.35707.178 d17.12
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BDInfo", "BDInfo\BDInfo.csproj", "{8993A1DB-DB2E-46C8-BA1E-F6C8FE8158F7}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BDExtractor", "BDExtractor\BDExtractor.csproj", "{7DB8725D-E6B1-43DF-9546-42C3AD2CA9A0}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BDCommon", "BDCommon\BDCommon.csproj", "{6D228997-CA22-42CD-A043-0A2574E09507}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BDInfoDataSubstractor", "BDInfoDataSubstractor\BDInfoDataSubstractor.csproj", "{17428421-CD53-4B16-89E2-27938EB6BA2C}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {8993A1DB-DB2E-46C8-BA1E-F6C8FE8158F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {8993A1DB-DB2E-46C8-BA1E-F6C8FE8158F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {8993A1DB-DB2E-46C8-BA1E-F6C8FE8158F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {8993A1DB-DB2E-46C8-BA1E-F6C8FE8158F7}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {7DB8725D-E6B1-43DF-9546-42C3AD2CA9A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {7DB8725D-E6B1-43DF-9546-42C3AD2CA9A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {7DB8725D-E6B1-43DF-9546-42C3AD2CA9A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {7DB8725D-E6B1-43DF-9546-42C3AD2CA9A0}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {6D228997-CA22-42CD-A043-0A2574E09507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {6D228997-CA22-42CD-A043-0A2574E09507}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {6D228997-CA22-42CD-A043-0A2574E09507}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {6D228997-CA22-42CD-A043-0A2574E09507}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {17428421-CD53-4B16-89E2-27938EB6BA2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {17428421-CD53-4B16-89E2-27938EB6BA2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {17428421-CD53-4B16-89E2-27938EB6BA2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {17428421-CD53-4B16-89E2-27938EB6BA2C}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {1E53D7A8-3B95-4BE7-ABCC-D9A86E466C97}
42 | EndGlobalSection
43 | EndGlobal
44 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo/BDInfo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | BDInfo
7 | win-x64;linux-x64
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo/BDSettings.cs:
--------------------------------------------------------------------------------
1 | using BDCommon;
2 | using System;
3 | using System.IO;
4 |
5 | namespace BDInfo
6 | {
7 | public sealed class BDSettings(CmdOptions opts) : BDInfoSettings
8 | {
9 | private readonly CmdOptions _opts = opts;
10 |
11 | public override bool GenerateStreamDiagnostics => _opts?.GenerateStreamDiagnostics ?? false;
12 |
13 | public override bool ExtendedStreamDiagnostics => _opts?.ExtendedStreamDiagnostics ?? false;
14 |
15 | public override bool EnableSSIF => _opts?.EnableSSIF ?? true;
16 |
17 | public override bool FilterLoopingPlaylists => _opts?.FilterLoopingPlaylists ?? false;
18 |
19 | public override bool FilterShortPlaylists => _opts?.FilterShortPlaylists ?? true;
20 |
21 | public override int FilterShortPlaylistsValue => _opts?.FilterShortPlaylistsValue ?? 20;
22 |
23 | public override bool KeepStreamOrder => _opts?.KeepStreamOrder ?? false;
24 |
25 | public override bool GenerateTextSummary => _opts?.GenerateTextSummary ?? true;
26 |
27 | public override string ReportFileName => string.IsNullOrWhiteSpace(_opts?.ReportFileName) ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "BDInfo_{0}.bdinfo") : _opts.ReportFileName;
28 |
29 | public override bool IncludeVersionAndNotes => _opts?.IncludeVersionAndNotes ?? false;
30 |
31 | public override bool GroupByTime => _opts?.GroupByTime ?? false;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo/CmdOptions.cs:
--------------------------------------------------------------------------------
1 | using CommandLine;
2 | using System;
3 |
4 | namespace BDInfo
5 | {
6 | [Serializable]
7 | public sealed class CmdOptions
8 | {
9 | [Option('p', "path", Required = true, HelpText = "The path to iso or bluray folder")]
10 | public string Path { get; set; }
11 |
12 | [Option('g', "generatestreamdiagnostics", Required = false, Default = null, HelpText = "Generate the stream diagnostics")]
13 | public bool? GenerateStreamDiagnostics { get; set; }
14 |
15 | [Option('e', "extendedstreamdiagnostics", Required = false, Default = null, HelpText = "Generete the extended stream diagnostics")]
16 | public bool? ExtendedStreamDiagnostics { get; set; }
17 |
18 | [Option('b', "enablessif", Required = false, Default = null, HelpText = "Enable SSIF support")]
19 | public bool? EnableSSIF { get; set; }
20 |
21 | [Option('l', "filterloopingplaylists", Required = false, Default = null, HelpText = "Filter loopig playlist")]
22 | public bool? FilterLoopingPlaylists { get; set; }
23 |
24 | [Option('y', "filtershortplaylist", Required = false, Default = null, HelpText = "Filter short playlist")]
25 | public bool? FilterShortPlaylists { get; set; }
26 |
27 | [Option('v', "filtershortplaylistvalue", Required = false, Default = 20, HelpText = "Filter number of short playlist")]
28 | public int FilterShortPlaylistsValue { get; set; }
29 |
30 | [Option('k', "keepstreamorder", Required = false, Default = null, HelpText = "Keep stream order")]
31 | public bool? KeepStreamOrder { get; set; }
32 |
33 | [Option('m', "generatetextsummary", Required = false, Default = null, HelpText = "Generate summary")]
34 | public bool? GenerateTextSummary { get; set; }
35 |
36 | [Option('o', "reportfilename", Required = false, Default = null, HelpText = "The report filename with extension. If no extension provided then will append .txt at end of filename")]
37 | public string ReportFileName { get; set; }
38 |
39 | [Option('q', "includeversionandnotes", Required = false, Default = null, HelpText = "Include version and notes inside report")]
40 | public bool? IncludeVersionAndNotes { get; set; }
41 |
42 | [Option('j', "groupbytime", Required = false, Default = null, HelpText = "Group by time")]
43 | public bool? GroupByTime { get; set; }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\
12 | linux-x64
13 | true
14 | False
15 | False
16 |
17 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "BDInfo": {
4 | "commandName": "Project",
5 | "commandLineArgs": "-p \"C:\\p\\Frosty.the.Snowman.1969.1080p.Blu-ray.AVC.TrueHD.5.1\" -b -a -l -y -k -m -z"
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfoDataSubstractor/BDInfoDataSubstractor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfoDataSubstractor/BdInfoDataModel.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Text.Json.Serialization;
3 |
4 | namespace BDInfoDataSubstractor
5 | {
6 | public sealed class BdInfoDataModel
7 | {
8 | public string DiscTitle { get; private set; } = string.Empty;
9 | public string DiscLabel { get; private set; } = string.Empty;
10 | public string DiscSize { get; private set; } = string.Empty;
11 | public long LongDiscSize => string.IsNullOrWhiteSpace(DiscSize) ? 0 : long.Parse(DiscSize.ToLower().Replace("bytes", "").Trim().Replace(",", ""));
12 | public PlaylistModel Playlist { get; private set; } = new();
13 |
14 | [JsonIgnore]
15 | public string InnerData { get; }
16 |
17 | public BdInfoDataModel(string inner)
18 | {
19 | InnerData = inner;
20 | PopulateFields(inner);
21 | }
22 |
23 | private void PopulateFields(string inner)
24 | {
25 | foreach (var line in inner.Split(Environment.NewLine))
26 | {
27 | if (string.IsNullOrWhiteSpace(line)) continue;
28 |
29 | var split = line.Split(':');
30 |
31 | if (split.Length > 1)
32 | {
33 | var key = split[0].ToLower();
34 | var value = string.Join(':', line.Split(':').Skip(1)).Trim();
35 |
36 | if (key.StartsWith("disc title"))
37 | {
38 | DiscTitle = value;
39 | }
40 | else if (key.StartsWith("disc label"))
41 | {
42 | DiscLabel = value;
43 | }
44 | else if (key.StartsWith("disc size"))
45 | {
46 | DiscSize = value;
47 | }
48 | else if (key.StartsWith("name") || (key.StartsWith("playlist") && !key.Contains("report")))
49 | {
50 | Playlist ??= new PlaylistModel();
51 | Playlist.Name = value;
52 | }
53 | else if (key.StartsWith("length"))
54 | {
55 | Playlist.Length = value;
56 | }
57 | else if (key.StartsWith("size"))
58 | {
59 | Playlist.Size = value;
60 | }
61 | else if (key.StartsWith("total bitrate"))
62 | {
63 | Playlist.TotalBitrate = value;
64 | break;
65 | }
66 | }
67 | }
68 | }
69 | }
70 |
71 | public sealed class PlaylistModel
72 | {
73 | public string Name { get; set; } = string.Empty;
74 | public string Length { get; set; } = string.Empty;
75 | public float LongLength => GetLength(Length);
76 |
77 | public string Size { get; set; } = string.Empty;
78 | public long LongSize => string.IsNullOrWhiteSpace(Size) ? 0 : long.Parse(Size.ToLower().Replace("bytes", "").Trim().Replace(",", ""));
79 |
80 | public string TotalBitrate { get; set; } = string.Empty;
81 | public long LongTotalBitrate => string.IsNullOrWhiteSpace(TotalBitrate) ? 0 : (long)(float.Parse(TotalBitrate.ToLower().Replace("mbps", "").Trim(), System.Globalization.NumberStyles.AllowDecimalPoint) * 1000);
82 |
83 | private static float GetLength(string length)
84 | {
85 | if (string.IsNullOrWhiteSpace(length) || !length.Contains(':'))
86 | {
87 | return 0.0f;
88 | }
89 |
90 | var valueData = length.Split('(')[0].Trim();
91 | var clockSplit = valueData.Split(':');
92 |
93 | return
94 | float.Parse(clockSplit[0]) * (24 * 60 * 60) +
95 | float.Parse(clockSplit[1]) * 60 +
96 | float.Parse(clockSplit[2], System.Globalization.NumberStyles.AllowDecimalPoint);
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfoDataSubstractor/DataContentManager.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace BDInfoDataSubstractor
5 | {
6 | internal static class DataContentManager
7 | {
8 | private static readonly Regex _codeRegex = new(@"\[code\](.+?)\[\/code\]", RegexOptions.Singleline);
9 | private static readonly string[] _allowedQuickSummary = ["Disc Title", "Disc Label", "Disc Size", "Protection", "Playlist", "Size", "Length", "Total Bitrate", "Video", "Audio", "Subtitle"];
10 |
11 | public static async Task ParseValidDataAsync(string inputFile, string? outputFileBdInfoContent = null, string? outputFileQuickSummary = null)
12 | {
13 | string name = Path.GetFileNameWithoutExtension(inputFile);
14 | string content = await File.ReadAllTextAsync(inputFile);
15 |
16 | var discInfosSection = ExtractDiscInfo(content);
17 | var summariesSection = ExtractSummaries(content);
18 |
19 | var filteredDiscSections = discInfosSection.Where(c => IsValidDiscInfoSection(c))
20 | .OrderByDescending(c => c.Playlist.LongTotalBitrate)
21 | .DistinctBy(c => c.Playlist.Name);
22 |
23 | var filteredSummariesSection = summariesSection.Where(c => IsValidDiscInfoSection(c))
24 | .OrderByDescending(c => c.Playlist.LongTotalBitrate)
25 | .DistinctBy(c => c.Playlist.Name);
26 |
27 | var outFile = outputFileBdInfoContent;
28 | if (string.IsNullOrWhiteSpace(outFile))
29 | {
30 | outFile = Path.Combine(Path.GetDirectoryName(inputFile)!, $"{name}.bdinfo.txt");
31 | }
32 | await File.WriteAllTextAsync(outFile, filteredDiscSections.First().InnerData);
33 |
34 | outFile = outputFileQuickSummary;
35 | if (string.IsNullOrWhiteSpace(outFile))
36 | {
37 | outFile = Path.Combine(Path.GetDirectoryName(inputFile)!, $"{name}.quicksummary.txt");
38 | }
39 | await File.WriteAllTextAsync(outFile, filteredSummariesSection.First().InnerData);
40 | }
41 |
42 | private static IEnumerable ExtractDiscInfo(string content)
43 | {
44 | var matches = _codeRegex.Matches(content);
45 |
46 | foreach (Match match in matches)
47 | {
48 | if (match.Groups[1].Value.Contains("disc info:", StringComparison.OrdinalIgnoreCase))
49 | {
50 | yield return new(match.Groups[1].Value.Trim());
51 | }
52 | }
53 | }
54 |
55 | private static bool IsValidDiscInfoSection(BdInfoDataModel model)
56 | {
57 | // get by size and length greater than 10 minute(s)
58 | return model.Playlist.LongSize < model.LongDiscSize && model.Playlist.LongLength > 10 * 60;
59 | }
60 |
61 | private static IEnumerable ExtractSummaries(string content)
62 | {
63 | List summaries = [];
64 | bool quickStart = false;
65 | StringBuilder sb = new();
66 | int indexEmptyLine = 0;
67 |
68 | foreach (var line in content.Split(Environment.NewLine))
69 | {
70 | if (string.IsNullOrWhiteSpace(line))
71 | {
72 | indexEmptyLine++;
73 | if (indexEmptyLine >= 4 && quickStart)
74 | {
75 | summaries.Add(sb.ToString());
76 | indexEmptyLine = 0;
77 | quickStart = false;
78 | }
79 |
80 | continue;
81 | }
82 |
83 | if (line.StartsWith("quick summary", StringComparison.OrdinalIgnoreCase))
84 | {
85 | quickStart = true;
86 | indexEmptyLine = 0;
87 | sb = new();
88 | continue;
89 | }
90 |
91 | if (quickStart && _allowedQuickSummary.Any(c => line.StartsWith(c)))
92 | {
93 | sb.AppendLine(line);
94 | indexEmptyLine = 0;
95 | continue;
96 | }
97 | }
98 |
99 | summaries.RemoveAll(c => string.IsNullOrWhiteSpace(c));
100 | return summaries.Select(c => new BdInfoDataModel(c));
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/BDInfo.Core/BDInfoDataSubstractor/Program.cs:
--------------------------------------------------------------------------------
1 | namespace BDInfoDataSubstractor
2 | {
3 | internal class Program
4 | {
5 | private static readonly string _errorFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "errors.log");
6 |
7 | static async Task Main(string[] args)
8 | {
9 | if (args.Length == 0)
10 | {
11 | Console.WriteLine("Tool expectes to provide text file(s) generated by bdinfo");
12 | return;
13 | }
14 |
15 | foreach (var file in args)
16 | {
17 | if (!File.Exists(file))
18 | {
19 | continue;
20 | }
21 |
22 | try
23 | {
24 | await DataContentManager.ParseValidDataAsync(file);
25 | }
26 | catch (Exception ex)
27 | {
28 | try
29 | {
30 | await File.AppendAllLinesAsync(_errorFile, [file, ex.Message, new string('=', 50)]);
31 | }
32 | catch
33 | {
34 | // kill
35 | }
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BDInfo
2 |
3 | It scans bluray disc (full hd, ultra hd and 3D) on various operating systems. The binaries provided are portable so no need to install any framework.
4 |
5 | ## Command arguments
6 |
7 | | Short argument | Long argument | Meaning | Required | Default |
8 | | --- | --- | --- | --- | --- |
9 | | _`-p`_ | _`--path`_ | The path to iso or bluray folder | x | |
10 | | _`-g`_ | _`--generatestreamdiagnostics`_ | Generate the stream diagnostics | | False |
11 | | _`-e`_ | _`--extendedstreamdiagnostics`_ | Generete the extended stream diagnostics | | False |
12 | | _`-b`_ | _`--enablessif`_ | Enable SSIF support | | False |
13 | | _`-l`_ | _`--filterloopingplaylists`_ | Filter loopig playlist | | False |
14 | | _`-y`_ | _`--filtershortplaylist`_ | Filter short playlist | | True |
15 | | _`-v`_ | _`--filtershortplaylistvalue`_ | Filter number of short playlist | | 20 |
16 | | _`-k`_ | _`--keepstreamorder`_ | Keep stream order | | False |
17 | | _`-m`_ | _`--generatetextsummary`_ | Generate summary | | True |
18 | | _`-o`_ | _`--reportfilename`_ | The report filename with extension. If no extension provided then will append .txt at end of filename | | |
19 | | _`-q`_ | _`--includeversionandnotes`_ | Include version and notes inside report | | False |
20 | | _`-j`_ | _`--groupbytime`_ | Group by time | | False |
21 |
22 |
23 | For linux, make `BDInfo` as executable (yes, that one without extension) using `chmod +x BDInfo`
24 |
25 | ## How to use
26 |
27 | ### Windows
28 | `BDInfo.exe -p PATH_TO_DISC_FOLDER -o PATH_TO_FILE.EXTENSION`
29 | `BDInfo.exe -p PATH_TO_ISO_FILE -o PATH_TO_FILE.EXTENSION`
30 |
31 | ### Linux
32 | `./BDInfo -p PATH_TO_DISC_FOLDER -o PATH_TO_FILE.EXTENSION`
33 | `./BDInfo -p PATH_TO_ISO_FILE -o PATH_TO_FILE.EXTENSION`
34 |
35 | # BDExtractor
36 |
37 | It extract bluray disc iso file on various operating systems without neeed to mount it (except non-EEF iso). The binaries provided are portable so no need to install any framework.
38 |
39 | ## Command arguments
40 |
41 | | Short argument | Long argument | Meaning | Required |
42 | | --- | --- | --- | --- |
43 | | _`-p`_ | _`--path`_ | The path to iso file | x |
44 | | _`-o`_ | _`--output`_ | The output folder (if not specified then will extract in same location with iso) | |
45 |
46 | For linux, make `BDExtractor` as executable (yes, that one without extension) using `chmod +x BDExtractor`
47 |
48 | ## How to use
49 |
50 | ### Windows
51 | `BDExtractor.exe -p PATH_TO_ISO_FILE -o FOLDER_OUTPUT`
52 | `BDExtractor.exe -p PATH_TO_ISO_FILE`
53 |
54 | ### Linux:
55 | `./BDExtractor -p PATH_TO_ISO_FILE -o FOLDER_OUTPUT`
56 | `./BDExtractor -p PATH_TO_ISO_FILE`
57 |
58 | # Known issue
59 |
60 | https://github.com/DiscUtils/DiscUtils/issues/199
61 |
62 | [](https://github.com/dotnetcorecorner/BDInfo/actions/workflows/dotnet.yml)
63 |
64 | # Statistics
65 |
66 |  
67 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ## Welcome to BDInfo Github page
2 |
3 | This repository contains two major executables: **BDInfo** (for scanning bluray disc) and **BDExtractor** (for extracting bluray ISO disc, only EEF support due to limitation of library used)
4 |
5 | ### BDInfo
6 |
7 | You can grab from https://github.com/dotnetcorecorner/BDInfo/releases for Windows or Linux. Both are portable so no framework is neccesary. For Linux, you must set BDInfo as executable by running `chmod u+x BDInfo`
8 |
9 | It scans bluray disc (full hd, ultra hd and 3D) on various operating systems.
10 |
11 | #### Command arguments
12 |
13 | | Short argument | Long argument | Meaning | Required | Default |
14 | | --- | --- | --- | --- | --- |
15 | | _`-p`_ | _`--path`_ | The path to iso or bluray folder | x | |
16 | | _`-g`_ | _`--generatestreamdiagnostics`_ | Generate the stream diagnostics | | False |
17 | | _`-e`_ | _`--extendedstreamdiagnostics`_ | Generete the extended stream diagnostics | | False |
18 | | _`-b`_ | _`--enablessif`_ | Enable SSIF support | | False |
19 | | _`-c`_ | _`--displaychaptercount`_ | Enable chapter count | | False |
20 | | _`-a`_ | _`--autosavereport`_ | Auto save report | | False |
21 | | _`-f`_ | _`--generateframedatafile`_ | Generate frame data file | | False |
22 | | _`-l`_ | _`--filterloopingplaylists`_ | Filter loopig playlist | | False |
23 | | _`-y`_ | _`--filtershortplaylist`_ | Filter short playlist | | False |
24 | | _`-v`_ | _`--filtershortplaylistvalue`_ | Filter number of short playlist | | 20 |
25 | | _`-i`_ | _`--useimageprefix`_ | Use image prefix | | False |
26 | | _`-x`_ | _`--useimageprefixvalue`_ | Image prefix | | video- |
27 | | _`-k`_ | _`--keepstreamorder`_ | Keep stream order | | False |
28 | | _`-m`_ | _`--generatetextsummary`_ | Generate summary | | False |
29 | | _`-r`_ | _`--reportpath`_ | The folder where report will be saved. If none provided then will be in same location with application | | |
30 | | _`-o`_ | _`--reportfilename`_ | The report filename with extension. If no extension provided then will append .txt at end of filename | | |
31 | | _`-q`_ | _`--includeversionandnotes`_ | Include version and notes inside report | | False |
32 | | _`-z`_ | _`--printonlybigplaylist`_ | Print report with only biggest playlist | | False |
33 | | _`-w`_ | _`--printtoconsole`_ | Print report to console | | False |
34 | | _`-j`_ | _`--groupbytime`_ | Group by time | | False |
35 | | _`-d`_ | _`--isexecutedasscript`_ | Check if is executed as script | | False |
36 |
37 |
38 | #### How to use
39 |
40 | ##### Windows
41 | `BDInfo.exe -p PATH_TO_DISC_FOLDER -r FOLDER_WHERE_REPORT_WILL_BE_SAVED -o REPORTNAME.EXTENSION`
42 | `BDInfo.exe -p PATH_TO_ISO_FILE -r FOLDER_WHERE_REPORT_WILL_BE_SAVED -o REPORTNAME.EXTENSION`
43 |
44 | ##### Linux
45 | `./BDInfo -p PATH_TO_DISC_FOLDER -r FOLDER_WHERE_REPORT_WILL_BE_SAVED -o REPORTNAME.EXTENSION`
46 | `./BDInfo -p PATH_TO_ISO_FILE -r FOLDER_WHERE_REPORT_WILL_BE_SAVED -o REPORTNAME.EXTENSION`
47 |
48 | ### BDExtractor
49 |
50 | It extract bluray disc iso file on various operating systems without neeed to mount it (except non-EEF iso). The binaries provided are portable so no need to install any framework.
51 |
52 | #### Command arguments
53 |
54 | | Short argument | Long argument | Meaning | Required |
55 | | --- | --- | --- | --- |
56 | | _`-p`_ | _`--path`_ | The path to iso file | x |
57 | | _`-o`_ | _`--output`_ | The output folder | x |
58 |
59 | For linux, make `BDExtractor` as executable (yes, that one without extension) using `chmod +x BDExtractor`
60 |
61 | #### How to use
62 |
63 | ##### Windows
64 | `BDExtractor.exe -p PATH_TO_ISO_FILE -o FOLDER_OUTPUT`
65 |
66 | ##### Linux:
67 | `./BDExtractor -p PATH_TO_ISO_FILE -o FOLDER_OUTPUT`
68 |
--------------------------------------------------------------------------------