├── .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 | [![Build x64](https://github.com/dotnetcorecorner/BDInfo/actions/workflows/dotnet.yml/badge.svg)](https://github.com/dotnetcorecorner/BDInfo/actions/workflows/dotnet.yml) 63 | 64 | # Statistics 65 | 66 | ![GitHub release (by tag)](https://img.shields.io/github/downloads/dotnetcorecorner/bdinfo/win-1.0.0/total?style=flat-square) ![GitHub release (by tag)](https://img.shields.io/github/downloads/dotnetcorecorner/bdinfo/linux-1.0.0/total?style=flat-square) 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 | --------------------------------------------------------------------------------