diff --git a/.ci/azure-pipelines-compat.yml b/.ci/azure-pipelines-compat.yml
new file mode 100644
index 0000000000..762bbdcb2e
--- /dev/null
+++ b/.ci/azure-pipelines-compat.yml
@@ -0,0 +1,96 @@
+parameters:
+ - name: Packages
+ type: object
+ default: {}
+ - name: LinuxImage
+ type: string
+ default: "ubuntu-latest"
+ - name: DotNetSdkVersion
+ type: string
+ default: 3.1.100
+
+jobs:
+ - job: CompatibilityCheck
+ displayName: Compatibility Check
+ pool:
+ vmImage: "${{ parameters.LinuxImage }}"
+ # only execute for pull requests
+ condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber'])
+ strategy:
+ matrix:
+ ${{ each Package in parameters.Packages }}:
+ ${{ Package.key }}:
+ NugetPackageName: ${{ Package.value.NugetPackageName }}
+ AssemblyFileName: ${{ Package.value.AssemblyFileName }}
+ maxParallel: 2
+ dependsOn: MainBuild
+ steps:
+ - checkout: none
+
+ - task: UseDotNet@2
+ displayName: "Update DotNet"
+ inputs:
+ packageType: sdk
+ version: ${{ parameters.DotNetSdkVersion }}
+
+ - task: DownloadPipelineArtifact@2
+ displayName: "Download New Assembly Build Artifact"
+ inputs:
+ source: "current"
+ artifact: "$(NugetPackageName)"
+ path: "$(System.ArtifactsDirectory)/new-artifacts"
+ runVersion: "latest"
+
+ - task: CopyFiles@2
+ displayName: "Copy New Assembly Build Artifact"
+ inputs:
+ sourceFolder: $(System.ArtifactsDirectory)/new-artifacts
+ contents: "**/*.dll"
+ targetFolder: $(System.ArtifactsDirectory)/new-release
+ cleanTargetFolder: true
+ overWrite: true
+ flattenFolders: true
+
+ - task: DownloadPipelineArtifact@2
+ displayName: "Download Reference Assembly Build Artifact"
+ inputs:
+ source: "specific"
+ artifact: "$(NugetPackageName)"
+ path: "$(System.ArtifactsDirectory)/current-artifacts"
+ project: "$(System.TeamProjectId)"
+ pipeline: "$(System.DefinitionId)"
+ runVersion: "latestFromBranch"
+ runBranch: "refs/heads/$(System.PullRequest.TargetBranch)"
+
+ - task: CopyFiles@2
+ displayName: "Copy Reference Assembly Build Artifact"
+ inputs:
+ sourceFolder: $(System.ArtifactsDirectory)/current-artifacts
+ contents: "**/*.dll"
+ targetFolder: $(System.ArtifactsDirectory)/current-release
+ cleanTargetFolder: true
+ overWrite: true
+ flattenFolders: true
+
+ - task: DownloadGitHubRelease@0
+ displayName: "Download ABI Compatibility Check Tool"
+ inputs:
+ connection: Jellyfin Release Download
+ userRepository: EraYaN/dotnet-compatibility
+ defaultVersionType: "latest"
+ itemPattern: "**-ci.zip"
+ downloadPath: "$(System.ArtifactsDirectory)"
+
+ - task: ExtractFiles@1
+ displayName: "Extract ABI Compatibility Check Tool"
+ inputs:
+ archiveFilePatterns: "$(System.ArtifactsDirectory)/*-ci.zip"
+ destinationFolder: $(System.ArtifactsDirectory)/tools
+ cleanDestinationFolder: true
+
+ # The `--warnings-only` switch will swallow the return code and not emit any errors.
+ - task: CmdLine@2
+ displayName: "Execute ABI Compatibility Check Tool"
+ inputs:
+ script: "dotnet tools/CompatibilityCheckerCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines --warnings-only"
+ workingDirectory: $(System.ArtifactsDirectory)
diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml
new file mode 100644
index 0000000000..09901b2a6a
--- /dev/null
+++ b/.ci/azure-pipelines-main.yml
@@ -0,0 +1,101 @@
+parameters:
+ LinuxImage: "ubuntu-latest"
+ RestoreBuildProjects: "Jellyfin.Server/Jellyfin.Server.csproj"
+ DotNetSdkVersion: 3.1.100
+
+jobs:
+ - job: MainBuild
+ displayName: Main Build
+ strategy:
+ matrix:
+ Release:
+ BuildConfiguration: Release
+ Debug:
+ BuildConfiguration: Debug
+ maxParallel: 2
+ pool:
+ vmImage: "${{ parameters.LinuxImage }}"
+ steps:
+ - checkout: self
+ clean: true
+ submodules: true
+ persistCredentials: true
+
+ - task: CmdLine@2
+ displayName: "Clone Web Client (Master, Release, or Tag)"
+ condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ script: "git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web"
+
+ - task: CmdLine@2
+ displayName: "Clone Web Client (PR)"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest'))
+ inputs:
+ script: "git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web"
+
+ - task: NodeTool@0
+ displayName: "Install Node"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ versionSpec: "10.x"
+
+ - task: CmdLine@2
+ displayName: "Build Web Client"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ script: yarn install
+ workingDirectory: $(Agent.TempDirectory)/jellyfin-web
+
+ - task: CopyFiles@2
+ displayName: "Copy Web Client"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist
+ contents: "**"
+ targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web
+ cleanTargetFolder: true
+ overWrite: true
+ flattenFolders: false
+
+ - task: UseDotNet@2
+ displayName: "Update DotNet"
+ inputs:
+ packageType: sdk
+ version: ${{ parameters.DotNetSdkVersion }}
+
+ - task: DotNetCoreCLI@2
+ displayName: "Publish Server"
+ inputs:
+ command: publish
+ publishWebProjects: false
+ projects: "${{ parameters.RestoreBuildProjects }}"
+ arguments: "--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)"
+ zipAfterPublish: false
+
+ - task: PublishPipelineArtifact@0
+ displayName: "Publish Artifact Naming"
+ condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
+ inputs:
+ targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/Emby.Naming.dll"
+ artifactName: "Jellyfin.Naming"
+
+ - task: PublishPipelineArtifact@0
+ displayName: "Publish Artifact Controller"
+ condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
+ inputs:
+ targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Controller.dll"
+ artifactName: "Jellyfin.Controller"
+
+ - task: PublishPipelineArtifact@0
+ displayName: "Publish Artifact Model"
+ condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
+ inputs:
+ targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Model.dll"
+ artifactName: "Jellyfin.Model"
+
+ - task: PublishPipelineArtifact@0
+ displayName: "Publish Artifact Common"
+ condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
+ inputs:
+ targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Common.dll"
+ artifactName: "Jellyfin.Common"
diff --git a/.ci/azure-pipelines-test.yml b/.ci/azure-pipelines-test.yml
new file mode 100644
index 0000000000..4455632e15
--- /dev/null
+++ b/.ci/azure-pipelines-test.yml
@@ -0,0 +1,65 @@
+parameters:
+ - name: ImageNames
+ type: object
+ default:
+ Linux: "ubuntu-latest"
+ Windows: "windows-latest"
+ macOS: "macos-latest"
+ - name: TestProjects
+ type: string
+ default: "tests/**/*Tests.csproj"
+ - name: DotNetSdkVersion
+ type: string
+ default: 3.1.100
+
+jobs:
+ - job: MainTest
+ displayName: Main Test
+ strategy:
+ matrix:
+ ${{ each imageName in parameters.ImageNames }}:
+ ${{ imageName.key }}:
+ ImageName: ${{ imageName.value }}
+ maxParallel: 3
+ pool:
+ vmImage: "$(ImageName)"
+ steps:
+ - checkout: self
+ clean: true
+ submodules: true
+ persistCredentials: false
+
+ - task: UseDotNet@2
+ displayName: "Update DotNet"
+ inputs:
+ packageType: sdk
+ version: ${{ parameters.DotNetSdkVersion }}
+
+ - task: DotNetCoreCLI@2
+ displayName: Run .NET Core CLI tests
+ inputs:
+ command: "test"
+ projects: ${{ parameters.TestProjects }}
+ arguments: '--configuration Release --collect:"XPlat Code Coverage" --settings tests/coverletArgs.runsettings --verbosity minimal "-p:GenerateDocumentationFile=False"'
+ publishTestResults: true
+ testRunTitle: $(Agent.JobName)
+ workingDirectory: "$(Build.SourcesDirectory)"
+
+ - task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging
+ displayName: ReportGenerator (merge)
+ inputs:
+ reports: "$(Agent.TempDirectory)/**/coverage.cobertura.xml"
+ targetdir: "$(Agent.TempDirectory)/merged/"
+ reporttypes: "Cobertura"
+
+ ## V2 is already in the repository but it does not work "wrong number of segments" YAML error.
+ - task: PublishCodeCoverageResults@1
+ condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging
+ displayName: Publish Code Coverage
+ inputs:
+ codeCoverageTool: "cobertura"
+ #summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml' # !!THIS IS FOR V2
+ summaryFileLocation: "$(Agent.TempDirectory)/merged/**.xml"
+ pathToSources: $(Build.SourcesDirectory)
+ failIfCoverageEmpty: true
diff --git a/.ci/azure-pipelines-windows.yml b/.ci/azure-pipelines-windows.yml
new file mode 100644
index 0000000000..32d1d1382d
--- /dev/null
+++ b/.ci/azure-pipelines-windows.yml
@@ -0,0 +1,82 @@
+parameters:
+ WindowsImage: "windows-latest"
+ TestProjects: "tests/**/*Tests.csproj"
+ DotNetSdkVersion: 3.1.100
+
+jobs:
+ - job: PublishWindows
+ displayName: Publish Windows
+ pool:
+ vmImage: ${{ parameters.WindowsImage }}
+ steps:
+ - checkout: self
+ clean: true
+ submodules: true
+ persistCredentials: true
+
+ - task: CmdLine@2
+ displayName: "Clone Web Client (Master, Release, or Tag)"
+ condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'tag')), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ script: "git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web"
+
+ - task: CmdLine@2
+ displayName: "Clone Web Client (PR)"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest'))
+ inputs:
+ script: "git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web"
+
+ - task: NodeTool@0
+ displayName: "Install Node"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ versionSpec: "10.x"
+
+ - task: CmdLine@2
+ displayName: "Build Web Client"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ script: yarn install
+ workingDirectory: $(Agent.TempDirectory)/jellyfin-web
+
+ - task: CopyFiles@2
+ displayName: "Copy Web Client"
+ condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+ inputs:
+ sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist
+ contents: "**"
+ targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web
+ cleanTargetFolder: true
+ overWrite: true
+ flattenFolders: false
+
+ - task: CmdLine@2
+ displayName: "Clone UX Repository"
+ inputs:
+ script: git clone --depth=1 https://github.com/jellyfin/jellyfin-ux $(Agent.TempDirectory)\jellyfin-ux
+
+ - task: PowerShell@2
+ displayName: "Build NSIS Installer"
+ inputs:
+ targetType: "filePath"
+ filePath: ./deployment/windows/build-jellyfin.ps1
+ arguments: -InstallFFMPEG -InstallNSSM -MakeNSIS -InstallTrayApp -UXLocation $(Agent.TempDirectory)\jellyfin-ux -InstallLocation $(build.artifactstagingdirectory)
+ errorActionPreference: "stop"
+ workingDirectory: $(Build.SourcesDirectory)
+
+ - task: CopyFiles@2
+ displayName: "Copy NSIS Installer"
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/deployment/windows/
+ contents: "jellyfin*.exe"
+ targetFolder: $(System.ArtifactsDirectory)/setup
+ cleanTargetFolder: true
+ overWrite: true
+ flattenFolders: true
+
+ - task: PublishPipelineArtifact@0
+ displayName: "Publish Artifact Setup"
+ condition: succeeded()
+ inputs:
+ targetPath: "$(build.artifactstagingdirectory)/setup"
+ artifactName: "Jellyfin Server Setup"
diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml
index 13cc67528f..f79a85b210 100644
--- a/.ci/azure-pipelines.yml
+++ b/.ci/azure-pipelines.yml
@@ -2,9 +2,11 @@ name: $(Date:yyyyMMdd)$(Rev:.r)
variables:
- name: TestProjects
- value: 'tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj'
+ value: "tests/**/*Tests.csproj"
- name: RestoreBuildProjects
- value: 'Jellyfin.Server/Jellyfin.Server.csproj'
+ value: "Jellyfin.Server/Jellyfin.Server.csproj"
+ - name: DotNetSdkVersion
+ value: 3.1.100
pr:
autoCancel: true
@@ -13,271 +15,26 @@ trigger:
batch: true
jobs:
- - job: main_build
- displayName: Main Build
- pool:
- vmImage: ubuntu-latest
- strategy:
- matrix:
- release:
- BuildConfiguration: Release
- debug:
- BuildConfiguration: Debug
- maxParallel: 2
- steps:
- - checkout: self
- clean: true
- submodules: true
- persistCredentials: true
-
- - task: CmdLine@2
- displayName: "Check out web"
- condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
-
- - task: CmdLine@2
- displayName: "Check out web (PR)"
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest'))
- inputs:
- script: 'git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
-
- - task: NodeTool@0
- displayName: 'Install Node.js'
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- versionSpec: '10.x'
-
- - task: CmdLine@2
- displayName: "Build Web UI"
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- script: yarn install
- workingDirectory: $(Agent.TempDirectory)/jellyfin-web
-
- - task: CopyFiles@2
- displayName: Copy the web UI
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist # Optional
- contents: '**'
- targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web
- cleanTargetFolder: true # Optional
- overWrite: true # Optional
- flattenFolders: false # Optional
-
- - task: DotNetCoreCLI@2
- displayName: Publish
- inputs:
- command: publish
- publishWebProjects: false
- projects: '$(RestoreBuildProjects)'
- arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
- zipAfterPublish: false
-
- - task: PublishPipelineArtifact@0
- displayName: 'Publish Artifact Naming'
- condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
- inputs:
- targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/Emby.Naming.dll'
- artifactName: 'Jellyfin.Naming'
-
- - task: PublishPipelineArtifact@0
- displayName: 'Publish Artifact Controller'
- condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
- inputs:
- targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Controller.dll'
- artifactName: 'Jellyfin.Controller'
-
- - task: PublishPipelineArtifact@0
- displayName: 'Publish Artifact Model'
- condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
- inputs:
- targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Model.dll'
- artifactName: 'Jellyfin.Model'
-
- - task: PublishPipelineArtifact@0
- displayName: 'Publish Artifact Common'
- condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
- inputs:
- targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Common.dll'
- artifactName: 'Jellyfin.Common'
-
- - job: main_test
- displayName: Main Test
- pool:
- vmImage: windows-latest
- steps:
- - checkout: self
- clean: true
- submodules: true
- persistCredentials: false
-
- - task: DotNetCoreCLI@2
- displayName: Build
- inputs:
- command: build
- publishWebProjects: false
- projects: '$(TestProjects)'
- arguments: '--configuration $(BuildConfiguration)'
- zipAfterPublish: false
-
- - task: VisualStudioTestPlatformInstaller@1
- inputs:
- packageFeedSelector: 'nugetOrg' # Options: nugetOrg, customFeed, netShare
- versionSelector: 'latestPreRelease' # Required when packageFeedSelector == NugetOrg || PackageFeedSelector == CustomFeed# Options: latestPreRelease, latestStable, specificVersion
-
- - task: VSTest@2
- inputs:
- testSelector: 'testAssemblies' # Options: testAssemblies, testPlan, testRun
- testAssemblyVer2: | # Required when testSelector == TestAssemblies
- **\bin\$(BuildConfiguration)\**\*test*.dll
- !**\obj\**
- !**\xunit.runner.visualstudio.testadapter.dll
- !**\xunit.runner.visualstudio.dotnetcore.testadapter.dll
- #testPlan: # Required when testSelector == TestPlan
- #testSuite: # Required when testSelector == TestPlan
- #testConfiguration: # Required when testSelector == TestPlan
- #tcmTestRun: '$(test.RunId)' # Optional
- searchFolder: '$(System.DefaultWorkingDirectory)'
- #testFiltercriteria: # Optional
- #runOnlyImpactedTests: False # Optional
- #runAllTestsAfterXBuilds: '50' # Optional
- #uiTests: false # Optional
- #vstestLocationMethod: 'version' # Optional. Options: version, location
- #vsTestVersion: 'latest' # Optional. Options: latest, 16.0, 15.0, 14.0, toolsInstaller
- #vstestLocation: # Optional
- #runSettingsFile: # Optional
- #overrideTestrunParameters: # Optional
- #pathtoCustomTestAdapters: # Optional
- runInParallel: True # Optional
- runTestsInIsolation: True # Optional
- codeCoverageEnabled: True # Optional
- #otherConsoleOptions: # Optional
- #distributionBatchType: 'basedOnTestCases' # Optional. Options: basedOnTestCases, basedOnExecutionTime, basedOnAssembly
- #batchingBasedOnAgentsOption: 'autoBatchSize' # Optional. Options: autoBatchSize, customBatchSize
- #customBatchSizeValue: '10' # Required when distributionBatchType == BasedOnTestCases && BatchingBasedOnAgentsOption == CustomBatchSize
- #batchingBasedOnExecutionTimeOption: 'autoBatchSize' # Optional. Options: autoBatchSize, customTimeBatchSize
- #customRunTimePerBatchValue: '60' # Required when distributionBatchType == BasedOnExecutionTime && BatchingBasedOnExecutionTimeOption == CustomTimeBatchSize
- #dontDistribute: False # Optional
- #testRunTitle: # Optional
- #platform: # Optional
- configuration: 'Debug' # Optional
- publishRunAttachments: true # Optional
- #diagnosticsEnabled: false # Optional
- #collectDumpOn: 'onAbortOnly' # Optional. Options: onAbortOnly, always, never
- #rerunFailedTests: False # Optional
- #rerunType: 'basedOnTestFailurePercentage' # Optional. Options: basedOnTestFailurePercentage, basedOnTestFailureCount
- #rerunFailedThreshold: '30' # Optional
- #rerunFailedTestCasesMaxLimit: '5' # Optional
- #rerunMaxAttempts: '3' # Optional
-
- # - task: PublishTestResults@2
- # inputs:
- # testResultsFormat: 'VSTest' # Options: JUnit, NUnit, VSTest, xUnit, cTest
- # testResultsFiles: '**/*.trx'
- # #searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
- # mergeTestResults: true # Optional
- # #failTaskOnFailedTests: false # Optional
- # #testRunTitle: # Optional
- # #buildPlatform: # Optional
- # #buildConfiguration: # Optional
- # #publishRunAttachments: true # Optional
-
- - job: main_build_win
- displayName: Main Build Windows
- pool:
- vmImage: windows-latest
- strategy:
- matrix:
- release:
- BuildConfiguration: Release
- maxParallel: 2
- steps:
- - checkout: self
- clean: true
- submodules: true
- persistCredentials: true
-
- - task: CmdLine@2
- displayName: "Check out web (master, release or tag)"
- condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'tag')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
-
- - task: CmdLine@2
- displayName: "Check out web (PR)"
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest'))
- inputs:
- script: 'git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
-
- - task: NodeTool@0
- displayName: 'Install Node.js'
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- versionSpec: '10.x'
-
- - task: CmdLine@2
- displayName: "Build Web UI"
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- script: yarn install
- workingDirectory: $(Agent.TempDirectory)/jellyfin-web
-
- - task: CopyFiles@2
- displayName: Copy the web UI
- condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
- inputs:
- sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist # Optional
- contents: '**'
- targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web
- cleanTargetFolder: true # Optional
- overWrite: true # Optional
- flattenFolders: false # Optional
-
- - task: CmdLine@2
- displayName: Clone the UX repository
- inputs:
- script: git clone --depth=1 https://github.com/jellyfin/jellyfin-ux $(Agent.TempDirectory)\jellyfin-ux
-
- - task: PowerShell@2
- displayName: Build the NSIS Installer
- inputs:
- targetType: 'filePath' # Optional. Options: filePath, inline
- filePath: ./deployment/windows/build-jellyfin.ps1 # Required when targetType == FilePath
- arguments: -InstallFFMPEG -InstallNSSM -MakeNSIS -InstallTrayApp -UXLocation $(Agent.TempDirectory)\jellyfin-ux -InstallLocation $(build.artifactstagingdirectory)
- #script: '# Write your PowerShell commands here.Write-Host Hello World' # Required when targetType == Inline
- errorActionPreference: 'stop' # Optional. Options: stop, continue, silentlyContinue
- #failOnStderr: false # Optional
- #ignoreLASTEXITCODE: false # Optional
- #pwsh: false # Optional
- workingDirectory: $(Build.SourcesDirectory) # Optional
-
- - task: CopyFiles@2
- displayName: Copy the NSIS Installer to the artifact directory
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/deployment/windows/ # Optional
- contents: 'jellyfin*.exe'
- targetFolder: $(System.ArtifactsDirectory)/setup
- cleanTargetFolder: true # Optional
- overWrite: true # Optional
- flattenFolders: true # Optional
-
- - task: PublishPipelineArtifact@0
- displayName: 'Publish Setup Artifact'
- condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
- inputs:
- targetPath: '$(build.artifactstagingdirectory)/setup'
- artifactName: 'Jellyfin Server Setup'
-
- - job: dotnet_compat
- displayName: Compatibility Check
- pool:
- vmImage: ubuntu-latest
- dependsOn: main_build
- condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber']) # Only execute if the pullrequest numer is defined. (So not for normal CI builds)
- strategy:
- matrix:
+ - template: azure-pipelines-main.yml
+ parameters:
+ LinuxImage: "ubuntu-latest"
+ RestoreBuildProjects: $(RestoreBuildProjects)
+
+ - template: azure-pipelines-test.yml
+ parameters:
+ ImageNames:
+ Linux: "ubuntu-latest"
+ Windows: "windows-latest"
+ macOS: "macos-latest"
+
+ - template: azure-pipelines-windows.yml
+ parameters:
+ WindowsImage: "windows-latest"
+ TestProjects: $(TestProjects)
+
+ - template: azure-pipelines-compat.yml
+ parameters:
+ Packages:
Naming:
NugetPackageName: Jellyfin.Naming
AssemblyFileName: Emby.Naming.dll
@@ -290,82 +47,4 @@ jobs:
Common:
NugetPackageName: Jellyfin.Common
AssemblyFileName: MediaBrowser.Common.dll
- maxParallel: 2
- steps:
- - checkout: none
-
- - task: DownloadPipelineArtifact@2
- displayName: Download the New Assembly Build Artifact
- inputs:
- source: 'current' # Options: current, specific
- #preferTriggeringPipeline: false # Optional
- #tags: # Optional
- artifact: '$(NugetPackageName)' # Optional
- #patterns: '**' # Optional
- path: '$(System.ArtifactsDirectory)/new-artifacts'
- #project: # Required when source == Specific
- #pipeline: # Required when source == Specific
- runVersion: 'latest' # Required when source == Specific. Options: latest, latestFromBranch, specific
- #runBranch: 'refs/heads/master' # Required when source == Specific && runVersion == LatestFromBranch
- #runId: # Required when source == Specific && runVersion == Specific
-
- - task: CopyFiles@2
- displayName: Copy New Assembly to new-release folder
- inputs:
- sourceFolder: $(System.ArtifactsDirectory)/new-artifacts # Optional
- contents: '**/*.dll'
- targetFolder: $(System.ArtifactsDirectory)/new-release
- cleanTargetFolder: true # Optional
- overWrite: true # Optional
- flattenFolders: true # Optional
-
- - task: DownloadPipelineArtifact@2
- displayName: Download the Reference Assembly Build Artifact
- inputs:
- source: 'specific' # Options: current, specific
- #preferTriggeringPipeline: false # Optional
- #tags: # Optional
- artifact: '$(NugetPackageName)' # Optional
- #patterns: '**' # Optional
- path: '$(System.ArtifactsDirectory)/current-artifacts'
- project: '$(System.TeamProjectId)' # Required when source == Specific
- pipeline: '$(System.DefinitionId)' # Required when source == Specific
- runVersion: 'latestFromBranch' # Required when source == Specific. Options: latest, latestFromBranch, specific
- runBranch: 'refs/heads/$(System.PullRequest.TargetBranch)' # Required when source == Specific && runVersion == LatestFromBranch
- #runId: # Required when source == Specific && runVersion == Specific
-
- - task: CopyFiles@2
- displayName: Copy Reference Assembly to current-release folder
- inputs:
- sourceFolder: $(System.ArtifactsDirectory)/current-artifacts # Optional
- contents: '**/*.dll'
- targetFolder: $(System.ArtifactsDirectory)/current-release
- cleanTargetFolder: true # Optional
- overWrite: true # Optional
- flattenFolders: true # Optional
-
- - task: DownloadGitHubRelease@0
- displayName: Download ABI compatibility check tool from GitHub
- inputs:
- connection: Jellyfin Release Download
- userRepository: EraYaN/dotnet-compatibility
- defaultVersionType: 'latest' # Options: latest, specificVersion, specificTag
- #version: # Required when defaultVersionType != Latest
- itemPattern: '**-ci.zip' # Optional
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - task: ExtractFiles@1
- displayName: Extract ABI compatibility check tool
- inputs:
- archiveFilePatterns: '$(System.ArtifactsDirectory)/*-ci.zip'
- destinationFolder: $(System.ArtifactsDirectory)/tools
- cleanDestinationFolder: true
-
- - task: CmdLine@2
- displayName: Execute ABI compatibility check tool
- inputs:
- script: 'dotnet tools/CompatibilityCheckerCoreCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines'
- workingDirectory: $(System.ArtifactsDirectory) # Optional
- #failOnStderr: false # Optional
-
-
+ LinuxImage: "ubuntu-latest"
diff --git a/.ci/publish-nightly.yml b/.ci/publish-nightly.yml
deleted file mode 100644
index a693e10f6c..0000000000
--- a/.ci/publish-nightly.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-name: Nightly-$(date:yyyyMMdd).$(rev:r)
-
-variables:
- - name: Version
- value: '1.0.0'
-
-trigger: none
-pr: none
-
-jobs:
- - job: publish_artifacts_nightly
- displayName: Publish Artifacts Nightly
- pool:
- vmImage: ubuntu-latest
- steps:
- - checkout: none
- - task: DownloadPipelineArtifact@2
- displayName: Download the Windows Setup Artifact
- inputs:
- source: 'specific' # Options: current, specific
- artifact: 'Jellyfin Server Setup' # Optional
- path: '$(System.ArtifactsDirectory)/win-installer'
- project: '$(System.TeamProjectId)' # Required when source == Specific
- pipelineId: 1 # Required when source == Specific
- runVersion: 'latestFromBranch' # Required when source == Specific. Options: latest, latestFromBranch, specific
- runBranch: 'refs/heads/master' # Required when source == Specific && runVersion == LatestFromBranch
-
- - task: SSH@0
- displayName: 'Create Drop directory'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_nightly_azure_upload'
-
- - task: CopyFilesOverSSH@0
- displayName: 'Copy the Windows Setup to the Repo'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- sourceFolder: '$(System.ArtifactsDirectory)/win-installer'
- contents: 'jellyfin_*.exe'
- targetFolder: '/srv/incoming/jellyfin_nightly_azure_upload/win-installer'
-
- - task: SSH@0
- displayName: 'Clean up SCP symlink'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- commands: 'rm -f /srv/incoming/jellyfin_nightly_azure_upload'
diff --git a/.ci/publish-release.yml b/.ci/publish-release.yml
deleted file mode 100644
index 57e77ae5aa..0000000000
--- a/.ci/publish-release.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: Release-$(Version)-$(date:yyyyMMdd).$(rev:r)
-
-variables:
- - name: Version
- value: '1.0.0'
- - name: UsedRunId
- value: 0
-
-trigger: none
-pr: none
-
-jobs:
- - job: publish_artifacts_release
- displayName: Publish Artifacts Release
- pool:
- vmImage: ubuntu-latest
- steps:
- - checkout: none
- - task: DownloadPipelineArtifact@2
- displayName: Download the Windows Setup Artifact
- inputs:
- source: 'specific' # Options: current, specific
- artifact: 'Jellyfin Server Setup' # Optional
- path: '$(System.ArtifactsDirectory)/win-installer'
- project: '$(System.TeamProjectId)' # Required when source == Specific
- pipelineId: 1 # Required when source == Specific
- runVersion: 'specific' # Required when source == Specific. Options: latest, latestFromBranch, specific
- runId: $(UsedRunId)
-
- - task: SSH@0
- displayName: 'Create Drop directory'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_release_azure_upload'
-
- - task: CopyFilesOverSSH@0
- displayName: 'Copy the Windows Setup to the Repo'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- sourceFolder: '$(System.ArtifactsDirectory)/win-installer'
- contents: 'jellyfin_*.exe'
- targetFolder: '/srv/incoming/jellyfin_release_azure_upload/win-installer'
-
- - task: SSH@0
- displayName: 'Clean up SCP symlink'
- inputs:
- sshEndpoint: 'Jellyfin Build Server'
- commands: 'rm -f /srv/incoming/jellyfin_release_azure_upload'
diff --git a/.github/ISSUE_TEMPLATE/media_playback.md b/.github/ISSUE_TEMPLATE/media_playback.md
index 93af33fbfd..b51500f870 100644
--- a/.github/ISSUE_TEMPLATE/media_playback.md
+++ b/.github/ISSUE_TEMPLATE/media_playback.md
@@ -11,7 +11,10 @@ assignees: ''
**Logs**
-
+
+
+**FFmpeg Logs**
+
**Stats for Nerds Screenshots**
@@ -29,4 +32,3 @@ assignees: ''
- Client: [e.g. Web/Browser, webOS, Android, Android TV, Electron]
- Browser (if Web client): [e.g. Firefox, Chrome, Safari]
- Client and Browser Version: [e.g. 10.3.4 and 68.0]
-
diff --git a/.vscode/launch.json b/.vscode/launch.json
index e2a09c0f15..73f347c9fe 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.0/jellyfin.dll",
+ "program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.1/jellyfin.dll",
"args": [],
"cwd": "${workspaceFolder}/Jellyfin.Server",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
diff --git a/BDInfo/BDInfo.csproj b/BDInfo/BDInfo.csproj
deleted file mode 100644
index 9dbaa9e2f0..0000000000
--- a/BDInfo/BDInfo.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- netstandard2.0
- false
- true
-
-
-
diff --git a/BDInfo/BDInfoSettings.cs b/BDInfo/BDInfoSettings.cs
deleted file mode 100644
index f4cb300166..0000000000
--- a/BDInfo/BDInfoSettings.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-
-namespace BDInfo
-{
- class BDInfoSettings
- {
- public static bool GenerateStreamDiagnostics => true;
-
- public static bool EnableSSIF => true;
-
- public static bool AutosaveReport => false;
-
- public static bool GenerateFrameDataFile => false;
-
- public static bool FilterLoopingPlaylists => true;
-
- public static bool FilterShortPlaylists => false;
-
- public static int FilterShortPlaylistsValue => 0;
-
- public static bool UseImagePrefix => false;
-
- public static string UseImagePrefixValue => null;
-
- ///
- /// Setting this to false throws an IComparer error on some discs.
- ///
- public static bool KeepStreamOrder => true;
-
- public static bool GenerateTextSummary => false;
-
- public static string LastPath => string.Empty;
- }
-}
diff --git a/BDInfo/BDROM.cs b/BDInfo/BDROM.cs
deleted file mode 100644
index 3a0c14ffda..0000000000
--- a/BDInfo/BDROM.cs
+++ /dev/null
@@ -1,449 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
- public class BDROM
- {
- public FileSystemMetadata DirectoryRoot = null;
- public FileSystemMetadata DirectoryBDMV = null;
- public FileSystemMetadata DirectoryBDJO = null;
- public FileSystemMetadata DirectoryCLIPINF = null;
- public FileSystemMetadata DirectoryPLAYLIST = null;
- public FileSystemMetadata DirectorySNP = null;
- public FileSystemMetadata DirectorySSIF = null;
- public FileSystemMetadata DirectorySTREAM = null;
-
- public string VolumeLabel = null;
- public ulong Size = 0;
- public bool IsBDPlus = false;
- public bool IsBDJava = false;
- public bool IsDBOX = false;
- public bool IsPSP = false;
- public bool Is3D = false;
- public bool Is50Hz = false;
-
- private readonly IFileSystem _fileSystem;
-
- public Dictionary PlaylistFiles =
- new Dictionary();
- public Dictionary StreamClipFiles =
- new Dictionary();
- public Dictionary StreamFiles =
- new Dictionary();
- public Dictionary InterleavedFiles =
- new Dictionary();
-
- public delegate bool OnStreamClipFileScanError(
- TSStreamClipFile streamClipFile, Exception ex);
-
- public event OnStreamClipFileScanError StreamClipFileScanError;
-
- public delegate bool OnStreamFileScanError(
- TSStreamFile streamClipFile, Exception ex);
-
- public event OnStreamFileScanError StreamFileScanError;
-
- public delegate bool OnPlaylistFileScanError(
- TSPlaylistFile playlistFile, Exception ex);
-
- public event OnPlaylistFileScanError PlaylistFileScanError;
-
- public BDROM(string path, IFileSystem fileSystem)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- _fileSystem = fileSystem;
- //
- // Locate BDMV directories.
- //
-
- DirectoryBDMV =
- GetDirectoryBDMV(path);
-
- if (DirectoryBDMV == null)
- {
- throw new Exception("Unable to locate BD structure.");
- }
-
- DirectoryRoot =
- _fileSystem.GetDirectoryInfo(Path.GetDirectoryName(DirectoryBDMV.FullName));
- DirectoryBDJO =
- GetDirectory("BDJO", DirectoryBDMV, 0);
- DirectoryCLIPINF =
- GetDirectory("CLIPINF", DirectoryBDMV, 0);
- DirectoryPLAYLIST =
- GetDirectory("PLAYLIST", DirectoryBDMV, 0);
- DirectorySNP =
- GetDirectory("SNP", DirectoryRoot, 0);
- DirectorySTREAM =
- GetDirectory("STREAM", DirectoryBDMV, 0);
- DirectorySSIF =
- GetDirectory("SSIF", DirectorySTREAM, 0);
-
- if (DirectoryCLIPINF == null
- || DirectoryPLAYLIST == null)
- {
- throw new Exception("Unable to locate BD structure.");
- }
-
- //
- // Initialize basic disc properties.
- //
-
- VolumeLabel = GetVolumeLabel(DirectoryRoot);
- Size = (ulong)GetDirectorySize(DirectoryRoot);
-
- if (null != GetDirectory("BDSVM", DirectoryRoot, 0))
- {
- IsBDPlus = true;
- }
- if (null != GetDirectory("SLYVM", DirectoryRoot, 0))
- {
- IsBDPlus = true;
- }
- if (null != GetDirectory("ANYVM", DirectoryRoot, 0))
- {
- IsBDPlus = true;
- }
-
- if (DirectoryBDJO != null &&
- _fileSystem.GetFilePaths(DirectoryBDJO.FullName).Any())
- {
- IsBDJava = true;
- }
-
- if (DirectorySNP != null &&
- GetFilePaths(DirectorySNP.FullName, ".mnv").Any())
- {
- IsPSP = true;
- }
-
- if (DirectorySSIF != null &&
- _fileSystem.GetFilePaths(DirectorySSIF.FullName).Any())
- {
- Is3D = true;
- }
-
- if (File.Exists(Path.Combine(DirectoryRoot.FullName, "FilmIndex.xml")))
- {
- IsDBOX = true;
- }
-
- //
- // Initialize file lists.
- //
-
- if (DirectoryPLAYLIST != null)
- {
- FileSystemMetadata[] files = GetFiles(DirectoryPLAYLIST.FullName, ".mpls").ToArray();
- foreach (var file in files)
- {
- PlaylistFiles.Add(
- file.Name.ToUpper(), new TSPlaylistFile(this, file));
- }
- }
-
- if (DirectorySTREAM != null)
- {
- FileSystemMetadata[] files = GetFiles(DirectorySTREAM.FullName, ".m2ts").ToArray();
- foreach (var file in files)
- {
- StreamFiles.Add(
- file.Name.ToUpper(), new TSStreamFile(file, _fileSystem));
- }
- }
-
- if (DirectoryCLIPINF != null)
- {
- FileSystemMetadata[] files = GetFiles(DirectoryCLIPINF.FullName, ".clpi").ToArray();
- foreach (var file in files)
- {
- StreamClipFiles.Add(
- file.Name.ToUpper(), new TSStreamClipFile(file));
- }
- }
-
- if (DirectorySSIF != null)
- {
- FileSystemMetadata[] files = GetFiles(DirectorySSIF.FullName, ".ssif").ToArray();
- foreach (var file in files)
- {
- InterleavedFiles.Add(
- file.Name.ToUpper(), new TSInterleavedFile(file));
- }
- }
- }
-
- private IEnumerable GetFiles(string path, string extension)
- {
- return _fileSystem.GetFiles(path, new[] { extension }, false, false);
- }
-
- private IEnumerable GetFilePaths(string path, string extension)
- {
- return _fileSystem.GetFilePaths(path, new[] { extension }, false, false);
- }
-
- public void Scan()
- {
- foreach (var streamClipFile in StreamClipFiles.Values)
- {
- try
- {
- streamClipFile.Scan();
- }
- catch (Exception ex)
- {
- if (StreamClipFileScanError != null)
- {
- if (StreamClipFileScanError(streamClipFile, ex))
- {
- continue;
- }
- else
- {
- break;
- }
- }
- else throw;
- }
- }
-
- foreach (var streamFile in StreamFiles.Values)
- {
- string ssifName = Path.GetFileNameWithoutExtension(streamFile.Name) + ".SSIF";
- if (InterleavedFiles.ContainsKey(ssifName))
- {
- streamFile.InterleavedFile = InterleavedFiles[ssifName];
- }
- }
-
- TSStreamFile[] streamFiles = new TSStreamFile[StreamFiles.Count];
- StreamFiles.Values.CopyTo(streamFiles, 0);
- Array.Sort(streamFiles, CompareStreamFiles);
-
- foreach (var playlistFile in PlaylistFiles.Values)
- {
- try
- {
- playlistFile.Scan(StreamFiles, StreamClipFiles);
- }
- catch (Exception ex)
- {
- if (PlaylistFileScanError != null)
- {
- if (PlaylistFileScanError(playlistFile, ex))
- {
- continue;
- }
- else
- {
- break;
- }
- }
- else throw;
- }
- }
-
- foreach (var streamFile in streamFiles)
- {
- try
- {
- var playlists = new List();
- foreach (var playlist in PlaylistFiles.Values)
- {
- foreach (var streamClip in playlist.StreamClips)
- {
- if (streamClip.Name == streamFile.Name)
- {
- playlists.Add(playlist);
- break;
- }
- }
- }
- streamFile.Scan(playlists, false);
- }
- catch (Exception ex)
- {
- if (StreamFileScanError != null)
- {
- if (StreamFileScanError(streamFile, ex))
- {
- continue;
- }
- else
- {
- break;
- }
- }
- else throw;
- }
- }
-
- foreach (var playlistFile in PlaylistFiles.Values)
- {
- playlistFile.Initialize();
- if (!Is50Hz)
- {
- foreach (var videoStream in playlistFile.VideoStreams)
- {
- if (videoStream.FrameRate == TSFrameRate.FRAMERATE_25 ||
- videoStream.FrameRate == TSFrameRate.FRAMERATE_50)
- {
- Is50Hz = true;
- }
- }
- }
- }
- }
-
- private FileSystemMetadata GetDirectoryBDMV(
- string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- FileSystemMetadata dir = _fileSystem.GetDirectoryInfo(path);
-
- while (dir != null)
- {
- if (string.Equals(dir.Name, "BDMV", StringComparison.OrdinalIgnoreCase))
- {
- return dir;
- }
- var parentFolder = Path.GetDirectoryName(dir.FullName);
- if (string.IsNullOrEmpty(parentFolder))
- {
- dir = null;
- }
- else
- {
- dir = _fileSystem.GetDirectoryInfo(parentFolder);
- }
- }
-
- return GetDirectory("BDMV", _fileSystem.GetDirectoryInfo(path), 0);
- }
-
- private FileSystemMetadata GetDirectory(
- string name,
- FileSystemMetadata dir,
- int searchDepth)
- {
- if (dir != null)
- {
- FileSystemMetadata[] children = _fileSystem.GetDirectories(dir.FullName).ToArray();
- foreach (var child in children)
- {
- if (string.Equals(child.Name, name, StringComparison.OrdinalIgnoreCase))
- {
- return child;
- }
- }
- if (searchDepth > 0)
- {
- foreach (var child in children)
- {
- GetDirectory(
- name, child, searchDepth - 1);
- }
- }
- }
- return null;
- }
-
- private long GetDirectorySize(FileSystemMetadata directoryInfo)
- {
- long size = 0;
-
- //if (!ExcludeDirs.Contains(directoryInfo.Name.ToUpper())) // TODO: Keep?
- {
- FileSystemMetadata[] pathFiles = _fileSystem.GetFiles(directoryInfo.FullName).ToArray();
- foreach (var pathFile in pathFiles)
- {
- if (pathFile.Extension.ToUpper() == ".SSIF")
- {
- continue;
- }
- size += pathFile.Length;
- }
-
- FileSystemMetadata[] pathChildren = _fileSystem.GetDirectories(directoryInfo.FullName).ToArray();
- foreach (var pathChild in pathChildren)
- {
- size += GetDirectorySize(pathChild);
- }
- }
-
- return size;
- }
-
- private string GetVolumeLabel(FileSystemMetadata dir)
- {
- return dir.Name;
- }
-
- public int CompareStreamFiles(
- TSStreamFile x,
- TSStreamFile y)
- {
- // TODO: Use interleaved file sizes
-
- if ((x == null || x.FileInfo == null) && (y == null || y.FileInfo == null))
- {
- return 0;
- }
- else if ((x == null || x.FileInfo == null) && (y != null && y.FileInfo != null))
- {
- return 1;
- }
- else if ((x != null && x.FileInfo != null) && (y == null || y.FileInfo == null))
- {
- return -1;
- }
- else
- {
- if (x.FileInfo.Length > y.FileInfo.Length)
- {
- return 1;
- }
- else if (y.FileInfo.Length > x.FileInfo.Length)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
- }
- }
-}
diff --git a/BDInfo/LanguageCodes.cs b/BDInfo/LanguageCodes.cs
deleted file mode 100644
index ab2693ffbc..0000000000
--- a/BDInfo/LanguageCodes.cs
+++ /dev/null
@@ -1,493 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class LanguageCodes
- {
- public static string GetName(string code)
- {
- switch (code)
- {
- case "abk": return "Abkhazian";
- case "ace": return "Achinese";
- case "ach": return "Acoli";
- case "ada": return "Adangme";
- case "aar": return "Afar";
- case "afh": return "Afrihili";
- case "afr": return "Afrikaans";
- case "afa": return "Afro-Asiatic (Other)";
- case "aka": return "Akan";
- case "akk": return "Akkadian";
- case "alb": return "Albanian";
- case "sqi": return "Albanian";
- case "ale": return "Aleut";
- case "alg": return "Algonquian languages";
- case "tut": return "Altaic (Other)";
- case "amh": return "Amharic";
- case "apa": return "Apache languages";
- case "ara": return "Arabic";
- case "arc": return "Aramaic";
- case "arp": return "Arapaho";
- case "arn": return "Araucanian";
- case "arw": return "Arawak";
- case "arm": return "Armenian";
- case "hye": return "Armenian";
- case "art": return "Artificial (Other)";
- case "asm": return "Assamese";
- case "ath": return "Athapascan languages";
- case "aus": return "Australian languages";
- case "map": return "Austronesian (Other)";
- case "ava": return "Avaric";
- case "ave": return "Avestan";
- case "awa": return "Awadhi";
- case "aym": return "Aymara";
- case "aze": return "Azerbaijani";
- case "ban": return "Balinese";
- case "bat": return "Baltic (Other)";
- case "bal": return "Baluchi";
- case "bam": return "Bambara";
- case "bai": return "Bamileke languages";
- case "bad": return "Banda";
- case "bnt": return "Bantu (Other)";
- case "bas": return "Basa";
- case "bak": return "Bashkir";
- case "baq": return "Basque";
- case "eus": return "Basque";
- case "btk": return "Batak (Indonesia)";
- case "bej": return "Beja";
- case "bel": return "Belarusian";
- case "bem": return "Bemba";
- case "ben": return "Bengali";
- case "ber": return "Berber (Other)";
- case "bho": return "Bhojpuri";
- case "bih": return "Bihari";
- case "bik": return "Bikol";
- case "bin": return "Bini";
- case "bis": return "Bislama";
- case "bos": return "Bosnian";
- case "bra": return "Braj";
- case "bre": return "Breton";
- case "bug": return "Buginese";
- case "bul": return "Bulgarian";
- case "bua": return "Buriat";
- case "bur": return "Burmese";
- case "mya": return "Burmese";
- case "cad": return "Caddo";
- case "car": return "Carib";
- case "cat": return "Catalan";
- case "cau": return "Caucasian (Other)";
- case "ceb": return "Cebuano";
- case "cel": return "Celtic (Other)";
- case "cai": return "Central American Indian (Other)";
- case "chg": return "Chagatai";
- case "cmc": return "Chamic languages";
- case "cha": return "Chamorro";
- case "che": return "Chechen";
- case "chr": return "Cherokee";
- case "chy": return "Cheyenne";
- case "chb": return "Chibcha";
- case "chi": return "Chinese";
- case "zho": return "Chinese";
- case "chn": return "Chinook jargon";
- case "chp": return "Chipewyan";
- case "cho": return "Choctaw";
- case "chu": return "Church Slavic";
- case "chk": return "Chuukese";
- case "chv": return "Chuvash";
- case "cop": return "Coptic";
- case "cor": return "Cornish";
- case "cos": return "Corsican";
- case "cre": return "Cree";
- case "mus": return "Creek";
- case "crp": return "Creoles and pidgins (Other)";
- case "cpe": return "Creoles and pidgins,";
- case "cpf": return "Creoles and pidgins,";
- case "cpp": return "Creoles and pidgins,";
- case "scr": return "Croatian";
- case "hrv": return "Croatian";
- case "cus": return "Cushitic (Other)";
- case "cze": return "Czech";
- case "ces": return "Czech";
- case "dak": return "Dakota";
- case "dan": return "Danish";
- case "day": return "Dayak";
- case "del": return "Delaware";
- case "din": return "Dinka";
- case "div": return "Divehi";
- case "doi": return "Dogri";
- case "dgr": return "Dogrib";
- case "dra": return "Dravidian (Other)";
- case "dua": return "Duala";
- case "dut": return "Dutch";
- case "nld": return "Dutch";
- case "dum": return "Dutch, Middle (ca. 1050-1350)";
- case "dyu": return "Dyula";
- case "dzo": return "Dzongkha";
- case "efi": return "Efik";
- case "egy": return "Egyptian (Ancient)";
- case "eka": return "Ekajuk";
- case "elx": return "Elamite";
- case "eng": return "English";
- case "enm": return "English, Middle (1100-1500)";
- case "ang": return "English, Old (ca.450-1100)";
- case "epo": return "Esperanto";
- case "est": return "Estonian";
- case "ewe": return "Ewe";
- case "ewo": return "Ewondo";
- case "fan": return "Fang";
- case "fat": return "Fanti";
- case "fao": return "Faroese";
- case "fij": return "Fijian";
- case "fin": return "Finnish";
- case "fiu": return "Finno-Ugrian (Other)";
- case "fon": return "Fon";
- case "fre": return "French";
- case "fra": return "French";
- case "frm": return "French, Middle (ca.1400-1600)";
- case "fro": return "French, Old (842-ca.1400)";
- case "fry": return "Frisian";
- case "fur": return "Friulian";
- case "ful": return "Fulah";
- case "gaa": return "Ga";
- case "glg": return "Gallegan";
- case "lug": return "Ganda";
- case "gay": return "Gayo";
- case "gba": return "Gbaya";
- case "gez": return "Geez";
- case "geo": return "Georgian";
- case "kat": return "Georgian";
- case "ger": return "German";
- case "deu": return "German";
- case "nds": return "Saxon";
- case "gmh": return "German, Middle High (ca.1050-1500)";
- case "goh": return "German, Old High (ca.750-1050)";
- case "gem": return "Germanic (Other)";
- case "gil": return "Gilbertese";
- case "gon": return "Gondi";
- case "gor": return "Gorontalo";
- case "got": return "Gothic";
- case "grb": return "Grebo";
- case "grc": return "Greek, Ancient (to 1453)";
- case "gre": return "Greek";
- case "ell": return "Greek";
- case "grn": return "Guarani";
- case "guj": return "Gujarati";
- case "gwi": return "Gwich´in";
- case "hai": return "Haida";
- case "hau": return "Hausa";
- case "haw": return "Hawaiian";
- case "heb": return "Hebrew";
- case "her": return "Herero";
- case "hil": return "Hiligaynon";
- case "him": return "Himachali";
- case "hin": return "Hindi";
- case "hmo": return "Hiri Motu";
- case "hit": return "Hittite";
- case "hmn": return "Hmong";
- case "hun": return "Hungarian";
- case "hup": return "Hupa";
- case "iba": return "Iban";
- case "ice": return "Icelandic";
- case "isl": return "Icelandic";
- case "ibo": return "Igbo";
- case "ijo": return "Ijo";
- case "ilo": return "Iloko";
- case "inc": return "Indic (Other)";
- case "ine": return "Indo-European (Other)";
- case "ind": return "Indonesian";
- case "ina": return "Interlingua (International";
- case "ile": return "Interlingue";
- case "iku": return "Inuktitut";
- case "ipk": return "Inupiaq";
- case "ira": return "Iranian (Other)";
- case "gle": return "Irish";
- case "mga": return "Irish, Middle (900-1200)";
- case "sga": return "Irish, Old (to 900)";
- case "iro": return "Iroquoian languages";
- case "ita": return "Italian";
- case "jpn": return "Japanese";
- case "jav": return "Javanese";
- case "jrb": return "Judeo-Arabic";
- case "jpr": return "Judeo-Persian";
- case "kab": return "Kabyle";
- case "kac": return "Kachin";
- case "kal": return "Kalaallisut";
- case "kam": return "Kamba";
- case "kan": return "Kannada";
- case "kau": return "Kanuri";
- case "kaa": return "Kara-Kalpak";
- case "kar": return "Karen";
- case "kas": return "Kashmiri";
- case "kaw": return "Kawi";
- case "kaz": return "Kazakh";
- case "kha": return "Khasi";
- case "khm": return "Khmer";
- case "khi": return "Khoisan (Other)";
- case "kho": return "Khotanese";
- case "kik": return "Kikuyu";
- case "kmb": return "Kimbundu";
- case "kin": return "Kinyarwanda";
- case "kir": return "Kirghiz";
- case "kom": return "Komi";
- case "kon": return "Kongo";
- case "kok": return "Konkani";
- case "kor": return "Korean";
- case "kos": return "Kosraean";
- case "kpe": return "Kpelle";
- case "kro": return "Kru";
- case "kua": return "Kuanyama";
- case "kum": return "Kumyk";
- case "kur": return "Kurdish";
- case "kru": return "Kurukh";
- case "kut": return "Kutenai";
- case "lad": return "Ladino";
- case "lah": return "Lahnda";
- case "lam": return "Lamba";
- case "lao": return "Lao";
- case "lat": return "Latin";
- case "lav": return "Latvian";
- case "ltz": return "Letzeburgesch";
- case "lez": return "Lezghian";
- case "lin": return "Lingala";
- case "lit": return "Lithuanian";
- case "loz": return "Lozi";
- case "lub": return "Luba-Katanga";
- case "lua": return "Luba-Lulua";
- case "lui": return "Luiseno";
- case "lun": return "Lunda";
- case "luo": return "Luo (Kenya and Tanzania)";
- case "lus": return "Lushai";
- case "mac": return "Macedonian";
- case "mkd": return "Macedonian";
- case "mad": return "Madurese";
- case "mag": return "Magahi";
- case "mai": return "Maithili";
- case "mak": return "Makasar";
- case "mlg": return "Malagasy";
- case "may": return "Malay";
- case "msa": return "Malay";
- case "mal": return "Malayalam";
- case "mlt": return "Maltese";
- case "mnc": return "Manchu";
- case "mdr": return "Mandar";
- case "man": return "Mandingo";
- case "mni": return "Manipuri";
- case "mno": return "Manobo languages";
- case "glv": return "Manx";
- case "mao": return "Maori";
- case "mri": return "Maori";
- case "mar": return "Marathi";
- case "chm": return "Mari";
- case "mah": return "Marshall";
- case "mwr": return "Marwari";
- case "mas": return "Masai";
- case "myn": return "Mayan languages";
- case "men": return "Mende";
- case "mic": return "Micmac";
- case "min": return "Minangkabau";
- case "mis": return "Miscellaneous languages";
- case "moh": return "Mohawk";
- case "mol": return "Moldavian";
- case "mkh": return "Mon-Khmer (Other)";
- case "lol": return "Mongo";
- case "mon": return "Mongolian";
- case "mos": return "Mossi";
- case "mul": return "Multiple languages";
- case "mun": return "Munda languages";
- case "nah": return "Nahuatl";
- case "nau": return "Nauru";
- case "nav": return "Navajo";
- case "nde": return "Ndebele, North";
- case "nbl": return "Ndebele, South";
- case "ndo": return "Ndonga";
- case "nep": return "Nepali";
- case "new": return "Newari";
- case "nia": return "Nias";
- case "nic": return "Niger-Kordofanian (Other)";
- case "ssa": return "Nilo-Saharan (Other)";
- case "niu": return "Niuean";
- case "non": return "Norse, Old";
- case "nai": return "North American Indian (Other)";
- case "sme": return "Northern Sami";
- case "nor": return "Norwegian";
- case "nob": return "Norwegian Bokmål";
- case "nno": return "Norwegian Nynorsk";
- case "nub": return "Nubian languages";
- case "nym": return "Nyamwezi";
- case "nya": return "Nyanja";
- case "nyn": return "Nyankole";
- case "nyo": return "Nyoro";
- case "nzi": return "Nzima";
- case "oci": return "Occitan";
- case "oji": return "Ojibwa";
- case "ori": return "Oriya";
- case "orm": return "Oromo";
- case "osa": return "Osage";
- case "oss": return "Ossetian";
- case "oto": return "Otomian languages";
- case "pal": return "Pahlavi";
- case "pau": return "Palauan";
- case "pli": return "Pali";
- case "pam": return "Pampanga";
- case "pag": return "Pangasinan";
- case "pan": return "Panjabi";
- case "pap": return "Papiamento";
- case "paa": return "Papuan (Other)";
- case "per": return "Persian";
- case "fas": return "Persian";
- case "peo": return "Persian, Old (ca.600-400 B.C.)";
- case "phi": return "Philippine (Other)";
- case "phn": return "Phoenician";
- case "pon": return "Pohnpeian";
- case "pol": return "Polish";
- case "por": return "Portuguese";
- case "pra": return "Prakrit languages";
- case "pro": return "Provençal";
- case "pus": return "Pushto";
- case "que": return "Quechua";
- case "roh": return "Raeto-Romance";
- case "raj": return "Rajasthani";
- case "rap": return "Rapanui";
- case "rar": return "Rarotongan";
- case "roa": return "Romance (Other)";
- case "rum": return "Romanian";
- case "ron": return "Romanian";
- case "rom": return "Romany";
- case "run": return "Rundi";
- case "rus": return "Russian";
- case "sal": return "Salishan languages";
- case "sam": return "Samaritan Aramaic";
- case "smi": return "Sami languages (Other)";
- case "smo": return "Samoan";
- case "sad": return "Sandawe";
- case "sag": return "Sango";
- case "san": return "Sanskrit";
- case "sat": return "Santali";
- case "srd": return "Sardinian";
- case "sas": return "Sasak";
- case "sco": return "Scots";
- case "gla": return "Gaelic";
- case "sel": return "Selkup";
- case "sem": return "Semitic (Other)";
- case "scc": return "Serbian";
- case "srp": return "Serbian";
- case "srr": return "Serer";
- case "shn": return "Shan";
- case "sna": return "Shona";
- case "sid": return "Sidamo";
- case "sgn": return "Sign languages";
- case "bla": return "Siksika";
- case "snd": return "Sindhi";
- case "sin": return "Sinhalese";
- case "sit": return "Sino-Tibetan (Other)";
- case "sio": return "Siouan languages";
- case "den": return "Slave (Athapascan)";
- case "sla": return "Slavic (Other)";
- case "slo": return "Slovak";
- case "slk": return "Slovak";
- case "slv": return "Slovenian";
- case "sog": return "Sogdian";
- case "som": return "Somali";
- case "son": return "Songhai";
- case "snk": return "Soninke";
- case "wen": return "Sorbian languages";
- case "nso": return "Sotho, Northern";
- case "sot": return "Sotho, Southern";
- case "sai": return "South American Indian (Other)";
- case "spa": return "Spanish";
- case "suk": return "Sukuma";
- case "sux": return "Sumerian";
- case "sun": return "Sundanese";
- case "sus": return "Susu";
- case "swa": return "Swahili";
- case "ssw": return "Swati";
- case "swe": return "Swedish";
- case "syr": return "Syriac";
- case "tgl": return "Tagalog";
- case "tah": return "Tahitian";
- case "tai": return "Tai (Other)";
- case "tgk": return "Tajik";
- case "tmh": return "Tamashek";
- case "tam": return "Tamil";
- case "tat": return "Tatar";
- case "tel": return "Telugu";
- case "ter": return "Tereno";
- case "tet": return "Tetum";
- case "tha": return "Thai";
- case "tib": return "Tibetan";
- case "bod": return "Tibetan";
- case "tig": return "Tigre";
- case "tir": return "Tigrinya";
- case "tem": return "Timne";
- case "tiv": return "Tiv";
- case "tli": return "Tlingit";
- case "tpi": return "Tok Pisin";
- case "tkl": return "Tokelau";
- case "tog": return "Tonga (Nyasa)";
- case "ton": return "Tonga (Tonga Islands)";
- case "tsi": return "Tsimshian";
- case "tso": return "Tsonga";
- case "tsn": return "Tswana";
- case "tum": return "Tumbuka";
- case "tur": return "Turkish";
- case "ota": return "Turkish, Ottoman (1500-1928)";
- case "tuk": return "Turkmen";
- case "tvl": return "Tuvalu";
- case "tyv": return "Tuvinian";
- case "twi": return "Twi";
- case "uga": return "Ugaritic";
- case "uig": return "Uighur";
- case "ukr": return "Ukrainian";
- case "umb": return "Umbundu";
- case "und": return "Undetermined";
- case "urd": return "Urdu";
- case "uzb": return "Uzbek";
- case "vai": return "Vai";
- case "ven": return "Venda";
- case "vie": return "Vietnamese";
- case "vol": return "Volapük";
- case "vot": return "Votic";
- case "wak": return "Wakashan languages";
- case "wal": return "Walamo";
- case "war": return "Waray";
- case "was": return "Washo";
- case "wel": return "Welsh";
- case "cym": return "Welsh";
- case "wol": return "Wolof";
- case "xho": return "Xhosa";
- case "sah": return "Yakut";
- case "yao": return "Yao";
- case "yap": return "Yapese";
- case "yid": return "Yiddish";
- case "yor": return "Yoruba";
- case "ypk": return "Yupik languages";
- case "znd": return "Zande";
- case "zap": return "Zapotec";
- case "zen": return "Zenaga";
- case "zha": return "Zhuang";
- case "zul": return "Zulu";
- case "zun": return "Zuni";
-
- default: return code;
- }
- }
- }
-}
diff --git a/BDInfo/Properties/AssemblyInfo.cs b/BDInfo/Properties/AssemblyInfo.cs
deleted file mode 100644
index f65c7036a4..0000000000
--- a/BDInfo/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Reflection;
-using System.Resources;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("BDInfo")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Jellyfin Project")]
-[assembly: AssemblyProduct("Jellyfin Server")]
-[assembly: AssemblyCopyright("Copyright © 2016 CinemaSquid. Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: NeutralResourcesLanguage("en")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
diff --git a/BDInfo/ReadMe.txt b/BDInfo/ReadMe.txt
deleted file mode 100644
index e70b0b66cd..0000000000
--- a/BDInfo/ReadMe.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-The source is taken from the BDRom folder of this project:
-
-http://www.cinemasquid.com/blu-ray/tools/bdinfo
-
-BDInfoSettings was taken from the FormSettings class, and changed so that the settings all return defaults.
diff --git a/BDInfo/TSCodecAC3.cs b/BDInfo/TSCodecAC3.cs
deleted file mode 100644
index 35d306a19d..0000000000
--- a/BDInfo/TSCodecAC3.cs
+++ /dev/null
@@ -1,309 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-#undef DEBUG
-using System.IO;
-
-namespace BDInfo
-{
- public abstract class TSCodecAC3
- {
- private static byte[] eac3_blocks = new byte[] { 1, 2, 3, 6 };
-
- public static void Scan(
- TSAudioStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- if (stream.IsInitialized) return;
-
- byte[] sync = buffer.ReadBytes(2);
- if (sync == null ||
- sync[0] != 0x0B ||
- sync[1] != 0x77)
- {
- return;
- }
-
- int sr_code = 0;
- int frame_size = 0;
- int frame_size_code = 0;
- int channel_mode = 0;
- int lfe_on = 0;
- int dial_norm = 0;
- int num_blocks = 0;
-
- byte[] hdr = buffer.ReadBytes(4);
- int bsid = (hdr[3] & 0xF8) >> 3;
- buffer.Seek(-4, SeekOrigin.Current);
- if (bsid <= 10)
- {
- byte[] crc = buffer.ReadBytes(2);
- sr_code = buffer.ReadBits(2);
- frame_size_code = buffer.ReadBits(6);
- bsid = buffer.ReadBits(5);
- int bsmod = buffer.ReadBits(3);
-
- channel_mode = buffer.ReadBits(3);
- int cmixlev = 0;
- if (((channel_mode & 0x1) > 0) && (channel_mode != 0x1))
- {
- cmixlev = buffer.ReadBits(2);
- }
- int surmixlev = 0;
- if ((channel_mode & 0x4) > 0)
- {
- surmixlev = buffer.ReadBits(2);
- }
- int dsurmod = 0;
- if (channel_mode == 0x2)
- {
- dsurmod = buffer.ReadBits(2);
- if (dsurmod == 0x2)
- {
- stream.AudioMode = TSAudioMode.Surround;
- }
- }
- lfe_on = buffer.ReadBits(1);
- dial_norm = buffer.ReadBits(5);
- int compr = 0;
- if (1 == buffer.ReadBits(1))
- {
- compr = buffer.ReadBits(8);
- }
- int langcod = 0;
- if (1 == buffer.ReadBits(1))
- {
- langcod = buffer.ReadBits(8);
- }
- int mixlevel = 0;
- int roomtyp = 0;
- if (1 == buffer.ReadBits(1))
- {
- mixlevel = buffer.ReadBits(5);
- roomtyp = buffer.ReadBits(2);
- }
- if (channel_mode == 0)
- {
- int dialnorm2 = buffer.ReadBits(5);
- int compr2 = 0;
- if (1 == buffer.ReadBits(1))
- {
- compr2 = buffer.ReadBits(8);
- }
- int langcod2 = 0;
- if (1 == buffer.ReadBits(1))
- {
- langcod2 = buffer.ReadBits(8);
- }
- int mixlevel2 = 0;
- int roomtyp2 = 0;
- if (1 == buffer.ReadBits(1))
- {
- mixlevel2 = buffer.ReadBits(5);
- roomtyp2 = buffer.ReadBits(2);
- }
- }
- int copyrightb = buffer.ReadBits(1);
- int origbs = buffer.ReadBits(1);
- if (bsid == 6)
- {
- if (1 == buffer.ReadBits(1))
- {
- int dmixmod = buffer.ReadBits(2);
- int ltrtcmixlev = buffer.ReadBits(3);
- int ltrtsurmixlev = buffer.ReadBits(3);
- int lorocmixlev = buffer.ReadBits(3);
- int lorosurmixlev = buffer.ReadBits(3);
- }
- if (1 == buffer.ReadBits(1))
- {
- int dsurexmod = buffer.ReadBits(2);
- int dheadphonmod = buffer.ReadBits(2);
- if (dheadphonmod == 0x2)
- {
- // TODO
- }
- int adconvtyp = buffer.ReadBits(1);
- int xbsi2 = buffer.ReadBits(8);
- int encinfo = buffer.ReadBits(1);
- if (dsurexmod == 2)
- {
- stream.AudioMode = TSAudioMode.Extended;
- }
- }
- }
- }
- else
- {
- int frame_type = buffer.ReadBits(2);
- int substreamid = buffer.ReadBits(3);
- frame_size = (buffer.ReadBits(11) + 1) << 1;
-
- sr_code = buffer.ReadBits(2);
- if (sr_code == 3)
- {
- sr_code = buffer.ReadBits(2);
- }
- else
- {
- num_blocks = buffer.ReadBits(2);
- }
- channel_mode = buffer.ReadBits(3);
- lfe_on = buffer.ReadBits(1);
- }
-
- switch (channel_mode)
- {
- case 0: // 1+1
- stream.ChannelCount = 2;
- if (stream.AudioMode == TSAudioMode.Unknown)
- {
- stream.AudioMode = TSAudioMode.DualMono;
- }
- break;
- case 1: // 1/0
- stream.ChannelCount = 1;
- break;
- case 2: // 2/0
- stream.ChannelCount = 2;
- if (stream.AudioMode == TSAudioMode.Unknown)
- {
- stream.AudioMode = TSAudioMode.Stereo;
- }
- break;
- case 3: // 3/0
- stream.ChannelCount = 3;
- break;
- case 4: // 2/1
- stream.ChannelCount = 3;
- break;
- case 5: // 3/1
- stream.ChannelCount = 4;
- break;
- case 6: // 2/2
- stream.ChannelCount = 4;
- break;
- case 7: // 3/2
- stream.ChannelCount = 5;
- break;
- default:
- stream.ChannelCount = 0;
- break;
- }
-
- switch (sr_code)
- {
- case 0:
- stream.SampleRate = 48000;
- break;
- case 1:
- stream.SampleRate = 44100;
- break;
- case 2:
- stream.SampleRate = 32000;
- break;
- default:
- stream.SampleRate = 0;
- break;
- }
-
- if (bsid <= 10)
- {
- switch (frame_size_code >> 1)
- {
- case 18:
- stream.BitRate = 640000;
- break;
- case 17:
- stream.BitRate = 576000;
- break;
- case 16:
- stream.BitRate = 512000;
- break;
- case 15:
- stream.BitRate = 448000;
- break;
- case 14:
- stream.BitRate = 384000;
- break;
- case 13:
- stream.BitRate = 320000;
- break;
- case 12:
- stream.BitRate = 256000;
- break;
- case 11:
- stream.BitRate = 224000;
- break;
- case 10:
- stream.BitRate = 192000;
- break;
- case 9:
- stream.BitRate = 160000;
- break;
- case 8:
- stream.BitRate = 128000;
- break;
- case 7:
- stream.BitRate = 112000;
- break;
- case 6:
- stream.BitRate = 96000;
- break;
- case 5:
- stream.BitRate = 80000;
- break;
- case 4:
- stream.BitRate = 64000;
- break;
- case 3:
- stream.BitRate = 56000;
- break;
- case 2:
- stream.BitRate = 48000;
- break;
- case 1:
- stream.BitRate = 40000;
- break;
- case 0:
- stream.BitRate = 32000;
- break;
- default:
- stream.BitRate = 0;
- break;
- }
- }
- else
- {
- stream.BitRate = (long)
- (4.0 * frame_size * stream.SampleRate / (num_blocks * 256));
- }
-
- stream.LFE = lfe_on;
- if (stream.StreamType != TSStreamType.AC3_PLUS_AUDIO &&
- stream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO)
- {
- stream.DialNorm = dial_norm - 31;
- }
- stream.IsVBR = false;
- stream.IsInitialized = true;
- }
- }
-}
diff --git a/BDInfo/TSCodecAVC.cs b/BDInfo/TSCodecAVC.cs
deleted file mode 100644
index 5833d169f4..0000000000
--- a/BDInfo/TSCodecAVC.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecAVC
- {
- public static void Scan(
- TSVideoStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- uint parse = 0;
- byte accessUnitDelimiterParse = 0;
- byte sequenceParameterSetParse = 0;
- string profile = null;
- string level = null;
- byte constraintSet0Flag = 0;
- byte constraintSet1Flag = 0;
- byte constraintSet2Flag = 0;
- byte constraintSet3Flag = 0;
-
- for (int i = 0; i < buffer.Length; i++)
- {
- parse = (parse << 8) + buffer.ReadByte();
-
- if (parse == 0x00000109)
- {
- accessUnitDelimiterParse = 1;
- }
- else if (accessUnitDelimiterParse > 0)
- {
- --accessUnitDelimiterParse;
- if (accessUnitDelimiterParse == 0)
- {
- switch ((parse & 0xFF) >> 5)
- {
- case 0: // I
- case 3: // SI
- case 5: // I, SI
- tag = "I";
- break;
-
- case 1: // I, P
- case 4: // SI, SP
- case 6: // I, SI, P, SP
- tag = "P";
- break;
-
- case 2: // I, P, B
- case 7: // I, SI, P, SP, B
- tag = "B";
- break;
- }
- if (stream.IsInitialized) return;
- }
- }
- else if (parse == 0x00000127 || parse == 0x00000167)
- {
- sequenceParameterSetParse = 3;
- }
- else if (sequenceParameterSetParse > 0)
- {
- --sequenceParameterSetParse;
- switch (sequenceParameterSetParse)
- {
- case 2:
- switch (parse & 0xFF)
- {
- case 66:
- profile = "Baseline Profile";
- break;
- case 77:
- profile = "Main Profile";
- break;
- case 88:
- profile = "Extended Profile";
- break;
- case 100:
- profile = "High Profile";
- break;
- case 110:
- profile = "High 10 Profile";
- break;
- case 122:
- profile = "High 4:2:2 Profile";
- break;
- case 144:
- profile = "High 4:4:4 Profile";
- break;
- default:
- profile = "Unknown Profile";
- break;
- }
- break;
-
- case 1:
- constraintSet0Flag = (byte)
- ((parse & 0x80) >> 7);
- constraintSet1Flag = (byte)
- ((parse & 0x40) >> 6);
- constraintSet2Flag = (byte)
- ((parse & 0x20) >> 5);
- constraintSet3Flag = (byte)
- ((parse & 0x10) >> 4);
- break;
-
- case 0:
- byte b = (byte)(parse & 0xFF);
- if (b == 11 && constraintSet3Flag == 1)
- {
- level = "1b";
- }
- else
- {
- level = string.Format(
- "{0:D}.{1:D}",
- b / 10, (b - ((b / 10) * 10)));
- }
- stream.EncodingProfile = string.Format(
- "{0} {1}", profile, level);
- stream.IsVBR = true;
- stream.IsInitialized = true;
- break;
- }
- }
- }
- return;
- }
- }
-}
diff --git a/BDInfo/TSCodecDTS.cs b/BDInfo/TSCodecDTS.cs
deleted file mode 100644
index ff94cb7022..0000000000
--- a/BDInfo/TSCodecDTS.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecDTS
- {
- private static int[] dca_sample_rates =
- {
- 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
- 12000, 24000, 48000, 96000, 192000
- };
-
- private static int[] dca_bit_rates =
- {
- 32000, 56000, 64000, 96000, 112000, 128000,
- 192000, 224000, 256000, 320000, 384000,
- 448000, 512000, 576000, 640000, 768000,
- 896000, 1024000, 1152000, 1280000, 1344000,
- 1408000, 1411200, 1472000, 1509000, 1920000,
- 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
- };
-
- private static int[] dca_channels =
- {
- 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8
- };
-
- private static int[] dca_bits_per_sample =
- {
- 16, 16, 20, 20, 0, 24, 24
- };
-
- public static void Scan(
- TSAudioStream stream,
- TSStreamBuffer buffer,
- long bitrate,
- ref string tag)
- {
- if (stream.IsInitialized) return;
-
- bool syncFound = false;
- uint sync = 0;
- for (int i = 0; i < buffer.Length; i++)
- {
- sync = (sync << 8) + buffer.ReadByte();
- if (sync == 0x7FFE8001)
- {
- syncFound = true;
- break;
- }
- }
- if (!syncFound) return;
-
- int frame_type = buffer.ReadBits(1);
- int samples_deficit = buffer.ReadBits(5);
- int crc_present = buffer.ReadBits(1);
- int sample_blocks = buffer.ReadBits(7);
- int frame_size = buffer.ReadBits(14);
- if (frame_size < 95)
- {
- return;
- }
- int amode = buffer.ReadBits(6);
- int sample_rate = buffer.ReadBits(4);
- if (sample_rate < 0 || sample_rate >= dca_sample_rates.Length)
- {
- return;
- }
- int bit_rate = buffer.ReadBits(5);
- if (bit_rate < 0 || bit_rate >= dca_bit_rates.Length)
- {
- return;
- }
- int downmix = buffer.ReadBits(1);
- int dynrange = buffer.ReadBits(1);
- int timestamp = buffer.ReadBits(1);
- int aux_data = buffer.ReadBits(1);
- int hdcd = buffer.ReadBits(1);
- int ext_descr = buffer.ReadBits(3);
- int ext_coding = buffer.ReadBits(1);
- int aspf = buffer.ReadBits(1);
- int lfe = buffer.ReadBits(2);
- int predictor_history = buffer.ReadBits(1);
- if (crc_present == 1)
- {
- int crc = buffer.ReadBits(16);
- }
- int multirate_inter = buffer.ReadBits(1);
- int version = buffer.ReadBits(4);
- int copy_history = buffer.ReadBits(2);
- int source_pcm_res = buffer.ReadBits(3);
- int front_sum = buffer.ReadBits(1);
- int surround_sum = buffer.ReadBits(1);
- int dialog_norm = buffer.ReadBits(4);
- if (source_pcm_res < 0 || source_pcm_res >= dca_bits_per_sample.Length)
- {
- return;
- }
- int subframes = buffer.ReadBits(4);
- int total_channels = buffer.ReadBits(3) + 1 + ext_coding;
-
- stream.SampleRate = dca_sample_rates[sample_rate];
- stream.ChannelCount = total_channels;
- stream.LFE = (lfe > 0 ? 1 : 0);
- stream.BitDepth = dca_bits_per_sample[source_pcm_res];
- stream.DialNorm = -dialog_norm;
- if ((source_pcm_res & 0x1) == 0x1)
- {
- stream.AudioMode = TSAudioMode.Extended;
- }
-
- stream.BitRate = (uint)dca_bit_rates[bit_rate];
- switch (stream.BitRate)
- {
- case 1:
- if (bitrate > 0)
- {
- stream.BitRate = bitrate;
- stream.IsVBR = false;
- stream.IsInitialized = true;
- }
- else
- {
- stream.BitRate = 0;
- }
- break;
-
- case 2:
- case 3:
- stream.IsVBR = true;
- stream.IsInitialized = true;
- break;
-
- default:
- stream.IsVBR = false;
- stream.IsInitialized = true;
- break;
- }
- }
- }
-}
diff --git a/BDInfo/TSCodecDTSHD.cs b/BDInfo/TSCodecDTSHD.cs
deleted file mode 100644
index 57a136d2d5..0000000000
--- a/BDInfo/TSCodecDTSHD.cs
+++ /dev/null
@@ -1,246 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecDTSHD
- {
- private static int[] SampleRates = new int[]
- { 0x1F40, 0x3E80, 0x7D00, 0x0FA00, 0x1F400, 0x5622, 0x0AC44, 0x15888, 0x2B110, 0x56220, 0x2EE0, 0x5DC0, 0x0BB80, 0x17700, 0x2EE00, 0x5DC00 };
-
- public static void Scan(
- TSAudioStream stream,
- TSStreamBuffer buffer,
- long bitrate,
- ref string tag)
- {
- if (stream.IsInitialized &&
- (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO ||
- (stream.CoreStream != null &&
- stream.CoreStream.IsInitialized))) return;
-
- bool syncFound = false;
- uint sync = 0;
- for (int i = 0; i < buffer.Length; i++)
- {
- sync = (sync << 8) + buffer.ReadByte();
- if (sync == 0x64582025)
- {
- syncFound = true;
- break;
- }
- }
-
- if (!syncFound)
- {
- tag = "CORE";
- if (stream.CoreStream == null)
- {
- stream.CoreStream = new TSAudioStream();
- stream.CoreStream.StreamType = TSStreamType.DTS_AUDIO;
- }
- if (!stream.CoreStream.IsInitialized)
- {
- buffer.BeginRead();
- TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag);
- }
- return;
- }
-
- tag = "HD";
- int temp1 = buffer.ReadBits(8);
- int nuSubStreamIndex = buffer.ReadBits(2);
- int nuExtSSHeaderSize = 0;
- int nuExtSSFSize = 0;
- int bBlownUpHeader = buffer.ReadBits(1);
- if (1 == bBlownUpHeader)
- {
- nuExtSSHeaderSize = buffer.ReadBits(12) + 1;
- nuExtSSFSize = buffer.ReadBits(20) + 1;
- }
- else
- {
- nuExtSSHeaderSize = buffer.ReadBits(8) + 1;
- nuExtSSFSize = buffer.ReadBits(16) + 1;
- }
- int nuNumAudioPresent = 1;
- int nuNumAssets = 1;
- int bStaticFieldsPresent = buffer.ReadBits(1);
- if (1 == bStaticFieldsPresent)
- {
- int nuRefClockCode = buffer.ReadBits(2);
- int nuExSSFrameDurationCode = buffer.ReadBits(3) + 1;
- long nuTimeStamp = 0;
- if (1 == buffer.ReadBits(1))
- {
- nuTimeStamp = (buffer.ReadBits(18) << 18) + buffer.ReadBits(18);
- }
- nuNumAudioPresent = buffer.ReadBits(3) + 1;
- nuNumAssets = buffer.ReadBits(3) + 1;
- int[] nuActiveExSSMask = new int[nuNumAudioPresent];
- for (int i = 0; i < nuNumAudioPresent; i++)
- {
- nuActiveExSSMask[i] = buffer.ReadBits(nuSubStreamIndex + 1); //?
- }
- for (int i = 0; i < nuNumAudioPresent; i++)
- {
- for (int j = 0; j < nuSubStreamIndex + 1; j++)
- {
- if (((j + 1) % 2) == 1)
- {
- int mask = buffer.ReadBits(8);
- }
- }
- }
- if (1 == buffer.ReadBits(1))
- {
- int nuMixMetadataAdjLevel = buffer.ReadBits(2);
- int nuBits4MixOutMask = buffer.ReadBits(2) * 4 + 4;
- int nuNumMixOutConfigs = buffer.ReadBits(2) + 1;
- int[] nuMixOutChMask = new int[nuNumMixOutConfigs];
- for (int i = 0; i < nuNumMixOutConfigs; i++)
- {
- nuMixOutChMask[i] = buffer.ReadBits(nuBits4MixOutMask);
- }
- }
- }
- int[] AssetSizes = new int[nuNumAssets];
- for (int i = 0; i < nuNumAssets; i++)
- {
- if (1 == bBlownUpHeader)
- {
- AssetSizes[i] = buffer.ReadBits(20) + 1;
- }
- else
- {
- AssetSizes[i] = buffer.ReadBits(16) + 1;
- }
- }
- for (int i = 0; i < nuNumAssets; i++)
- {
- long bufferPosition = buffer.Position;
- int nuAssetDescriptorFSIZE = buffer.ReadBits(9) + 1;
- int DescriptorDataForAssetIndex = buffer.ReadBits(3);
- if (1 == bStaticFieldsPresent)
- {
- int AssetTypeDescrPresent = buffer.ReadBits(1);
- if (1 == AssetTypeDescrPresent)
- {
- int AssetTypeDescriptor = buffer.ReadBits(4);
- }
- int LanguageDescrPresent = buffer.ReadBits(1);
- if (1 == LanguageDescrPresent)
- {
- int LanguageDescriptor = buffer.ReadBits(24);
- }
- int bInfoTextPresent = buffer.ReadBits(1);
- if (1 == bInfoTextPresent)
- {
- int nuInfoTextByteSize = buffer.ReadBits(10) + 1;
- int[] InfoText = new int[nuInfoTextByteSize];
- for (int j = 0; j < nuInfoTextByteSize; j++)
- {
- InfoText[j] = buffer.ReadBits(8);
- }
- }
- int nuBitResolution = buffer.ReadBits(5) + 1;
- int nuMaxSampleRate = buffer.ReadBits(4);
- int nuTotalNumChs = buffer.ReadBits(8) + 1;
- int bOne2OneMapChannels2Speakers = buffer.ReadBits(1);
- int nuSpkrActivityMask = 0;
- if (1 == bOne2OneMapChannels2Speakers)
- {
- int bEmbeddedStereoFlag = 0;
- if (nuTotalNumChs > 2)
- {
- bEmbeddedStereoFlag = buffer.ReadBits(1);
- }
- int bEmbeddedSixChFlag = 0;
- if (nuTotalNumChs > 6)
- {
- bEmbeddedSixChFlag = buffer.ReadBits(1);
- }
- int bSpkrMaskEnabled = buffer.ReadBits(1);
- int nuNumBits4SAMask = 0;
- if (1 == bSpkrMaskEnabled)
- {
- nuNumBits4SAMask = buffer.ReadBits(2);
- nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4;
- nuSpkrActivityMask = buffer.ReadBits(nuNumBits4SAMask);
- }
- // TODO...
- }
- stream.SampleRate = SampleRates[nuMaxSampleRate];
- stream.BitDepth = nuBitResolution;
-
- stream.LFE = 0;
- if ((nuSpkrActivityMask & 0x8) == 0x8)
- {
- ++stream.LFE;
- }
- if ((nuSpkrActivityMask & 0x1000) == 0x1000)
- {
- ++stream.LFE;
- }
- stream.ChannelCount = nuTotalNumChs - stream.LFE;
- }
- if (nuNumAssets > 1)
- {
- // TODO...
- break;
- }
- }
-
- // TODO
- if (stream.CoreStream != null)
- {
- var coreStream = (TSAudioStream)stream.CoreStream;
- if (coreStream.AudioMode == TSAudioMode.Extended &&
- stream.ChannelCount == 5)
- {
- stream.AudioMode = TSAudioMode.Extended;
- }
- /*
- if (coreStream.DialNorm != 0)
- {
- stream.DialNorm = coreStream.DialNorm;
- }
- */
- }
-
- if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO)
- {
- stream.IsVBR = true;
- stream.IsInitialized = true;
- }
- else if (bitrate > 0)
- {
- stream.IsVBR = false;
- stream.BitRate = bitrate;
- if (stream.CoreStream != null)
- {
- stream.BitRate += stream.CoreStream.BitRate;
- stream.IsInitialized = true;
- }
- stream.IsInitialized = (stream.BitRate > 0 ? true : false);
- }
- }
- }
-}
diff --git a/BDInfo/TSCodecLPCM.cs b/BDInfo/TSCodecLPCM.cs
deleted file mode 100644
index 5709d8689f..0000000000
--- a/BDInfo/TSCodecLPCM.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecLPCM
- {
- public static void Scan(
- TSAudioStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- if (stream.IsInitialized) return;
-
- byte[] header = buffer.ReadBytes(4);
- int flags = (header[2] << 8) + header[3];
-
- switch ((flags & 0xF000) >> 12)
- {
- case 1: // 1/0/0
- stream.ChannelCount = 1;
- stream.LFE = 0;
- break;
- case 3: // 2/0/0
- stream.ChannelCount = 2;
- stream.LFE = 0;
- break;
- case 4: // 3/0/0
- stream.ChannelCount = 3;
- stream.LFE = 0;
- break;
- case 5: // 2/1/0
- stream.ChannelCount = 3;
- stream.LFE = 0;
- break;
- case 6: // 3/1/0
- stream.ChannelCount = 4;
- stream.LFE = 0;
- break;
- case 7: // 2/2/0
- stream.ChannelCount = 4;
- stream.LFE = 0;
- break;
- case 8: // 3/2/0
- stream.ChannelCount = 5;
- stream.LFE = 0;
- break;
- case 9: // 3/2/1
- stream.ChannelCount = 5;
- stream.LFE = 1;
- break;
- case 10: // 3/4/0
- stream.ChannelCount = 7;
- stream.LFE = 0;
- break;
- case 11: // 3/4/1
- stream.ChannelCount = 7;
- stream.LFE = 1;
- break;
- default:
- stream.ChannelCount = 0;
- stream.LFE = 0;
- break;
- }
-
- switch ((flags & 0xC0) >> 6)
- {
- case 1:
- stream.BitDepth = 16;
- break;
- case 2:
- stream.BitDepth = 20;
- break;
- case 3:
- stream.BitDepth = 24;
- break;
- default:
- stream.BitDepth = 0;
- break;
- }
-
- switch ((flags & 0xF00) >> 8)
- {
- case 1:
- stream.SampleRate = 48000;
- break;
- case 4:
- stream.SampleRate = 96000;
- break;
- case 5:
- stream.SampleRate = 192000;
- break;
- default:
- stream.SampleRate = 0;
- break;
- }
-
- stream.BitRate = (uint)
- (stream.SampleRate * stream.BitDepth *
- (stream.ChannelCount + stream.LFE));
-
- stream.IsVBR = false;
- stream.IsInitialized = true;
- }
- }
-}
diff --git a/BDInfo/TSCodecMPEG2.cs b/BDInfo/TSCodecMPEG2.cs
deleted file mode 100644
index 8bcd07d020..0000000000
--- a/BDInfo/TSCodecMPEG2.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-#undef DEBUG
-
-
-namespace BDInfo
-{
- public abstract class TSCodecMPEG2
- {
- public static void Scan(
- TSVideoStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- int parse = 0;
- int pictureParse = 0;
- int sequenceHeaderParse = 0;
- int extensionParse = 0;
- int sequenceExtensionParse = 0;
-
- for (int i = 0; i < buffer.Length; i++)
- {
- parse = (parse << 8) + buffer.ReadByte();
-
- if (parse == 0x00000100)
- {
- pictureParse = 2;
- }
- else if (parse == 0x000001B3)
- {
- sequenceHeaderParse = 7;
- }
- else if (sequenceHeaderParse > 0)
- {
- --sequenceHeaderParse;
- switch (sequenceHeaderParse)
- {
-#if DEBUG
- case 6:
- break;
-
- case 5:
- break;
-
- case 4:
- stream.Width =
- (int)((parse & 0xFFF000) >> 12);
- stream.Height =
- (int)(parse & 0xFFF);
- break;
-
- case 3:
- stream.AspectRatio =
- (TSAspectRatio)((parse & 0xF0) >> 4);
-
- switch ((parse & 0xF0) >> 4)
- {
- case 0: // Forbidden
- break;
- case 1: // Square
- break;
- case 2: // 4:3
- break;
- case 3: // 16:9
- break;
- case 4: // 2.21:1
- break;
- default: // Reserved
- break;
- }
-
- switch (parse & 0xF)
- {
- case 0: // Forbidden
- break;
- case 1: // 23.976
- stream.FrameRateEnumerator = 24000;
- stream.FrameRateDenominator = 1001;
- break;
- case 2: // 24
- stream.FrameRateEnumerator = 24000;
- stream.FrameRateDenominator = 1000;
- break;
- case 3: // 25
- stream.FrameRateEnumerator = 25000;
- stream.FrameRateDenominator = 1000;
- break;
- case 4: // 29.97
- stream.FrameRateEnumerator = 30000;
- stream.FrameRateDenominator = 1001;
- break;
- case 5: // 30
- stream.FrameRateEnumerator = 30000;
- stream.FrameRateDenominator = 1000;
- break;
- case 6: // 50
- stream.FrameRateEnumerator = 50000;
- stream.FrameRateDenominator = 1000;
- break;
- case 7: // 59.94
- stream.FrameRateEnumerator = 60000;
- stream.FrameRateDenominator = 1001;
- break;
- case 8: // 60
- stream.FrameRateEnumerator = 60000;
- stream.FrameRateDenominator = 1000;
- break;
- default: // Reserved
- stream.FrameRateEnumerator = 0;
- stream.FrameRateDenominator = 0;
- break;
- }
- break;
-
- case 2:
- break;
-
- case 1:
- break;
-#endif
-
- case 0:
-#if DEBUG
- stream.BitRate =
- (((parse & 0xFFFFC0) >> 6) * 200);
-#endif
- stream.IsVBR = true;
- stream.IsInitialized = true;
- break;
- }
- }
- else if (pictureParse > 0)
- {
- --pictureParse;
- if (pictureParse == 0)
- {
- switch ((parse & 0x38) >> 3)
- {
- case 1:
- tag = "I";
- break;
- case 2:
- tag = "P";
- break;
- case 3:
- tag = "B";
- break;
- default:
- break;
- }
- if (stream.IsInitialized) return;
- }
- }
- else if (parse == 0x000001B5)
- {
- extensionParse = 1;
- }
- else if (extensionParse > 0)
- {
- --extensionParse;
- if (extensionParse == 0)
- {
- if ((parse & 0xF0) == 0x10)
- {
- sequenceExtensionParse = 1;
- }
- }
- }
- else if (sequenceExtensionParse > 0)
- {
- --sequenceExtensionParse;
-#if DEBUG
- if (sequenceExtensionParse == 0)
- {
- uint sequenceExtension =
- ((parse & 0x8) >> 3);
- if (sequenceExtension == 0)
- {
- stream.IsInterlaced = true;
- }
- else
- {
- stream.IsInterlaced = false;
- }
- }
-#endif
- }
- }
- }
- }
-}
diff --git a/BDInfo/TSCodecMVC.cs b/BDInfo/TSCodecMVC.cs
deleted file mode 100644
index abff0c1b08..0000000000
--- a/BDInfo/TSCodecMVC.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- // TODO: Do something more interesting here...
-
- public abstract class TSCodecMVC
- {
- public static void Scan(
- TSVideoStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- stream.IsVBR = true;
- stream.IsInitialized = true;
- }
- }
-}
diff --git a/BDInfo/TSCodecTrueHD.cs b/BDInfo/TSCodecTrueHD.cs
deleted file mode 100644
index 5e81e162c5..0000000000
--- a/BDInfo/TSCodecTrueHD.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecTrueHD
- {
- public static void Scan(
- TSAudioStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- if (stream.IsInitialized &&
- stream.CoreStream != null &&
- stream.CoreStream.IsInitialized) return;
-
- bool syncFound = false;
- uint sync = 0;
- for (int i = 0; i < buffer.Length; i++)
- {
- sync = (sync << 8) + buffer.ReadByte();
- if (sync == 0xF8726FBA)
- {
- syncFound = true;
- break;
- }
- }
-
- if (!syncFound)
- {
- tag = "CORE";
- if (stream.CoreStream == null)
- {
- stream.CoreStream = new TSAudioStream();
- stream.CoreStream.StreamType = TSStreamType.AC3_AUDIO;
- }
- if (!stream.CoreStream.IsInitialized)
- {
- buffer.BeginRead();
- TSCodecAC3.Scan(stream.CoreStream, buffer, ref tag);
- }
- return;
- }
-
- tag = "HD";
- int ratebits = buffer.ReadBits(4);
- if (ratebits != 0xF)
- {
- stream.SampleRate =
- (((ratebits & 8) > 0 ? 44100 : 48000) << (ratebits & 7));
- }
- int temp1 = buffer.ReadBits(8);
- int channels_thd_stream1 = buffer.ReadBits(5);
- int temp2 = buffer.ReadBits(2);
-
- stream.ChannelCount = 0;
- stream.LFE = 0;
- int c_LFE2 = buffer.ReadBits(1);
- if (c_LFE2 == 1)
- {
- stream.LFE += 1;
- }
- int c_Cvh = buffer.ReadBits(1);
- if (c_Cvh == 1)
- {
- stream.ChannelCount += 1;
- }
- int c_LRw = buffer.ReadBits(1);
- if (c_LRw == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_LRsd = buffer.ReadBits(1);
- if (c_LRsd == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_Ts = buffer.ReadBits(1);
- if (c_Ts == 1)
- {
- stream.ChannelCount += 1;
- }
- int c_Cs = buffer.ReadBits(1);
- if (c_Cs == 1)
- {
- stream.ChannelCount += 1;
- }
- int c_LRrs = buffer.ReadBits(1);
- if (c_LRrs == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_LRc = buffer.ReadBits(1);
- if (c_LRc == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_LRvh = buffer.ReadBits(1);
- if (c_LRvh == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_LRs = buffer.ReadBits(1);
- if (c_LRs == 1)
- {
- stream.ChannelCount += 2;
- }
- int c_LFE = buffer.ReadBits(1);
- if (c_LFE == 1)
- {
- stream.LFE += 1;
- }
- int c_C = buffer.ReadBits(1);
- if (c_C == 1)
- {
- stream.ChannelCount += 1;
- }
- int c_LR = buffer.ReadBits(1);
- if (c_LR == 1)
- {
- stream.ChannelCount += 2;
- }
-
- int access_unit_size = 40 << (ratebits & 7);
- int access_unit_size_pow2 = 64 << (ratebits & 7);
-
- int a1 = buffer.ReadBits(16);
- int a2 = buffer.ReadBits(16);
- int a3 = buffer.ReadBits(16);
-
- int is_vbr = buffer.ReadBits(1);
- int peak_bitrate = buffer.ReadBits(15);
- peak_bitrate = (peak_bitrate * stream.SampleRate) >> 4;
-
- double peak_bitdepth =
- (double)peak_bitrate /
- (stream.ChannelCount + stream.LFE) /
- stream.SampleRate;
- if (peak_bitdepth > 14)
- {
- stream.BitDepth = 24;
- }
- else
- {
- stream.BitDepth = 16;
- }
-
-#if DEBUG
- System.Diagnostics.Debug.WriteLine(string.Format(
- "{0}\t{1}\t{2:F2}",
- stream.PID, peak_bitrate, peak_bitdepth));
-#endif
- /*
- // TODO: Get THD dialnorm from metadata
- if (stream.CoreStream != null)
- {
- TSAudioStream coreStream = (TSAudioStream)stream.CoreStream;
- if (coreStream.DialNorm != 0)
- {
- stream.DialNorm = coreStream.DialNorm;
- }
- }
- */
-
- stream.IsVBR = true;
- stream.IsInitialized = true;
- }
- }
-}
diff --git a/BDInfo/TSCodecVC1.cs b/BDInfo/TSCodecVC1.cs
deleted file mode 100644
index e2fbbf692f..0000000000
--- a/BDInfo/TSCodecVC1.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-
-namespace BDInfo
-{
- public abstract class TSCodecVC1
- {
- public static void Scan(
- TSVideoStream stream,
- TSStreamBuffer buffer,
- ref string tag)
- {
- int parse = 0;
- byte frameHeaderParse = 0;
- byte sequenceHeaderParse = 0;
- bool isInterlaced = false;
-
- for (int i = 0; i < buffer.Length; i++)
- {
- parse = (parse << 8) + buffer.ReadByte();
-
- if (parse == 0x0000010D)
- {
- frameHeaderParse = 4;
- }
- else if (frameHeaderParse > 0)
- {
- --frameHeaderParse;
- if (frameHeaderParse == 0)
- {
- uint pictureType = 0;
- if (isInterlaced)
- {
- if ((parse & 0x80000000) == 0)
- {
- pictureType =
- (uint)((parse & 0x78000000) >> 13);
- }
- else
- {
- pictureType =
- (uint)((parse & 0x3c000000) >> 12);
- }
- }
- else
- {
- pictureType =
- (uint)((parse & 0xf0000000) >> 14);
- }
-
- if ((pictureType & 0x20000) == 0)
- {
- tag = "P";
- }
- else if ((pictureType & 0x10000) == 0)
- {
- tag = "B";
- }
- else if ((pictureType & 0x8000) == 0)
- {
- tag = "I";
- }
- else if ((pictureType & 0x4000) == 0)
- {
- tag = "BI";
- }
- else
- {
- tag = null;
- }
- if (stream.IsInitialized) return;
- }
- }
- else if (parse == 0x0000010F)
- {
- sequenceHeaderParse = 6;
- }
- else if (sequenceHeaderParse > 0)
- {
- --sequenceHeaderParse;
- switch (sequenceHeaderParse)
- {
- case 5:
- int profileLevel = ((parse & 0x38) >> 3);
- if (((parse & 0xC0) >> 6) == 3)
- {
- stream.EncodingProfile = string.Format(
- "Advanced Profile {0}", profileLevel);
- }
- else
- {
- stream.EncodingProfile = string.Format(
- "Main Profile {0}", profileLevel);
- }
- break;
-
- case 0:
- if (((parse & 0x40) >> 6) > 0)
- {
- isInterlaced = true;
- }
- else
- {
- isInterlaced = false;
- }
- break;
- }
- stream.IsVBR = true;
- stream.IsInitialized = true;
- }
- }
- }
- }
-}
diff --git a/BDInfo/TSInterleavedFile.cs b/BDInfo/TSInterleavedFile.cs
deleted file mode 100644
index 0f35cfb2a1..0000000000
--- a/BDInfo/TSInterleavedFile.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-using MediaBrowser.Model.IO;
-
-// TODO: Do more interesting things here...
-
-namespace BDInfo
-{
- public class TSInterleavedFile
- {
- public FileSystemMetadata FileInfo = null;
- public string Name = null;
-
- public TSInterleavedFile(FileSystemMetadata fileInfo)
- {
- FileInfo = fileInfo;
- Name = fileInfo.Name.ToUpper();
- }
- }
-}
diff --git a/BDInfo/TSPlaylistFile.cs b/BDInfo/TSPlaylistFile.cs
deleted file mode 100644
index 1cc629b1de..0000000000
--- a/BDInfo/TSPlaylistFile.cs
+++ /dev/null
@@ -1,1282 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
- public class TSPlaylistFile
- {
- private FileSystemMetadata FileInfo = null;
- public string FileType = null;
- public bool IsInitialized = false;
- public string Name = null;
- public BDROM BDROM = null;
- public bool HasHiddenTracks = false;
- public bool HasLoops = false;
- public bool IsCustom = false;
-
- public List Chapters = new List();
-
- public Dictionary Streams =
- new Dictionary();
- public Dictionary PlaylistStreams =
- new Dictionary();
- public List StreamClips =
- new List();
- public List> AngleStreams =
- new List>();
- public List> AngleClips =
- new List>();
- public int AngleCount = 0;
-
- public List SortedStreams =
- new List();
- public List VideoStreams =
- new List();
- public List AudioStreams =
- new List();
- public List TextStreams =
- new List();
- public List GraphicsStreams =
- new List();
-
- public TSPlaylistFile(BDROM bdrom,
- FileSystemMetadata fileInfo)
- {
- BDROM = bdrom;
- FileInfo = fileInfo;
- Name = fileInfo.Name.ToUpper();
- }
-
- public TSPlaylistFile(BDROM bdrom,
- string name,
- List clips)
- {
- BDROM = bdrom;
- Name = name;
- IsCustom = true;
- foreach (var clip in clips)
- {
- var newClip = new TSStreamClip(
- clip.StreamFile, clip.StreamClipFile);
-
- newClip.Name = clip.Name;
- newClip.TimeIn = clip.TimeIn;
- newClip.TimeOut = clip.TimeOut;
- newClip.Length = newClip.TimeOut - newClip.TimeIn;
- newClip.RelativeTimeIn = TotalLength;
- newClip.RelativeTimeOut = newClip.RelativeTimeIn + newClip.Length;
- newClip.AngleIndex = clip.AngleIndex;
- newClip.Chapters.Add(clip.TimeIn);
- StreamClips.Add(newClip);
-
- if (newClip.AngleIndex > AngleCount)
- {
- AngleCount = newClip.AngleIndex;
- }
- if (newClip.AngleIndex == 0)
- {
- Chapters.Add(newClip.RelativeTimeIn);
- }
- }
- LoadStreamClips();
- IsInitialized = true;
- }
-
- public override string ToString()
- {
- return Name;
- }
-
- public ulong InterleavedFileSize
- {
- get
- {
- ulong size = 0;
- foreach (var clip in StreamClips)
- {
- size += clip.InterleavedFileSize;
- }
- return size;
- }
- }
- public ulong FileSize
- {
- get
- {
- ulong size = 0;
- foreach (var clip in StreamClips)
- {
- size += clip.FileSize;
- }
- return size;
- }
- }
- public double TotalLength
- {
- get
- {
- double length = 0;
- foreach (var clip in StreamClips)
- {
- if (clip.AngleIndex == 0)
- {
- length += clip.Length;
- }
- }
- return length;
- }
- }
-
- public double TotalAngleLength
- {
- get
- {
- double length = 0;
- foreach (var clip in StreamClips)
- {
- length += clip.Length;
- }
- return length;
- }
- }
-
- public ulong TotalSize
- {
- get
- {
- ulong size = 0;
- foreach (var clip in StreamClips)
- {
- if (clip.AngleIndex == 0)
- {
- size += clip.PacketSize;
- }
- }
- return size;
- }
- }
-
- public ulong TotalAngleSize
- {
- get
- {
- ulong size = 0;
- foreach (var clip in StreamClips)
- {
- size += clip.PacketSize;
- }
- return size;
- }
- }
-
- public ulong TotalBitRate
- {
- get
- {
- if (TotalLength > 0)
- {
- return (ulong)Math.Round(((TotalSize * 8.0) / TotalLength));
- }
- return 0;
- }
- }
-
- public ulong TotalAngleBitRate
- {
- get
- {
- if (TotalAngleLength > 0)
- {
- return (ulong)Math.Round(((TotalAngleSize * 8.0) / TotalAngleLength));
- }
- return 0;
- }
- }
-
- public void Scan(
- Dictionary streamFiles,
- Dictionary streamClipFiles)
- {
- Stream fileStream = null;
- BinaryReader fileReader = null;
-
- try
- {
- Streams.Clear();
- StreamClips.Clear();
-
- fileStream = File.OpenRead(FileInfo.FullName);
- fileReader = new BinaryReader(fileStream);
-
- byte[] data = new byte[fileStream.Length];
- int dataLength = fileReader.Read(data, 0, data.Length);
-
- int pos = 0;
-
- FileType = ReadString(data, 8, ref pos);
- if (FileType != "MPLS0100" && FileType != "MPLS0200")
- {
- throw new Exception(string.Format(
- "Playlist {0} has an unknown file type {1}.",
- FileInfo.Name, FileType));
- }
-
- int playlistOffset = ReadInt32(data, ref pos);
- int chaptersOffset = ReadInt32(data, ref pos);
- int extensionsOffset = ReadInt32(data, ref pos);
-
- pos = playlistOffset;
-
- int playlistLength = ReadInt32(data, ref pos);
- int playlistReserved = ReadInt16(data, ref pos);
- int itemCount = ReadInt16(data, ref pos);
- int subitemCount = ReadInt16(data, ref pos);
-
- var chapterClips = new List();
- for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
- {
- int itemStart = pos;
- int itemLength = ReadInt16(data, ref pos);
- string itemName = ReadString(data, 5, ref pos);
- string itemType = ReadString(data, 4, ref pos);
-
- TSStreamFile streamFile = null;
- string streamFileName = string.Format(
- "{0}.M2TS", itemName);
- if (streamFiles.ContainsKey(streamFileName))
- {
- streamFile = streamFiles[streamFileName];
- }
- if (streamFile == null)
- {
- // Error condition
- }
-
- TSStreamClipFile streamClipFile = null;
- string streamClipFileName = string.Format(
- "{0}.CLPI", itemName);
- if (streamClipFiles.ContainsKey(streamClipFileName))
- {
- streamClipFile = streamClipFiles[streamClipFileName];
- }
- if (streamClipFile == null)
- {
- throw new Exception(string.Format(
- "Playlist {0} referenced missing file {1}.",
- FileInfo.Name, streamFileName));
- }
-
- pos += 1;
- int multiangle = (data[pos] >> 4) & 0x01;
- int condition = data[pos] & 0x0F;
- pos += 2;
-
- int inTime = ReadInt32(data, ref pos);
- if (inTime < 0) inTime &= 0x7FFFFFFF;
- double timeIn = (double)inTime / 45000;
-
- int outTime = ReadInt32(data, ref pos);
- if (outTime < 0) outTime &= 0x7FFFFFFF;
- double timeOut = (double)outTime / 45000;
-
- var streamClip = new TSStreamClip(
- streamFile, streamClipFile);
-
- streamClip.Name = streamFileName; //TODO
- streamClip.TimeIn = timeIn;
- streamClip.TimeOut = timeOut;
- streamClip.Length = streamClip.TimeOut - streamClip.TimeIn;
- streamClip.RelativeTimeIn = TotalLength;
- streamClip.RelativeTimeOut = streamClip.RelativeTimeIn + streamClip.Length;
- StreamClips.Add(streamClip);
- chapterClips.Add(streamClip);
-
- pos += 12;
- if (multiangle > 0)
- {
- int angles = data[pos];
- pos += 2;
- for (int angle = 0; angle < angles - 1; angle++)
- {
- string angleName = ReadString(data, 5, ref pos);
- string angleType = ReadString(data, 4, ref pos);
- pos += 1;
-
- TSStreamFile angleFile = null;
- string angleFileName = string.Format(
- "{0}.M2TS", angleName);
- if (streamFiles.ContainsKey(angleFileName))
- {
- angleFile = streamFiles[angleFileName];
- }
- if (angleFile == null)
- {
- throw new Exception(string.Format(
- "Playlist {0} referenced missing angle file {1}.",
- FileInfo.Name, angleFileName));
- }
-
- TSStreamClipFile angleClipFile = null;
- string angleClipFileName = string.Format(
- "{0}.CLPI", angleName);
- if (streamClipFiles.ContainsKey(angleClipFileName))
- {
- angleClipFile = streamClipFiles[angleClipFileName];
- }
- if (angleClipFile == null)
- {
- throw new Exception(string.Format(
- "Playlist {0} referenced missing angle file {1}.",
- FileInfo.Name, angleClipFileName));
- }
-
- var angleClip =
- new TSStreamClip(angleFile, angleClipFile);
- angleClip.AngleIndex = angle + 1;
- angleClip.TimeIn = streamClip.TimeIn;
- angleClip.TimeOut = streamClip.TimeOut;
- angleClip.RelativeTimeIn = streamClip.RelativeTimeIn;
- angleClip.RelativeTimeOut = streamClip.RelativeTimeOut;
- angleClip.Length = streamClip.Length;
- StreamClips.Add(angleClip);
- }
- if (angles - 1 > AngleCount) AngleCount = angles - 1;
- }
-
- int streamInfoLength = ReadInt16(data, ref pos);
- pos += 2;
- int streamCountVideo = data[pos++];
- int streamCountAudio = data[pos++];
- int streamCountPG = data[pos++];
- int streamCountIG = data[pos++];
- int streamCountSecondaryAudio = data[pos++];
- int streamCountSecondaryVideo = data[pos++];
- int streamCountPIP = data[pos++];
- pos += 5;
-
-#if DEBUG
- Debug.WriteLine(string.Format(
- "{0} : {1} -> V:{2} A:{3} PG:{4} IG:{5} 2A:{6} 2V:{7} PIP:{8}",
- Name, streamFileName, streamCountVideo, streamCountAudio, streamCountPG, streamCountIG,
- streamCountSecondaryAudio, streamCountSecondaryVideo, streamCountPIP));
-#endif
-
- for (int i = 0; i < streamCountVideo; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- }
- for (int i = 0; i < streamCountAudio; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- }
- for (int i = 0; i < streamCountPG; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- }
- for (int i = 0; i < streamCountIG; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- }
- for (int i = 0; i < streamCountSecondaryAudio; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- pos += 2;
- }
- for (int i = 0; i < streamCountSecondaryVideo; i++)
- {
- var stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- pos += 6;
- }
- /*
- * TODO
- *
- for (int i = 0; i < streamCountPIP; i++)
- {
- TSStream stream = CreatePlaylistStream(data, ref pos);
- if (stream != null) PlaylistStreams[stream.PID] = stream;
- }
- */
-
- pos += itemLength - (pos - itemStart) + 2;
- }
-
- pos = chaptersOffset + 4;
-
- int chapterCount = ReadInt16(data, ref pos);
-
- for (int chapterIndex = 0;
- chapterIndex < chapterCount;
- chapterIndex++)
- {
- int chapterType = data[pos + 1];
-
- if (chapterType == 1)
- {
- int streamFileIndex =
- ((int)data[pos + 2] << 8) + data[pos + 3];
-
- long chapterTime =
- ((long)data[pos + 4] << 24) +
- ((long)data[pos + 5] << 16) +
- ((long)data[pos + 6] << 8) +
- ((long)data[pos + 7]);
-
- var streamClip = chapterClips[streamFileIndex];
-
- double chapterSeconds = (double)chapterTime / 45000;
-
- double relativeSeconds =
- chapterSeconds -
- streamClip.TimeIn +
- streamClip.RelativeTimeIn;
-
- // TODO: Ignore short last chapter?
- if (TotalLength - relativeSeconds > 1.0)
- {
- streamClip.Chapters.Add(chapterSeconds);
- this.Chapters.Add(relativeSeconds);
- }
- }
- else
- {
- // TODO: Handle other chapter types?
- }
- pos += 14;
- }
- }
- finally
- {
- if (fileReader != null)
- {
- fileReader.Dispose();
- }
- if (fileStream != null)
- {
- fileStream.Dispose();
- }
- }
- }
-
- public void Initialize()
- {
- LoadStreamClips();
-
- var clipTimes = new Dictionary>();
- foreach (var clip in StreamClips)
- {
- if (clip.AngleIndex == 0)
- {
- if (clipTimes.ContainsKey(clip.Name))
- {
- if (clipTimes[clip.Name].Contains(clip.TimeIn))
- {
- HasLoops = true;
- break;
- }
- else
- {
- clipTimes[clip.Name].Add(clip.TimeIn);
- }
- }
- else
- {
- clipTimes[clip.Name] = new List { clip.TimeIn };
- }
- }
- }
- ClearBitrates();
- IsInitialized = true;
- }
-
- protected TSStream CreatePlaylistStream(byte[] data, ref int pos)
- {
- TSStream stream = null;
-
- int start = pos;
-
- int headerLength = data[pos++];
- int headerPos = pos;
- int headerType = data[pos++];
-
- int pid = 0;
- int subpathid = 0;
- int subclipid = 0;
-
- switch (headerType)
- {
- case 1:
- pid = ReadInt16(data, ref pos);
- break;
- case 2:
- subpathid = data[pos++];
- subclipid = data[pos++];
- pid = ReadInt16(data, ref pos);
- break;
- case 3:
- subpathid = data[pos++];
- pid = ReadInt16(data, ref pos);
- break;
- case 4:
- subpathid = data[pos++];
- subclipid = data[pos++];
- pid = ReadInt16(data, ref pos);
- break;
- default:
- break;
- }
-
- pos = headerPos + headerLength;
-
- int streamLength = data[pos++];
- int streamPos = pos;
-
- var streamType = (TSStreamType)data[pos++];
- switch (streamType)
- {
- case TSStreamType.MVC_VIDEO:
- // TODO
- break;
-
- case TSStreamType.AVC_VIDEO:
- case TSStreamType.MPEG1_VIDEO:
- case TSStreamType.MPEG2_VIDEO:
- case TSStreamType.VC1_VIDEO:
-
- var videoFormat = (TSVideoFormat)
- (data[pos] >> 4);
- var frameRate = (TSFrameRate)
- (data[pos] & 0xF);
- var aspectRatio = (TSAspectRatio)
- (data[pos + 1] >> 4);
-
- stream = new TSVideoStream();
- ((TSVideoStream)stream).VideoFormat = videoFormat;
- ((TSVideoStream)stream).AspectRatio = aspectRatio;
- ((TSVideoStream)stream).FrameRate = frameRate;
-
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2} {3} {4}",
- pid,
- streamType,
- videoFormat,
- frameRate,
- aspectRatio));
-#endif
-
- break;
-
- case TSStreamType.AC3_AUDIO:
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- case TSStreamType.DTS_AUDIO:
- case TSStreamType.DTS_HD_AUDIO:
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- case TSStreamType.LPCM_AUDIO:
- case TSStreamType.MPEG1_AUDIO:
- case TSStreamType.MPEG2_AUDIO:
-
- int audioFormat = ReadByte(data, ref pos);
-
- var channelLayout = (TSChannelLayout)
- (audioFormat >> 4);
- var sampleRate = (TSSampleRate)
- (audioFormat & 0xF);
-
- string audioLanguage = ReadString(data, 3, ref pos);
-
- stream = new TSAudioStream();
- ((TSAudioStream)stream).ChannelLayout = channelLayout;
- ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate);
- ((TSAudioStream)stream).LanguageCode = audioLanguage;
-
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2} {3} {4}",
- pid,
- streamType,
- audioLanguage,
- channelLayout,
- sampleRate));
-#endif
-
- break;
-
- case TSStreamType.INTERACTIVE_GRAPHICS:
- case TSStreamType.PRESENTATION_GRAPHICS:
-
- string graphicsLanguage = ReadString(data, 3, ref pos);
-
- stream = new TSGraphicsStream();
- ((TSGraphicsStream)stream).LanguageCode = graphicsLanguage;
-
- if (data[pos] != 0)
- {
- }
-
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2}",
- pid,
- streamType,
- graphicsLanguage));
-#endif
-
- break;
-
- case TSStreamType.SUBTITLE:
-
- int code = ReadByte(data, ref pos); // TODO
- string textLanguage = ReadString(data, 3, ref pos);
-
- stream = new TSTextStream();
- ((TSTextStream)stream).LanguageCode = textLanguage;
-
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2}",
- pid,
- streamType,
- textLanguage));
-#endif
-
- break;
-
- default:
- break;
- }
-
- pos = streamPos + streamLength;
-
- if (stream != null)
- {
- stream.PID = (ushort)pid;
- stream.StreamType = streamType;
- }
-
- return stream;
- }
-
- private void LoadStreamClips()
- {
- AngleClips.Clear();
- if (AngleCount > 0)
- {
- for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++)
- {
- AngleClips.Add(new Dictionary());
- }
- }
-
- TSStreamClip referenceClip = null;
- if (StreamClips.Count > 0)
- {
- referenceClip = StreamClips[0];
- }
- foreach (var clip in StreamClips)
- {
- if (clip.StreamClipFile.Streams.Count > referenceClip.StreamClipFile.Streams.Count)
- {
- referenceClip = clip;
- }
- else if (clip.Length > referenceClip.Length)
- {
- referenceClip = clip;
- }
- if (AngleCount > 0)
- {
- if (clip.AngleIndex == 0)
- {
- for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++)
- {
- AngleClips[angleIndex][clip.RelativeTimeIn] = clip;
- }
- }
- else
- {
- AngleClips[clip.AngleIndex - 1][clip.RelativeTimeIn] = clip;
- }
- }
- }
-
- foreach (var clipStream
- in referenceClip.StreamClipFile.Streams.Values)
- {
- if (!Streams.ContainsKey(clipStream.PID))
- {
- var stream = clipStream.Clone();
- Streams[clipStream.PID] = stream;
-
- if (!IsCustom && !PlaylistStreams.ContainsKey(stream.PID))
- {
- stream.IsHidden = true;
- HasHiddenTracks = true;
- }
-
- if (stream.IsVideoStream)
- {
- VideoStreams.Add((TSVideoStream)stream);
- }
- else if (stream.IsAudioStream)
- {
- AudioStreams.Add((TSAudioStream)stream);
- }
- else if (stream.IsGraphicsStream)
- {
- GraphicsStreams.Add((TSGraphicsStream)stream);
- }
- else if (stream.IsTextStream)
- {
- TextStreams.Add((TSTextStream)stream);
- }
- }
- }
-
- if (referenceClip.StreamFile != null)
- {
- // TODO: Better way to add this in?
- if (BDInfoSettings.EnableSSIF &&
- referenceClip.StreamFile.InterleavedFile != null &&
- referenceClip.StreamFile.Streams.ContainsKey(4114) &&
- !Streams.ContainsKey(4114))
- {
- var stream = referenceClip.StreamFile.Streams[4114].Clone();
- Streams[4114] = stream;
- if (stream.IsVideoStream)
- {
- VideoStreams.Add((TSVideoStream)stream);
- }
- }
-
- foreach (var clipStream
- in referenceClip.StreamFile.Streams.Values)
- {
- if (Streams.ContainsKey(clipStream.PID))
- {
- var stream = Streams[clipStream.PID];
-
- if (stream.StreamType != clipStream.StreamType) continue;
-
- if (clipStream.BitRate > stream.BitRate)
- {
- stream.BitRate = clipStream.BitRate;
- }
- stream.IsVBR = clipStream.IsVBR;
-
- if (stream.IsVideoStream &&
- clipStream.IsVideoStream)
- {
- ((TSVideoStream)stream).EncodingProfile =
- ((TSVideoStream)clipStream).EncodingProfile;
- }
- else if (stream.IsAudioStream &&
- clipStream.IsAudioStream)
- {
- var audioStream = (TSAudioStream)stream;
- var clipAudioStream = (TSAudioStream)clipStream;
-
- if (clipAudioStream.ChannelCount > audioStream.ChannelCount)
- {
- audioStream.ChannelCount = clipAudioStream.ChannelCount;
- }
- if (clipAudioStream.LFE > audioStream.LFE)
- {
- audioStream.LFE = clipAudioStream.LFE;
- }
- if (clipAudioStream.SampleRate > audioStream.SampleRate)
- {
- audioStream.SampleRate = clipAudioStream.SampleRate;
- }
- if (clipAudioStream.BitDepth > audioStream.BitDepth)
- {
- audioStream.BitDepth = clipAudioStream.BitDepth;
- }
- if (clipAudioStream.DialNorm < audioStream.DialNorm)
- {
- audioStream.DialNorm = clipAudioStream.DialNorm;
- }
- if (clipAudioStream.AudioMode != TSAudioMode.Unknown)
- {
- audioStream.AudioMode = clipAudioStream.AudioMode;
- }
- if (clipAudioStream.CoreStream != null &&
- audioStream.CoreStream == null)
- {
- audioStream.CoreStream = (TSAudioStream)
- clipAudioStream.CoreStream.Clone();
- }
- }
- }
- }
- }
-
- for (int i = 0; i < AngleCount; i++)
- {
- AngleStreams.Add(new Dictionary());
- }
-
- if (!BDInfoSettings.KeepStreamOrder)
- {
- VideoStreams.Sort(CompareVideoStreams);
- }
- foreach (TSStream stream in VideoStreams)
- {
- SortedStreams.Add(stream);
- for (int i = 0; i < AngleCount; i++)
- {
- var angleStream = stream.Clone();
- angleStream.AngleIndex = i + 1;
- AngleStreams[i][angleStream.PID] = angleStream;
- SortedStreams.Add(angleStream);
- }
- }
-
- if (!BDInfoSettings.KeepStreamOrder)
- {
- AudioStreams.Sort(CompareAudioStreams);
- }
- foreach (TSStream stream in AudioStreams)
- {
- SortedStreams.Add(stream);
- }
-
- if (!BDInfoSettings.KeepStreamOrder)
- {
- GraphicsStreams.Sort(CompareGraphicsStreams);
- }
- foreach (TSStream stream in GraphicsStreams)
- {
- SortedStreams.Add(stream);
- }
-
- if (!BDInfoSettings.KeepStreamOrder)
- {
- TextStreams.Sort(CompareTextStreams);
- }
- foreach (TSStream stream in TextStreams)
- {
- SortedStreams.Add(stream);
- }
- }
-
- public void ClearBitrates()
- {
- foreach (var clip in StreamClips)
- {
- clip.PayloadBytes = 0;
- clip.PacketCount = 0;
- clip.PacketSeconds = 0;
-
- if (clip.StreamFile != null)
- {
- foreach (var stream in clip.StreamFile.Streams.Values)
- {
- stream.PayloadBytes = 0;
- stream.PacketCount = 0;
- stream.PacketSeconds = 0;
- }
-
- if (clip.StreamFile != null &&
- clip.StreamFile.StreamDiagnostics != null)
- {
- clip.StreamFile.StreamDiagnostics.Clear();
- }
- }
- }
-
- foreach (var stream in SortedStreams)
- {
- stream.PayloadBytes = 0;
- stream.PacketCount = 0;
- stream.PacketSeconds = 0;
- }
- }
-
- public bool IsValid
- {
- get
- {
- if (!IsInitialized) return false;
-
- if (BDInfoSettings.FilterShortPlaylists &&
- TotalLength < BDInfoSettings.FilterShortPlaylistsValue)
- {
- return false;
- }
-
- if (HasLoops &&
- BDInfoSettings.FilterLoopingPlaylists)
- {
- return false;
- }
-
- return true;
- }
- }
-
- public int CompareVideoStreams(
- TSVideoStream x,
- TSVideoStream y)
- {
- if (x == null && y == null)
- {
- return 0;
- }
- else if (x == null && y != null)
- {
- return 1;
- }
- else if (x != null && y == null)
- {
- return -1;
- }
- else
- {
- if (x.Height > y.Height)
- {
- return -1;
- }
- else if (y.Height > x.Height)
- {
- return 1;
- }
- else if (x.PID > y.PID)
- {
- return 1;
- }
- else if (y.PID > x.PID)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
- }
-
- public int CompareAudioStreams(
- TSAudioStream x,
- TSAudioStream y)
- {
- if (x == y)
- {
- return 0;
- }
- else if (x == null && y == null)
- {
- return 0;
- }
- else if (x == null && y != null)
- {
- return -1;
- }
- else if (x != null && y == null)
- {
- return 1;
- }
- else
- {
- if (x.ChannelCount > y.ChannelCount)
- {
- return -1;
- }
- else if (y.ChannelCount > x.ChannelCount)
- {
- return 1;
- }
- else
- {
- int sortX = GetStreamTypeSortIndex(x.StreamType);
- int sortY = GetStreamTypeSortIndex(y.StreamType);
-
- if (sortX > sortY)
- {
- return -1;
- }
- else if (sortY > sortX)
- {
- return 1;
- }
- else
- {
- if (x.LanguageCode == "eng")
- {
- return -1;
- }
- else if (y.LanguageCode == "eng")
- {
- return 1;
- }
- else if (x.LanguageCode != y.LanguageCode)
- {
- return string.Compare(
- x.LanguageName, y.LanguageName);
- }
- else if (x.PID < y.PID)
- {
- return -1;
- }
- else if (y.PID < x.PID)
- {
- return 1;
- }
- return 0;
- }
- }
- }
- }
-
- public int CompareTextStreams(
- TSTextStream x,
- TSTextStream y)
- {
- if (x == y)
- {
- return 0;
- }
- else if (x == null && y == null)
- {
- return 0;
- }
- else if (x == null && y != null)
- {
- return -1;
- }
- else if (x != null && y == null)
- {
- return 1;
- }
- else
- {
- if (x.LanguageCode == "eng")
- {
- return -1;
- }
- else if (y.LanguageCode == "eng")
- {
- return 1;
- }
- else
- {
- if (x.LanguageCode == y.LanguageCode)
- {
- if (x.PID > y.PID)
- {
- return 1;
- }
- else if (y.PID > x.PID)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return string.Compare(
- x.LanguageName, y.LanguageName);
- }
- }
- }
- }
-
- private int CompareGraphicsStreams(
- TSGraphicsStream x,
- TSGraphicsStream y)
- {
- if (x == y)
- {
- return 0;
- }
- else if (x == null && y == null)
- {
- return 0;
- }
- else if (x == null && y != null)
- {
- return -1;
- }
- else if (x != null && y == null)
- {
- return 1;
- }
- else
- {
- int sortX = GetStreamTypeSortIndex(x.StreamType);
- int sortY = GetStreamTypeSortIndex(y.StreamType);
-
- if (sortX > sortY)
- {
- return -1;
- }
- else if (sortY > sortX)
- {
- return 1;
- }
- else if (x.LanguageCode == "eng")
- {
- return -1;
- }
- else if (y.LanguageCode == "eng")
- {
- return 1;
- }
- else
- {
- if (x.LanguageCode == y.LanguageCode)
- {
- if (x.PID > y.PID)
- {
- return 1;
- }
- else if (y.PID > x.PID)
- {
- return -1;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return string.Compare(x.LanguageName, y.LanguageName);
- }
- }
- }
- }
-
- private int GetStreamTypeSortIndex(TSStreamType streamType)
- {
- switch (streamType)
- {
- case TSStreamType.Unknown:
- return 0;
- case TSStreamType.MPEG1_VIDEO:
- return 1;
- case TSStreamType.MPEG2_VIDEO:
- return 2;
- case TSStreamType.AVC_VIDEO:
- return 3;
- case TSStreamType.VC1_VIDEO:
- return 4;
- case TSStreamType.MVC_VIDEO:
- return 5;
-
- case TSStreamType.MPEG1_AUDIO:
- return 1;
- case TSStreamType.MPEG2_AUDIO:
- return 2;
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- return 3;
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- return 4;
- case TSStreamType.AC3_AUDIO:
- return 5;
- case TSStreamType.DTS_AUDIO:
- return 6;
- case TSStreamType.AC3_PLUS_AUDIO:
- return 7;
- case TSStreamType.DTS_HD_AUDIO:
- return 8;
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- return 9;
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- return 10;
- case TSStreamType.LPCM_AUDIO:
- return 11;
-
- case TSStreamType.SUBTITLE:
- return 1;
- case TSStreamType.INTERACTIVE_GRAPHICS:
- return 2;
- case TSStreamType.PRESENTATION_GRAPHICS:
- return 3;
-
- default:
- return 0;
- }
- }
-
- protected string ReadString(
- byte[] data,
- int count,
- ref int pos)
- {
- string val = Encoding.ASCII.GetString(data, pos, count);
-
- pos += count;
-
- return val;
- }
-
- protected int ReadInt32(
- byte[] data,
- ref int pos)
- {
- int val =
- ((int)data[pos] << 24) +
- ((int)data[pos + 1] << 16) +
- ((int)data[pos + 2] << 8) +
- ((int)data[pos + 3]);
-
- pos += 4;
-
- return val;
- }
-
- protected int ReadInt16(
- byte[] data,
- ref int pos)
- {
- int val =
- ((int)data[pos] << 8) +
- ((int)data[pos + 1]);
-
- pos += 2;
-
- return val;
- }
-
- protected byte ReadByte(
- byte[] data,
- ref int pos)
- {
- return data[pos++];
- }
- }
-}
diff --git a/BDInfo/TSStream.cs b/BDInfo/TSStream.cs
deleted file mode 100644
index 3c30a85971..0000000000
--- a/BDInfo/TSStream.cs
+++ /dev/null
@@ -1,780 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-
-namespace BDInfo
-{
- public enum TSStreamType : byte
- {
- Unknown = 0,
- MPEG1_VIDEO = 0x01,
- MPEG2_VIDEO = 0x02,
- AVC_VIDEO = 0x1b,
- MVC_VIDEO = 0x20,
- VC1_VIDEO = 0xea,
- MPEG1_AUDIO = 0x03,
- MPEG2_AUDIO = 0x04,
- LPCM_AUDIO = 0x80,
- AC3_AUDIO = 0x81,
- AC3_PLUS_AUDIO = 0x84,
- AC3_PLUS_SECONDARY_AUDIO = 0xA1,
- AC3_TRUE_HD_AUDIO = 0x83,
- DTS_AUDIO = 0x82,
- DTS_HD_AUDIO = 0x85,
- DTS_HD_SECONDARY_AUDIO = 0xA2,
- DTS_HD_MASTER_AUDIO = 0x86,
- PRESENTATION_GRAPHICS = 0x90,
- INTERACTIVE_GRAPHICS = 0x91,
- SUBTITLE = 0x92
- }
-
- public enum TSVideoFormat : byte
- {
- Unknown = 0,
- VIDEOFORMAT_480i = 1,
- VIDEOFORMAT_576i = 2,
- VIDEOFORMAT_480p = 3,
- VIDEOFORMAT_1080i = 4,
- VIDEOFORMAT_720p = 5,
- VIDEOFORMAT_1080p = 6,
- VIDEOFORMAT_576p = 7,
- }
-
- public enum TSFrameRate : byte
- {
- Unknown = 0,
- FRAMERATE_23_976 = 1,
- FRAMERATE_24 = 2,
- FRAMERATE_25 = 3,
- FRAMERATE_29_97 = 4,
- FRAMERATE_50 = 6,
- FRAMERATE_59_94 = 7
- }
-
- public enum TSChannelLayout : byte
- {
- Unknown = 0,
- CHANNELLAYOUT_MONO = 1,
- CHANNELLAYOUT_STEREO = 3,
- CHANNELLAYOUT_MULTI = 6,
- CHANNELLAYOUT_COMBO = 12
- }
-
- public enum TSSampleRate : byte
- {
- Unknown = 0,
- SAMPLERATE_48 = 1,
- SAMPLERATE_96 = 4,
- SAMPLERATE_192 = 5,
- SAMPLERATE_48_192 = 12,
- SAMPLERATE_48_96 = 14
- }
-
- public enum TSAspectRatio
- {
- Unknown = 0,
- ASPECT_4_3 = 2,
- ASPECT_16_9 = 3,
- ASPECT_2_21 = 4
- }
-
- public class TSDescriptor
- {
- public byte Name;
- public byte[] Value;
-
- public TSDescriptor(byte name, byte length)
- {
- Name = name;
- Value = new byte[length];
- }
-
- public TSDescriptor Clone()
- {
- var descriptor =
- new TSDescriptor(Name, (byte)Value.Length);
- Value.CopyTo(descriptor.Value, 0);
- return descriptor;
- }
- }
-
- public abstract class TSStream
- {
- public TSStream()
- {
- }
-
- public override string ToString()
- {
- return string.Format("{0} ({1})", CodecShortName, PID);
- }
-
- public ushort PID;
- public TSStreamType StreamType;
- public List Descriptors = null;
- public long BitRate = 0;
- public long ActiveBitRate = 0;
- public bool IsVBR = false;
- public bool IsInitialized = false;
- public string LanguageName;
- public bool IsHidden = false;
-
- public ulong PayloadBytes = 0;
- public ulong PacketCount = 0;
- public double PacketSeconds = 0;
- public int AngleIndex = 0;
-
- public ulong PacketSize => PacketCount * 192;
-
- private string _LanguageCode;
- public string LanguageCode
- {
- get => _LanguageCode;
- set
- {
- _LanguageCode = value;
- LanguageName = LanguageCodes.GetName(value);
- }
- }
-
- public bool IsVideoStream
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.MPEG1_VIDEO:
- case TSStreamType.MPEG2_VIDEO:
- case TSStreamType.AVC_VIDEO:
- case TSStreamType.MVC_VIDEO:
- case TSStreamType.VC1_VIDEO:
- return true;
-
- default:
- return false;
- }
- }
- }
-
- public bool IsAudioStream
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.MPEG1_AUDIO:
- case TSStreamType.MPEG2_AUDIO:
- case TSStreamType.LPCM_AUDIO:
- case TSStreamType.AC3_AUDIO:
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- case TSStreamType.DTS_AUDIO:
- case TSStreamType.DTS_HD_AUDIO:
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- return true;
-
- default:
- return false;
- }
- }
- }
-
- public bool IsGraphicsStream
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.PRESENTATION_GRAPHICS:
- case TSStreamType.INTERACTIVE_GRAPHICS:
- return true;
-
- default:
- return false;
- }
- }
- }
-
- public bool IsTextStream
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.SUBTITLE:
- return true;
-
- default:
- return false;
- }
- }
- }
-
- public string CodecName
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.MPEG1_VIDEO:
- return "MPEG-1 Video";
- case TSStreamType.MPEG2_VIDEO:
- return "MPEG-2 Video";
- case TSStreamType.AVC_VIDEO:
- return "MPEG-4 AVC Video";
- case TSStreamType.MVC_VIDEO:
- return "MPEG-4 MVC Video";
- case TSStreamType.VC1_VIDEO:
- return "VC-1 Video";
- case TSStreamType.MPEG1_AUDIO:
- return "MP1 Audio";
- case TSStreamType.MPEG2_AUDIO:
- return "MP2 Audio";
- case TSStreamType.LPCM_AUDIO:
- return "LPCM Audio";
- case TSStreamType.AC3_AUDIO:
- if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
- return "Dolby Digital EX Audio";
- else
- return "Dolby Digital Audio";
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- return "Dolby Digital Plus Audio";
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- return "Dolby TrueHD Audio";
- case TSStreamType.DTS_AUDIO:
- if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
- return "DTS-ES Audio";
- else
- return "DTS Audio";
- case TSStreamType.DTS_HD_AUDIO:
- return "DTS-HD High-Res Audio";
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- return "DTS Express";
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- return "DTS-HD Master Audio";
- case TSStreamType.PRESENTATION_GRAPHICS:
- return "Presentation Graphics";
- case TSStreamType.INTERACTIVE_GRAPHICS:
- return "Interactive Graphics";
- case TSStreamType.SUBTITLE:
- return "Subtitle";
- default:
- return "UNKNOWN";
- }
- }
- }
-
- public string CodecAltName
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.MPEG1_VIDEO:
- return "MPEG-1";
- case TSStreamType.MPEG2_VIDEO:
- return "MPEG-2";
- case TSStreamType.AVC_VIDEO:
- return "AVC";
- case TSStreamType.MVC_VIDEO:
- return "MVC";
- case TSStreamType.VC1_VIDEO:
- return "VC-1";
- case TSStreamType.MPEG1_AUDIO:
- return "MP1";
- case TSStreamType.MPEG2_AUDIO:
- return "MP2";
- case TSStreamType.LPCM_AUDIO:
- return "LPCM";
- case TSStreamType.AC3_AUDIO:
- return "DD AC3";
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- return "DD AC3+";
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- return "Dolby TrueHD";
- case TSStreamType.DTS_AUDIO:
- return "DTS";
- case TSStreamType.DTS_HD_AUDIO:
- return "DTS-HD Hi-Res";
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- return "DTS Express";
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- return "DTS-HD Master";
- case TSStreamType.PRESENTATION_GRAPHICS:
- return "PGS";
- case TSStreamType.INTERACTIVE_GRAPHICS:
- return "IGS";
- case TSStreamType.SUBTITLE:
- return "SUB";
- default:
- return "UNKNOWN";
- }
- }
- }
-
- public string CodecShortName
- {
- get
- {
- switch (StreamType)
- {
- case TSStreamType.MPEG1_VIDEO:
- return "MPEG-1";
- case TSStreamType.MPEG2_VIDEO:
- return "MPEG-2";
- case TSStreamType.AVC_VIDEO:
- return "AVC";
- case TSStreamType.MVC_VIDEO:
- return "MVC";
- case TSStreamType.VC1_VIDEO:
- return "VC-1";
- case TSStreamType.MPEG1_AUDIO:
- return "MP1";
- case TSStreamType.MPEG2_AUDIO:
- return "MP2";
- case TSStreamType.LPCM_AUDIO:
- return "LPCM";
- case TSStreamType.AC3_AUDIO:
- if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
- return "AC3-EX";
- else
- return "AC3";
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- return "AC3+";
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- return "TrueHD";
- case TSStreamType.DTS_AUDIO:
- if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
- return "DTS-ES";
- else
- return "DTS";
- case TSStreamType.DTS_HD_AUDIO:
- return "DTS-HD HR";
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- return "DTS Express";
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- return "DTS-HD MA";
- case TSStreamType.PRESENTATION_GRAPHICS:
- return "PGS";
- case TSStreamType.INTERACTIVE_GRAPHICS:
- return "IGS";
- case TSStreamType.SUBTITLE:
- return "SUB";
- default:
- return "UNKNOWN";
- }
- }
- }
-
- public virtual string Description => "";
-
- public abstract TSStream Clone();
-
- protected void CopyTo(TSStream stream)
- {
- stream.PID = PID;
- stream.StreamType = StreamType;
- stream.IsVBR = IsVBR;
- stream.BitRate = BitRate;
- stream.IsInitialized = IsInitialized;
- stream.LanguageCode = _LanguageCode;
- if (Descriptors != null)
- {
- stream.Descriptors = new List();
- foreach (var descriptor in Descriptors)
- {
- stream.Descriptors.Add(descriptor.Clone());
- }
- }
- }
- }
-
- public class TSVideoStream : TSStream
- {
- public TSVideoStream()
- {
- }
-
- public int Width;
- public int Height;
- public bool IsInterlaced;
- public int FrameRateEnumerator;
- public int FrameRateDenominator;
- public TSAspectRatio AspectRatio;
- public string EncodingProfile;
-
- private TSVideoFormat _VideoFormat;
- public TSVideoFormat VideoFormat
- {
- get => _VideoFormat;
- set
- {
- _VideoFormat = value;
- switch (value)
- {
- case TSVideoFormat.VIDEOFORMAT_480i:
- Height = 480;
- IsInterlaced = true;
- break;
- case TSVideoFormat.VIDEOFORMAT_480p:
- Height = 480;
- IsInterlaced = false;
- break;
- case TSVideoFormat.VIDEOFORMAT_576i:
- Height = 576;
- IsInterlaced = true;
- break;
- case TSVideoFormat.VIDEOFORMAT_576p:
- Height = 576;
- IsInterlaced = false;
- break;
- case TSVideoFormat.VIDEOFORMAT_720p:
- Height = 720;
- IsInterlaced = false;
- break;
- case TSVideoFormat.VIDEOFORMAT_1080i:
- Height = 1080;
- IsInterlaced = true;
- break;
- case TSVideoFormat.VIDEOFORMAT_1080p:
- Height = 1080;
- IsInterlaced = false;
- break;
- }
- }
- }
-
- private TSFrameRate _FrameRate;
- public TSFrameRate FrameRate
- {
- get => _FrameRate;
- set
- {
- _FrameRate = value;
- switch (value)
- {
- case TSFrameRate.FRAMERATE_23_976:
- FrameRateEnumerator = 24000;
- FrameRateDenominator = 1001;
- break;
- case TSFrameRate.FRAMERATE_24:
- FrameRateEnumerator = 24000;
- FrameRateDenominator = 1000;
- break;
- case TSFrameRate.FRAMERATE_25:
- FrameRateEnumerator = 25000;
- FrameRateDenominator = 1000;
- break;
- case TSFrameRate.FRAMERATE_29_97:
- FrameRateEnumerator = 30000;
- FrameRateDenominator = 1001;
- break;
- case TSFrameRate.FRAMERATE_50:
- FrameRateEnumerator = 50000;
- FrameRateDenominator = 1000;
- break;
- case TSFrameRate.FRAMERATE_59_94:
- FrameRateEnumerator = 60000;
- FrameRateDenominator = 1001;
- break;
- }
- }
- }
-
- public override string Description
- {
- get
- {
- string description = "";
-
- if (Height > 0)
- {
- description += string.Format("{0:D}{1} / ",
- Height,
- IsInterlaced ? "i" : "p");
- }
- if (FrameRateEnumerator > 0 &&
- FrameRateDenominator > 0)
- {
- if (FrameRateEnumerator % FrameRateDenominator == 0)
- {
- description += string.Format("{0:D} fps / ",
- FrameRateEnumerator / FrameRateDenominator);
- }
- else
- {
- description += string.Format("{0:F3} fps / ",
- (double)FrameRateEnumerator / FrameRateDenominator);
- }
-
- }
- if (AspectRatio == TSAspectRatio.ASPECT_4_3)
- {
- description += "4:3 / ";
- }
- else if (AspectRatio == TSAspectRatio.ASPECT_16_9)
- {
- description += "16:9 / ";
- }
- if (EncodingProfile != null)
- {
- description += EncodingProfile + " / ";
- }
- if (description.EndsWith(" / "))
- {
- description = description.Substring(0, description.Length - 3);
- }
- return description;
- }
- }
-
- public override TSStream Clone()
- {
- var stream = new TSVideoStream();
- CopyTo(stream);
-
- stream.VideoFormat = _VideoFormat;
- stream.FrameRate = _FrameRate;
- stream.Width = Width;
- stream.Height = Height;
- stream.IsInterlaced = IsInterlaced;
- stream.FrameRateEnumerator = FrameRateEnumerator;
- stream.FrameRateDenominator = FrameRateDenominator;
- stream.AspectRatio = AspectRatio;
- stream.EncodingProfile = EncodingProfile;
-
- return stream;
- }
- }
-
- public enum TSAudioMode
- {
- Unknown,
- DualMono,
- Stereo,
- Surround,
- Extended
- }
-
- public class TSAudioStream : TSStream
- {
- public TSAudioStream()
- {
- }
-
- public int SampleRate;
- public int ChannelCount;
- public int BitDepth;
- public int LFE;
- public int DialNorm;
- public TSAudioMode AudioMode;
- public TSAudioStream CoreStream;
- public TSChannelLayout ChannelLayout;
-
- public static int ConvertSampleRate(
- TSSampleRate sampleRate)
- {
- switch (sampleRate)
- {
- case TSSampleRate.SAMPLERATE_48:
- return 48000;
-
- case TSSampleRate.SAMPLERATE_96:
- case TSSampleRate.SAMPLERATE_48_96:
- return 96000;
-
- case TSSampleRate.SAMPLERATE_192:
- case TSSampleRate.SAMPLERATE_48_192:
- return 192000;
- }
- return 0;
- }
-
- public string ChannelDescription
- {
- get
- {
- if (ChannelLayout == TSChannelLayout.CHANNELLAYOUT_MONO &&
- ChannelCount == 2)
- {
- }
-
- string description = "";
- if (ChannelCount > 0)
- {
- description += string.Format(
- "{0:D}.{1:D}",
- ChannelCount, LFE);
- }
- else
- {
- switch (ChannelLayout)
- {
- case TSChannelLayout.CHANNELLAYOUT_MONO:
- description += "1.0";
- break;
- case TSChannelLayout.CHANNELLAYOUT_STEREO:
- description += "2.0";
- break;
- case TSChannelLayout.CHANNELLAYOUT_MULTI:
- description += "5.1";
- break;
- }
- }
- if (AudioMode == TSAudioMode.Extended)
- {
- if (StreamType == TSStreamType.AC3_AUDIO)
- {
- description += "-EX";
- }
- if (StreamType == TSStreamType.DTS_AUDIO ||
- StreamType == TSStreamType.DTS_HD_AUDIO ||
- StreamType == TSStreamType.DTS_HD_MASTER_AUDIO)
- {
- description += "-ES";
- }
- }
- return description;
- }
- }
-
- public override string Description
- {
- get
- {
- string description = ChannelDescription;
-
- if (SampleRate > 0)
- {
- description += string.Format(
- " / {0:D} kHz", SampleRate / 1000);
- }
- if (BitRate > 0)
- {
- description += string.Format(
- " / {0:D} kbps", (uint)Math.Round((double)BitRate / 1000));
- }
- if (BitDepth > 0)
- {
- description += string.Format(
- " / {0:D}-bit", BitDepth);
- }
- if (DialNorm != 0)
- {
- description += string.Format(
- " / DN {0}dB", DialNorm);
- }
- if (ChannelCount == 2)
- {
- switch (AudioMode)
- {
- case TSAudioMode.DualMono:
- description += " / Dual Mono";
- break;
-
- case TSAudioMode.Surround:
- description += " / Dolby Surround";
- break;
- }
- }
- if (description.EndsWith(" / "))
- {
- description = description.Substring(0, description.Length - 3);
- }
- if (CoreStream != null)
- {
- string codec = "";
- switch (CoreStream.StreamType)
- {
- case TSStreamType.AC3_AUDIO:
- codec = "AC3 Embedded";
- break;
- case TSStreamType.DTS_AUDIO:
- codec = "DTS Core";
- break;
- }
- description += string.Format(
- " ({0}: {1})",
- codec,
- CoreStream.Description);
- }
- return description;
- }
- }
-
- public override TSStream Clone()
- {
- var stream = new TSAudioStream();
- CopyTo(stream);
-
- stream.SampleRate = SampleRate;
- stream.ChannelLayout = ChannelLayout;
- stream.ChannelCount = ChannelCount;
- stream.BitDepth = BitDepth;
- stream.LFE = LFE;
- stream.DialNorm = DialNorm;
- stream.AudioMode = AudioMode;
- if (CoreStream != null)
- {
- stream.CoreStream = (TSAudioStream)CoreStream.Clone();
- }
-
- return stream;
- }
- }
-
- public class TSGraphicsStream : TSStream
- {
- public TSGraphicsStream()
- {
- IsVBR = true;
- IsInitialized = true;
- }
-
- public override TSStream Clone()
- {
- var stream = new TSGraphicsStream();
- CopyTo(stream);
- return stream;
- }
- }
-
- public class TSTextStream : TSStream
- {
- public TSTextStream()
- {
- IsVBR = true;
- IsInitialized = true;
- }
-
- public override TSStream Clone()
- {
- var stream = new TSTextStream();
- CopyTo(stream);
- return stream;
- }
- }
-}
diff --git a/BDInfo/TSStreamBuffer.cs b/BDInfo/TSStreamBuffer.cs
deleted file mode 100644
index 30bd1a3f44..0000000000
--- a/BDInfo/TSStreamBuffer.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-using System;
-using System.Collections.Specialized;
-using System.IO;
-
-namespace BDInfo
-{
- public class TSStreamBuffer
- {
- private MemoryStream Stream = new MemoryStream();
- private int SkipBits = 0;
- private byte[] Buffer;
- private int BufferLength = 0;
- public int TransferLength = 0;
-
- public TSStreamBuffer()
- {
- Buffer = new byte[4096];
- Stream = new MemoryStream(Buffer);
- }
-
- public long Length => (long)BufferLength;
-
- public long Position => Stream.Position;
-
- public void Add(
- byte[] buffer,
- int offset,
- int length)
- {
- TransferLength += length;
-
- if (BufferLength + length >= Buffer.Length)
- {
- length = Buffer.Length - BufferLength;
- }
- if (length > 0)
- {
- Array.Copy(buffer, offset, Buffer, BufferLength, length);
- BufferLength += length;
- }
- }
-
- public void Seek(
- long offset,
- SeekOrigin loc)
- {
- Stream.Seek(offset, loc);
- }
-
- public void Reset()
- {
- BufferLength = 0;
- TransferLength = 0;
- }
-
- public void BeginRead()
- {
- SkipBits = 0;
- Stream.Seek(0, SeekOrigin.Begin);
- }
-
- public void EndRead()
- {
- }
-
- public byte[] ReadBytes(int bytes)
- {
- if (Stream.Position + bytes >= BufferLength)
- {
- return null;
- }
-
- byte[] value = new byte[bytes];
- Stream.Read(value, 0, bytes);
- return value;
- }
-
- public byte ReadByte()
- {
- return (byte)Stream.ReadByte();
- }
-
- public int ReadBits(int bits)
- {
- long pos = Stream.Position;
-
- int shift = 24;
- int data = 0;
- for (int i = 0; i < 4; i++)
- {
- if (pos + i >= BufferLength) break;
- data += (Stream.ReadByte() << shift);
- shift -= 8;
- }
- var vector = new BitVector32(data);
-
- int value = 0;
- for (int i = SkipBits; i < SkipBits + bits; i++)
- {
- value <<= 1;
- value += (vector[1 << (32 - i - 1)] ? 1 : 0);
- }
-
- SkipBits += bits;
- Stream.Seek(pos + (SkipBits >> 3), SeekOrigin.Begin);
- SkipBits = SkipBits % 8;
-
- return value;
- }
- }
-}
diff --git a/BDInfo/TSStreamClip.cs b/BDInfo/TSStreamClip.cs
deleted file mode 100644
index 295eeb6b18..0000000000
--- a/BDInfo/TSStreamClip.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-
-namespace BDInfo
-{
- public class TSStreamClip
- {
- public int AngleIndex = 0;
- public string Name;
- public double TimeIn;
- public double TimeOut;
- public double RelativeTimeIn;
- public double RelativeTimeOut;
- public double Length;
-
- public ulong FileSize = 0;
- public ulong InterleavedFileSize = 0;
- public ulong PayloadBytes = 0;
- public ulong PacketCount = 0;
- public double PacketSeconds = 0;
-
- public List Chapters = new List();
-
- public TSStreamFile StreamFile = null;
- public TSStreamClipFile StreamClipFile = null;
-
- public TSStreamClip(
- TSStreamFile streamFile,
- TSStreamClipFile streamClipFile)
- {
- if (streamFile != null)
- {
- Name = streamFile.Name;
- StreamFile = streamFile;
- FileSize = (ulong)StreamFile.FileInfo.Length;
- if (StreamFile.InterleavedFile != null)
- {
- InterleavedFileSize = (ulong)StreamFile.InterleavedFile.FileInfo.Length;
- }
- }
- StreamClipFile = streamClipFile;
- }
-
- public string DisplayName
- {
- get
- {
- if (StreamFile != null &&
- StreamFile.InterleavedFile != null &&
- BDInfoSettings.EnableSSIF)
- {
- return StreamFile.InterleavedFile.Name;
- }
- return Name;
- }
- }
-
- public ulong PacketSize => PacketCount * 192;
-
- public ulong PacketBitRate
- {
- get
- {
- if (PacketSeconds > 0)
- {
- return (ulong)Math.Round(((PacketSize * 8.0) / PacketSeconds));
- }
- return 0;
- }
- }
-
- public bool IsCompatible(TSStreamClip clip)
- {
- foreach (var stream1 in StreamFile.Streams.Values)
- {
- if (clip.StreamFile.Streams.ContainsKey(stream1.PID))
- {
- var stream2 = clip.StreamFile.Streams[stream1.PID];
- if (stream1.StreamType != stream2.StreamType)
- {
- return false;
- }
- }
- }
- return true;
- }
- }
-}
diff --git a/BDInfo/TSStreamClipFile.cs b/BDInfo/TSStreamClipFile.cs
deleted file mode 100644
index e1097b23da..0000000000
--- a/BDInfo/TSStreamClipFile.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
- public class TSStreamClipFile
- {
- public FileSystemMetadata FileInfo = null;
- public string FileType = null;
- public bool IsValid = false;
- public string Name = null;
-
- public Dictionary Streams =
- new Dictionary();
-
- public TSStreamClipFile(FileSystemMetadata fileInfo)
- {
- FileInfo = fileInfo;
- Name = fileInfo.Name.ToUpper();
- }
-
- public void Scan()
- {
- Stream fileStream = null;
- BinaryReader fileReader = null;
-
- try
- {
-#if DEBUG
- Debug.WriteLine(string.Format(
- "Scanning {0}...", Name));
-#endif
- Streams.Clear();
-
- fileStream = File.OpenRead(FileInfo.FullName);
- fileReader = new BinaryReader(fileStream);
-
- byte[] data = new byte[fileStream.Length];
- fileReader.Read(data, 0, data.Length);
-
- byte[] fileType = new byte[8];
- Array.Copy(data, 0, fileType, 0, fileType.Length);
-
- FileType = Encoding.ASCII.GetString(fileType, 0, fileType.Length);
- if (FileType != "HDMV0100" &&
- FileType != "HDMV0200")
- {
- throw new Exception(string.Format(
- "Clip info file {0} has an unknown file type {1}.",
- FileInfo.Name, FileType));
- }
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\tFileType: {0}", FileType));
-#endif
- int clipIndex =
- ((int)data[12] << 24) +
- ((int)data[13] << 16) +
- ((int)data[14] << 8) +
- ((int)data[15]);
-
- int clipLength =
- ((int)data[clipIndex] << 24) +
- ((int)data[clipIndex + 1] << 16) +
- ((int)data[clipIndex + 2] << 8) +
- ((int)data[clipIndex + 3]);
-
- byte[] clipData = new byte[clipLength];
- Array.Copy(data, clipIndex + 4, clipData, 0, clipData.Length);
-
- int streamCount = clipData[8];
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\tStreamCount: {0}", streamCount));
-#endif
- int streamOffset = 10;
- for (int streamIndex = 0;
- streamIndex < streamCount;
- streamIndex++)
- {
- TSStream stream = null;
-
- ushort PID = (ushort)
- ((clipData[streamOffset] << 8) +
- clipData[streamOffset + 1]);
-
- streamOffset += 2;
-
- var streamType = (TSStreamType)
- clipData[streamOffset + 1];
- switch (streamType)
- {
- case TSStreamType.MVC_VIDEO:
- // TODO
- break;
-
- case TSStreamType.AVC_VIDEO:
- case TSStreamType.MPEG1_VIDEO:
- case TSStreamType.MPEG2_VIDEO:
- case TSStreamType.VC1_VIDEO:
- {
- var videoFormat = (TSVideoFormat)
- (clipData[streamOffset + 2] >> 4);
- var frameRate = (TSFrameRate)
- (clipData[streamOffset + 2] & 0xF);
- var aspectRatio = (TSAspectRatio)
- (clipData[streamOffset + 3] >> 4);
-
- stream = new TSVideoStream();
- ((TSVideoStream)stream).VideoFormat = videoFormat;
- ((TSVideoStream)stream).AspectRatio = aspectRatio;
- ((TSVideoStream)stream).FrameRate = frameRate;
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2} {3} {4}",
- PID,
- streamType,
- videoFormat,
- frameRate,
- aspectRatio));
-#endif
- }
- break;
-
- case TSStreamType.AC3_AUDIO:
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- case TSStreamType.DTS_AUDIO:
- case TSStreamType.DTS_HD_AUDIO:
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- case TSStreamType.LPCM_AUDIO:
- case TSStreamType.MPEG1_AUDIO:
- case TSStreamType.MPEG2_AUDIO:
- {
- byte[] languageBytes = new byte[3];
- Array.Copy(clipData, streamOffset + 3,
- languageBytes, 0, languageBytes.Length);
- string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-
- var channelLayout = (TSChannelLayout)
- (clipData[streamOffset + 2] >> 4);
- var sampleRate = (TSSampleRate)
- (clipData[streamOffset + 2] & 0xF);
-
- stream = new TSAudioStream();
- ((TSAudioStream)stream).LanguageCode = languageCode;
- ((TSAudioStream)stream).ChannelLayout = channelLayout;
- ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate);
- ((TSAudioStream)stream).LanguageCode = languageCode;
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2} {3} {4}",
- PID,
- streamType,
- languageCode,
- channelLayout,
- sampleRate));
-#endif
- }
- break;
-
- case TSStreamType.INTERACTIVE_GRAPHICS:
- case TSStreamType.PRESENTATION_GRAPHICS:
- {
- byte[] languageBytes = new byte[3];
- Array.Copy(clipData, streamOffset + 2,
- languageBytes, 0, languageBytes.Length);
- string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-
- stream = new TSGraphicsStream();
- stream.LanguageCode = languageCode;
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2}",
- PID,
- streamType,
- languageCode));
-#endif
- }
- break;
-
- case TSStreamType.SUBTITLE:
- {
- byte[] languageBytes = new byte[3];
- Array.Copy(clipData, streamOffset + 3,
- languageBytes, 0, languageBytes.Length);
- string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-#if DEBUG
- Debug.WriteLine(string.Format(
- "\t{0} {1} {2}",
- PID,
- streamType,
- languageCode));
-#endif
- stream = new TSTextStream();
- stream.LanguageCode = languageCode;
- }
- break;
- }
-
- if (stream != null)
- {
- stream.PID = PID;
- stream.StreamType = streamType;
- Streams.Add(PID, stream);
- }
-
- streamOffset += clipData[streamOffset] + 1;
- }
- IsValid = true;
- }
- finally
- {
- if (fileReader != null) fileReader.Dispose();
- if (fileStream != null) fileStream.Dispose();
- }
- }
- }
-}
diff --git a/BDInfo/TSStreamFile.cs b/BDInfo/TSStreamFile.cs
deleted file mode 100644
index ecf6609e2e..0000000000
--- a/BDInfo/TSStreamFile.cs
+++ /dev/null
@@ -1,1555 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
- public class TSStreamState
- {
- public ulong TransferCount = 0;
-
- public string StreamTag = null;
-
- public ulong TotalPackets = 0;
- public ulong WindowPackets = 0;
-
- public ulong TotalBytes = 0;
- public ulong WindowBytes = 0;
-
- public long PeakTransferLength = 0;
- public long PeakTransferRate = 0;
-
- public double TransferMarker = 0;
- public double TransferInterval = 0;
-
- public TSStreamBuffer StreamBuffer = new TSStreamBuffer();
-
- public uint Parse = 0;
- public bool TransferState = false;
- public int TransferLength = 0;
- public int PacketLength = 0;
- public byte PacketLengthParse = 0;
- public byte PacketParse = 0;
-
- public byte PTSParse = 0;
- public ulong PTS = 0;
- public ulong PTSTemp = 0;
- public ulong PTSLast = 0;
- public ulong PTSPrev = 0;
- public ulong PTSDiff = 0;
- public ulong PTSCount = 0;
- public ulong PTSTransfer = 0;
-
- public byte DTSParse = 0;
- public ulong DTSTemp = 0;
- public ulong DTSPrev = 0;
-
- public byte PESHeaderLength = 0;
- public byte PESHeaderFlags = 0;
-#if DEBUG
- public byte PESHeaderIndex = 0;
- public byte[] PESHeader = new byte[256 + 9];
-#endif
- }
-
- public class TSPacketParser
- {
- public bool SyncState = false;
- public byte TimeCodeParse = 4;
- public byte PacketLength = 0;
- public byte HeaderParse = 0;
-
- public uint TimeCode;
- public byte TransportErrorIndicator;
- public byte PayloadUnitStartIndicator;
- public byte TransportPriority;
- public ushort PID;
- public byte TransportScramblingControl;
- public byte AdaptionFieldControl;
-
- public bool AdaptionFieldState = false;
- public byte AdaptionFieldParse = 0;
- public byte AdaptionFieldLength = 0;
-
- public ushort PCRPID = 0xFFFF;
- public byte PCRParse = 0;
- public ulong PreviousPCR = 0;
- public ulong PCR = 0;
- public ulong PCRCount = 0;
- public ulong PTSFirst = ulong.MaxValue;
- public ulong PTSLast = ulong.MinValue;
- public ulong PTSDiff = 0;
-
- public byte[] PAT = new byte[1024];
- public bool PATSectionStart = false;
- public byte PATPointerField = 0;
- public uint PATOffset = 0;
- public byte PATSectionLengthParse = 0;
- public ushort PATSectionLength = 0;
- public uint PATSectionParse = 0;
- public bool PATTransferState = false;
- public byte PATSectionNumber = 0;
- public byte PATLastSectionNumber = 0;
-
- public ushort TransportStreamId = 0xFFFF;
-
- public List PMTProgramDescriptors = new List();
- public ushort PMTPID = 0xFFFF;
- public Dictionary PMT = new Dictionary();
- public bool PMTSectionStart = false;
- public ushort PMTProgramInfoLength = 0;
- public byte PMTProgramDescriptor = 0;
- public byte PMTProgramDescriptorLengthParse = 0;
- public byte PMTProgramDescriptorLength = 0;
- public ushort PMTStreamInfoLength = 0;
- public uint PMTStreamDescriptorLengthParse = 0;
- public uint PMTStreamDescriptorLength = 0;
- public byte PMTPointerField = 0;
- public uint PMTOffset = 0;
- public uint PMTSectionLengthParse = 0;
- public ushort PMTSectionLength = 0;
- public uint PMTSectionParse = 0;
- public bool PMTTransferState = false;
- public byte PMTSectionNumber = 0;
- public byte PMTLastSectionNumber = 0;
-
- public byte PMTTemp = 0;
-
- public TSStream Stream = null;
- public TSStreamState StreamState = null;
-
- public ulong TotalPackets = 0;
- }
-
- public class TSStreamDiagnostics
- {
- public ulong Bytes = 0;
- public ulong Packets = 0;
- public double Marker = 0;
- public double Interval = 0;
- public string Tag = null;
- }
-
- public class TSStreamFile
- {
- public FileSystemMetadata FileInfo = null;
- public string Name = null;
- public long Size = 0;
- public double Length = 0;
-
- public TSInterleavedFile InterleavedFile = null;
-
- private Dictionary StreamStates =
- new Dictionary();
-
- public Dictionary Streams =
- new Dictionary();
-
- public Dictionary> StreamDiagnostics =
- new Dictionary>();
-
- private List Playlists = null;
-
- private readonly IFileSystem _fileSystem;
-
- public TSStreamFile(FileSystemMetadata fileInfo, IFileSystem fileSystem)
- {
- FileInfo = fileInfo;
- _fileSystem = fileSystem;
- Name = fileInfo.Name.ToUpper();
- }
-
- public string DisplayName
- {
- get
- {
- if (BDInfoSettings.EnableSSIF &&
- InterleavedFile != null)
- {
- return InterleavedFile.Name;
- }
- return Name;
- }
- }
-
- private bool ScanStream(
- TSStream stream,
- TSStreamState streamState,
- TSStreamBuffer buffer)
- {
- streamState.StreamTag = null;
-
- long bitrate = 0;
- if (stream.IsAudioStream &&
- streamState.PTSTransfer > 0)
- {
- bitrate = (long)Math.Round(
- (buffer.TransferLength * 8.0) /
- ((double)streamState.PTSTransfer / 90000));
-
- if (bitrate > streamState.PeakTransferRate)
- {
- streamState.PeakTransferRate = bitrate;
- }
- }
- if (buffer.TransferLength > streamState.PeakTransferLength)
- {
- streamState.PeakTransferLength = buffer.TransferLength;
- }
-
- buffer.BeginRead();
- switch (stream.StreamType)
- {
- case TSStreamType.MPEG2_VIDEO:
- TSCodecMPEG2.Scan(
- (TSVideoStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.AVC_VIDEO:
- TSCodecAVC.Scan(
- (TSVideoStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.MVC_VIDEO:
- TSCodecMVC.Scan(
- (TSVideoStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.VC1_VIDEO:
- TSCodecVC1.Scan(
- (TSVideoStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.AC3_AUDIO:
- TSCodecAC3.Scan(
- (TSAudioStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- TSCodecAC3.Scan(
- (TSAudioStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- TSCodecTrueHD.Scan(
- (TSAudioStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.LPCM_AUDIO:
- TSCodecLPCM.Scan(
- (TSAudioStream)stream, buffer, ref streamState.StreamTag);
- break;
-
- case TSStreamType.DTS_AUDIO:
- TSCodecDTS.Scan(
- (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag);
- break;
-
- case TSStreamType.DTS_HD_AUDIO:
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- TSCodecDTSHD.Scan(
- (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag);
- break;
-
- default:
- stream.IsInitialized = true;
- break;
- }
- buffer.EndRead();
- streamState.StreamBuffer.Reset();
-
- bool isAVC = false;
- bool isMVC = false;
- foreach (var finishedStream in Streams.Values)
- {
- if (!finishedStream.IsInitialized)
- {
- return false;
- }
- if (finishedStream.StreamType == TSStreamType.AVC_VIDEO)
- {
- isAVC = true;
- }
- if (finishedStream.StreamType == TSStreamType.MVC_VIDEO)
- {
- isMVC = true;
- }
- }
- if (isMVC && !isAVC)
- {
- return false;
- }
- return true;
- }
-
- private void UpdateStreamBitrates(
- ushort PTSPID,
- ulong PTS,
- ulong PTSDiff)
- {
- if (Playlists == null) return;
-
- foreach (ushort PID in StreamStates.Keys)
- {
- if (Streams.ContainsKey(PID) &&
- Streams[PID].IsVideoStream &&
- PID != PTSPID)
- {
- continue;
- }
- if (StreamStates[PID].WindowPackets == 0)
- {
- continue;
- }
- UpdateStreamBitrate(PID, PTSPID, PTS, PTSDiff);
- }
-
- foreach (var playlist in Playlists)
- {
- double packetSeconds = 0;
- foreach (var clip in playlist.StreamClips)
- {
- if (clip.AngleIndex == 0)
- {
- packetSeconds += clip.PacketSeconds;
- }
- }
- if (packetSeconds > 0)
- {
- foreach (var playlistStream in playlist.SortedStreams)
- {
- if (playlistStream.IsVBR)
- {
- playlistStream.BitRate = (long)Math.Round(
- ((playlistStream.PayloadBytes * 8.0) / packetSeconds));
-
- if (playlistStream.StreamType == TSStreamType.AC3_TRUE_HD_AUDIO &&
- ((TSAudioStream)playlistStream).CoreStream != null)
- {
- playlistStream.BitRate -=
- ((TSAudioStream)playlistStream).CoreStream.BitRate;
- }
- }
- }
- }
- }
- }
-
- private void UpdateStreamBitrate(
- ushort PID,
- ushort PTSPID,
- ulong PTS,
- ulong PTSDiff)
- {
- if (Playlists == null) return;
-
- var streamState = StreamStates[PID];
- double streamTime = (double)PTS / 90000;
- double streamInterval = (double)PTSDiff / 90000;
- double streamOffset = streamTime + streamInterval;
-
- foreach (var playlist in Playlists)
- {
- foreach (var clip in playlist.StreamClips)
- {
- if (clip.Name != this.Name) continue;
-
- if (streamTime == 0 ||
- (streamTime >= clip.TimeIn &&
- streamTime <= clip.TimeOut))
- {
- clip.PayloadBytes += streamState.WindowBytes;
- clip.PacketCount += streamState.WindowPackets;
-
- if (streamOffset > clip.TimeIn &&
- streamOffset - clip.TimeIn > clip.PacketSeconds)
- {
- clip.PacketSeconds = streamOffset - clip.TimeIn;
- }
-
- var playlistStreams = playlist.Streams;
- if (clip.AngleIndex > 0 &&
- clip.AngleIndex < playlist.AngleStreams.Count + 1)
- {
- playlistStreams = playlist.AngleStreams[clip.AngleIndex - 1];
- }
- if (playlistStreams.ContainsKey(PID))
- {
- var stream = playlistStreams[PID];
-
- stream.PayloadBytes += streamState.WindowBytes;
- stream.PacketCount += streamState.WindowPackets;
-
- if (stream.IsVideoStream)
- {
- stream.PacketSeconds += streamInterval;
-
- stream.ActiveBitRate = (long)Math.Round(
- ((stream.PayloadBytes * 8.0) /
- stream.PacketSeconds));
- }
-
- if (stream.StreamType == TSStreamType.AC3_TRUE_HD_AUDIO &&
- ((TSAudioStream)stream).CoreStream != null)
- {
- stream.ActiveBitRate -=
- ((TSAudioStream)stream).CoreStream.BitRate;
- }
- }
- }
- }
- }
-
- if (Streams.ContainsKey(PID))
- {
- var stream = Streams[PID];
- stream.PayloadBytes += streamState.WindowBytes;
- stream.PacketCount += streamState.WindowPackets;
-
- if (stream.IsVideoStream)
- {
- var diag = new TSStreamDiagnostics();
- diag.Marker = (double)PTS / 90000;
- diag.Interval = (double)PTSDiff / 90000;
- diag.Bytes = streamState.WindowBytes;
- diag.Packets = streamState.WindowPackets;
- diag.Tag = streamState.StreamTag;
- StreamDiagnostics[PID].Add(diag);
-
- stream.PacketSeconds += streamInterval;
- }
- }
- streamState.WindowPackets = 0;
- streamState.WindowBytes = 0;
- }
-
- public void Scan(List playlists, bool isFullScan)
- {
- if (playlists == null || playlists.Count == 0)
- {
- return;
- }
-
- Playlists = playlists;
- int dataSize = 16384;
- Stream fileStream = null;
- try
- {
- string fileName;
- if (BDInfoSettings.EnableSSIF &&
- InterleavedFile != null)
- {
- fileName = InterleavedFile.FileInfo.FullName;
- }
- else
- {
- fileName = FileInfo.FullName;
- }
- fileStream = _fileSystem.GetFileStream(
- fileName,
- FileOpenMode.Open,
- FileAccessMode.Read,
- FileShareMode.Read,
- false);
-
- Size = 0;
- Length = 0;
-
- Streams.Clear();
- StreamStates.Clear();
- StreamDiagnostics.Clear();
-
- var parser =
- new TSPacketParser();
-
- long fileLength = (uint)fileStream.Length;
- byte[] buffer = new byte[dataSize];
- int bufferLength = 0;
- while ((bufferLength =
- fileStream.Read(buffer, 0, buffer.Length)) > 0)
- {
- int offset = 0;
- for (int i = 0; i < bufferLength; i++)
- {
- if (parser.SyncState == false)
- {
- if (parser.TimeCodeParse > 0)
- {
- parser.TimeCodeParse--;
- switch (parser.TimeCodeParse)
- {
- case 3:
- parser.TimeCode = 0;
- parser.TimeCode |=
- ((uint)buffer[i] & 0x3F) << 24;
- break;
- case 2:
- parser.TimeCode |=
- ((uint)buffer[i] & 0xFF) << 16;
- break;
- case 1:
- parser.TimeCode |=
- ((uint)buffer[i] & 0xFF) << 8;
- break;
- case 0:
- parser.TimeCode |=
- ((uint)buffer[i] & 0xFF);
- break;
- }
- }
- else if (buffer[i] == 0x47)
- {
- parser.SyncState = true;
- parser.PacketLength = 187;
- parser.TimeCodeParse = 4;
- parser.HeaderParse = 3;
- }
- }
- else if (parser.HeaderParse > 0)
- {
- parser.PacketLength--;
- parser.HeaderParse--;
-
- switch (parser.HeaderParse)
- {
- case 2:
- {
- parser.TransportErrorIndicator =
- (byte)((buffer[i] >> 7) & 0x1);
- parser.PayloadUnitStartIndicator =
- (byte)((buffer[i] >> 6) & 0x1);
- parser.TransportPriority =
- (byte)((buffer[i] >> 5) & 0x1);
- parser.PID =
- (ushort)((buffer[i] & 0x1f) << 8);
- }
- break;
-
- case 1:
- {
- parser.PID |= (ushort)buffer[i];
- if (Streams.ContainsKey(parser.PID))
- {
- parser.Stream = Streams[parser.PID];
- }
- else
- {
- parser.Stream = null;
- }
- if (!StreamStates.ContainsKey(parser.PID))
- {
- StreamStates[parser.PID] = new TSStreamState();
- }
- parser.StreamState = StreamStates[parser.PID];
- parser.StreamState.TotalPackets++;
- parser.StreamState.WindowPackets++;
- parser.TotalPackets++;
- }
- break;
-
- case 0:
- {
- parser.TransportScramblingControl =
- (byte)((buffer[i] >> 6) & 0x3);
- parser.AdaptionFieldControl =
- (byte)((buffer[i] >> 4) & 0x3);
-
- if ((parser.AdaptionFieldControl & 0x2) == 0x2)
- {
- parser.AdaptionFieldState = true;
- }
- if (parser.PayloadUnitStartIndicator == 1)
- {
- if (parser.PID == 0)
- {
- parser.PATSectionStart = true;
- }
- else if (parser.PID == parser.PMTPID)
- {
- parser.PMTSectionStart = true;
- }
- else if (parser.StreamState != null &&
- parser.StreamState.TransferState)
- {
- parser.StreamState.TransferState = false;
- parser.StreamState.TransferCount++;
-
- bool isFinished = ScanStream(
- parser.Stream,
- parser.StreamState,
- parser.StreamState.StreamBuffer);
-
- if (!isFullScan && isFinished)
- {
- return;
- }
- }
- }
- }
- break;
- }
- }
- else if (parser.AdaptionFieldState)
- {
- parser.PacketLength--;
- parser.AdaptionFieldParse = buffer[i];
- parser.AdaptionFieldLength = buffer[i];
- parser.AdaptionFieldState = false;
- }
- else if (parser.AdaptionFieldParse > 0)
- {
- parser.PacketLength--;
- parser.AdaptionFieldParse--;
- if ((parser.AdaptionFieldLength - parser.AdaptionFieldParse) == 1)
- {
- if ((buffer[i] & 0x10) == 0x10)
- {
- parser.PCRParse = 6;
- parser.PCR = 0;
- }
- }
- else if (parser.PCRParse > 0)
- {
- parser.PCRParse--;
- parser.PCR = (parser.PCR << 8) + (ulong)buffer[i];
- if (parser.PCRParse == 0)
- {
- parser.PreviousPCR = parser.PCR;
- parser.PCR = (parser.PCR & 0x1FF) +
- ((parser.PCR >> 15) * 300);
- }
- parser.PCRCount++;
- }
- if (parser.PacketLength == 0)
- {
- parser.SyncState = false;
- }
- }
- else if (parser.PID == 0)
- {
- if (parser.PATTransferState)
- {
- if ((bufferLength - i) > parser.PATSectionLength)
- {
- offset = parser.PATSectionLength;
- }
- else
- {
- offset = (bufferLength - i);
- }
- if (parser.PacketLength <= offset)
- {
- offset = parser.PacketLength;
- }
-
- for (int k = 0; k < offset; k++)
- {
- parser.PAT[parser.PATOffset++] = buffer[i++];
- parser.PATSectionLength--;
- parser.PacketLength--;
- }
- --i;
-
- if (parser.PATSectionLength == 0)
- {
- parser.PATTransferState = false;
- if (parser.PATSectionNumber == parser.PATLastSectionNumber)
- {
- for (int k = 0; k < (parser.PATOffset - 4); k += 4)
- {
- uint programNumber = (uint)
- ((parser.PAT[k] << 8) +
- parser.PAT[k + 1]);
-
- ushort programPID = (ushort)
- (((parser.PAT[k + 2] & 0x1F) << 8) +
- parser.PAT[k + 3]);
-
- if (programNumber == 1)
- {
- parser.PMTPID = programPID;
- }
- }
- }
- }
- }
- else
- {
- --parser.PacketLength;
- if (parser.PATSectionStart)
- {
- parser.PATPointerField = buffer[i];
- if (parser.PATPointerField == 0)
- {
- parser.PATSectionLengthParse = 3;
- }
- parser.PATSectionStart = false;
- }
- else if (parser.PATPointerField > 0)
- {
- --parser.PATPointerField;
- if (parser.PATPointerField == 0)
- {
- parser.PATSectionLengthParse = 3;
- }
- }
- else if (parser.PATSectionLengthParse > 0)
- {
- --parser.PATSectionLengthParse;
- switch (parser.PATSectionLengthParse)
- {
- case 2:
- break;
- case 1:
- parser.PATSectionLength = (ushort)
- ((buffer[i] & 0xF) << 8);
- break;
- case 0:
- parser.PATSectionLength |= buffer[i];
- if (parser.PATSectionLength > 1021)
- {
- parser.PATSectionLength = 0;
- }
- else
- {
- parser.PATSectionParse = 5;
- }
- break;
- }
- }
- else if (parser.PATSectionParse > 0)
- {
- --parser.PATSectionLength;
- --parser.PATSectionParse;
-
- switch (parser.PATSectionParse)
- {
- case 4:
- parser.TransportStreamId = (ushort)
- (buffer[i] << 8);
- break;
- case 3:
- parser.TransportStreamId |= buffer[i];
- break;
- case 2:
- break;
- case 1:
- parser.PATSectionNumber = buffer[i];
- if (parser.PATSectionNumber == 0)
- {
- parser.PATOffset = 0;
- }
- break;
- case 0:
- parser.PATLastSectionNumber = buffer[i];
- parser.PATTransferState = true;
- break;
- }
- }
- }
- if (parser.PacketLength == 0)
- {
- parser.SyncState = false;
- }
- }
- else if (parser.PID == parser.PMTPID)
- {
- if (parser.PMTTransferState)
- {
- if ((bufferLength - i) >= parser.PMTSectionLength)
- {
- offset = parser.PMTSectionLength;
- }
- else
- {
- offset = (bufferLength - i);
- }
- if (parser.PacketLength <= offset)
- {
- offset = parser.PacketLength;
- }
- if (!parser.PMT.ContainsKey(parser.PID))
- {
- parser.PMT[parser.PID] = new byte[1024];
- }
-
- byte[] PMT = parser.PMT[parser.PID];
- for (int k = 0; k < offset; k++)
- {
- PMT[parser.PMTOffset++] = buffer[i++];
- --parser.PMTSectionLength;
- --parser.PacketLength;
- }
- --i;
-
- if (parser.PMTSectionLength == 0)
- {
- parser.PMTTransferState = false;
- if (parser.PMTSectionNumber == parser.PMTLastSectionNumber)
- {
- //Console.WriteLine("PMT Start: " + parser.PMTTemp);
- try
- {
- for (int k = 0; k < (parser.PMTOffset - 4); k += 5)
- {
- byte streamType = PMT[k];
-
- ushort streamPID = (ushort)
- (((PMT[k + 1] & 0x1F) << 8) +
- PMT[k + 2]);
-
- ushort streamInfoLength = (ushort)
- (((PMT[k + 3] & 0xF) << 8) +
- PMT[k + 4]);
-
- /*
- if (streamInfoLength == 2)
- {
- // TODO: Cleanup
- //streamInfoLength = 0;
- }
-
- Console.WriteLine(string.Format(
- "Type: {0} PID: {1} Length: {2}",
- streamType, streamPID, streamInfoLength));
- */
-
- if (!Streams.ContainsKey(streamPID))
- {
- var streamDescriptors =
- new List();
-
- /*
- * TODO: Getting bad streamInfoLength
- if (streamInfoLength > 0)
- {
- for (int d = 0; d < streamInfoLength; d++)
- {
- byte name = PMT[k + d + 5];
- byte length = PMT[k + d + 6];
- TSDescriptor descriptor =
- new TSDescriptor(name, length);
- for (int v = 0; v < length; v++)
- {
- descriptor.Value[v] =
- PMT[k + d + v + 7];
- }
- streamDescriptors.Add(descriptor);
- d += (length + 1);
- }
- }
- */
- CreateStream(streamPID, streamType, streamDescriptors);
- }
- k += streamInfoLength;
- }
- }
- catch
- {
- // TODO
- //Console.WriteLine(ex.Message);
- }
- }
- }
- }
- else
- {
- --parser.PacketLength;
- if (parser.PMTSectionStart)
- {
- parser.PMTPointerField = buffer[i];
- if (parser.PMTPointerField == 0)
- {
- parser.PMTSectionLengthParse = 3;
- }
- parser.PMTSectionStart = false;
- }
- else if (parser.PMTPointerField > 0)
- {
- --parser.PMTPointerField;
- if (parser.PMTPointerField == 0)
- {
- parser.PMTSectionLengthParse = 3;
- }
- }
- else if (parser.PMTSectionLengthParse > 0)
- {
- --parser.PMTSectionLengthParse;
- switch (parser.PMTSectionLengthParse)
- {
- case 2:
- if (buffer[i] != 0x2)
- {
- parser.PMTSectionLengthParse = 0;
- }
- break;
- case 1:
- parser.PMTSectionLength = (ushort)
- ((buffer[i] & 0xF) << 8);
- break;
- case 0:
- parser.PMTSectionLength |= buffer[i];
- if (parser.PMTSectionLength > 1021)
- {
- parser.PMTSectionLength = 0;
- }
- else
- {
- parser.PMTSectionParse = 9;
- }
- break;
- }
- }
- else if (parser.PMTSectionParse > 0)
- {
- --parser.PMTSectionLength;
- --parser.PMTSectionParse;
-
- switch (parser.PMTSectionParse)
- {
- case 8:
- case 7:
- break;
- case 6:
- parser.PMTTemp = buffer[i];
- break;
- case 5:
- parser.PMTSectionNumber = buffer[i];
- if (parser.PMTSectionNumber == 0)
- {
- parser.PMTOffset = 0;
- }
- break;
- case 4:
- parser.PMTLastSectionNumber = buffer[i];
- break;
- case 3:
- parser.PCRPID = (ushort)
- ((buffer[i] & 0x1F) << 8);
- break;
- case 2:
- parser.PCRPID |= buffer[i];
- break;
- case 1:
- parser.PMTProgramInfoLength = (ushort)
- ((buffer[i] & 0xF) << 8);
- break;
- case 0:
- parser.PMTProgramInfoLength |= buffer[i];
- if (parser.PMTProgramInfoLength == 0)
- {
- parser.PMTTransferState = true;
- }
- else
- {
- parser.PMTProgramDescriptorLengthParse = 2;
- }
- break;
- }
- }
- else if (parser.PMTProgramInfoLength > 0)
- {
- --parser.PMTSectionLength;
- --parser.PMTProgramInfoLength;
-
- if (parser.PMTProgramDescriptorLengthParse > 0)
- {
- --parser.PMTProgramDescriptorLengthParse;
- switch (parser.PMTProgramDescriptorLengthParse)
- {
- case 1:
- parser.PMTProgramDescriptor = buffer[i];
- break;
- case 0:
- parser.PMTProgramDescriptorLength = buffer[i];
- parser.PMTProgramDescriptors.Add(
- new TSDescriptor(
- parser.PMTProgramDescriptor,
- parser.PMTProgramDescriptorLength));
- break;
- }
- }
- else if (parser.PMTProgramDescriptorLength > 0)
- {
- --parser.PMTProgramDescriptorLength;
-
- var descriptor = parser.PMTProgramDescriptors[
- parser.PMTProgramDescriptors.Count - 1];
-
- int valueIndex =
- descriptor.Value.Length -
- parser.PMTProgramDescriptorLength - 1;
-
- descriptor.Value[valueIndex] = buffer[i];
-
- if (parser.PMTProgramDescriptorLength == 0 &&
- parser.PMTProgramInfoLength > 0)
- {
- parser.PMTProgramDescriptorLengthParse = 2;
- }
- }
- if (parser.PMTProgramInfoLength == 0)
- {
- parser.PMTTransferState = true;
- }
- }
- }
- if (parser.PacketLength == 0)
- {
- parser.SyncState = false;
- }
- }
- else if (parser.Stream != null &&
- parser.StreamState != null &&
- parser.TransportScramblingControl == 0)
- {
- var stream = parser.Stream;
- var streamState = parser.StreamState;
-
- streamState.Parse =
- (streamState.Parse << 8) + buffer[i];
-
- if (streamState.TransferState)
- {
- if ((bufferLength - i) >= streamState.PacketLength &&
- streamState.PacketLength > 0)
- {
- offset = streamState.PacketLength;
- }
- else
- {
- offset = (bufferLength - i);
- }
- if (parser.PacketLength <= offset)
- {
- offset = parser.PacketLength;
- }
- streamState.TransferLength = offset;
-
- if (!stream.IsInitialized ||
- stream.IsVideoStream)
- {
- streamState.StreamBuffer.Add(
- buffer, i, offset);
- }
- else
- {
- streamState.StreamBuffer.TransferLength += offset;
- }
-
- i += (int)(streamState.TransferLength - 1);
- streamState.PacketLength -= streamState.TransferLength;
- parser.PacketLength -= (byte)streamState.TransferLength;
-
- streamState.TotalBytes += (ulong)streamState.TransferLength;
- streamState.WindowBytes += (ulong)streamState.TransferLength;
-
- if (streamState.PacketLength == 0)
- {
- streamState.TransferState = false;
- streamState.TransferCount++;
- bool isFinished = ScanStream(
- stream,
- streamState,
- streamState.StreamBuffer);
-
- if (!isFullScan && isFinished)
- {
- return;
- }
- }
- }
- else
- {
- --parser.PacketLength;
-
- bool headerFound = false;
- if (stream.IsVideoStream &&
- streamState.Parse == 0x000001FD)
- {
- headerFound = true;
- }
- if (stream.IsVideoStream &&
- streamState.Parse >= 0x000001E0 &&
- streamState.Parse <= 0x000001EF)
- {
- headerFound = true;
- }
- if (stream.IsAudioStream &&
- streamState.Parse == 0x000001BD)
- {
- headerFound = true;
- }
- if (stream.IsAudioStream &&
- (streamState.Parse == 0x000001FA ||
- streamState.Parse == 0x000001FD))
- {
- headerFound = true;
- }
-
- if (!stream.IsVideoStream &&
- !stream.IsAudioStream &&
- (streamState.Parse == 0x000001FA ||
- streamState.Parse == 0x000001FD ||
- streamState.Parse == 0x000001BD ||
- (streamState.Parse >= 0x000001E0 &&
- streamState.Parse <= 0x000001EF)))
- {
- headerFound = true;
- }
-
- if (headerFound)
- {
- streamState.PacketLengthParse = 2;
-#if DEBUG
- streamState.PESHeaderIndex = 0;
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)((streamState.Parse >> 24) & 0xFF);
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)((streamState.Parse >> 16) & 0xFF);
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)((streamState.Parse >> 8) & 0xFF);
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- }
- else if (streamState.PacketLengthParse > 0)
- {
- --streamState.PacketLengthParse;
- switch (streamState.PacketLengthParse)
- {
- case 1:
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 0:
- streamState.PacketLength =
- (int)(streamState.Parse & 0xFFFF);
- streamState.PacketParse = 3;
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
- }
- }
- else if (streamState.PacketParse > 0)
- {
- --streamState.PacketLength;
- --streamState.PacketParse;
-
- switch (streamState.PacketParse)
- {
- case 2:
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 1:
- streamState.PESHeaderFlags =
- (byte)(streamState.Parse & 0xFF);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 0:
- streamState.PESHeaderLength =
- (byte)(streamState.Parse & 0xFF);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- if ((streamState.PESHeaderFlags & 0xC0) == 0x80)
- {
- streamState.PTSParse = 5;
- }
- else if ((streamState.PESHeaderFlags & 0xC0) == 0xC0)
- {
- streamState.DTSParse = 10;
- }
- if (streamState.PESHeaderLength == 0)
- {
- streamState.TransferState = true;
- }
- break;
- }
- }
- else if (streamState.PTSParse > 0)
- {
- --streamState.PacketLength;
- --streamState.PESHeaderLength;
- --streamState.PTSParse;
-
- switch (streamState.PTSParse)
- {
- case 4:
- streamState.PTSTemp =
- ((streamState.Parse & 0xE) << 29);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- break;
-
- case 3:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 2:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 1:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 0:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- streamState.PTS = streamState.PTSTemp;
-
- if (streamState.PTS > streamState.PTSLast)
- {
- if (streamState.PTSLast > 0)
- {
- streamState.PTSTransfer = (streamState.PTS - streamState.PTSLast);
- }
- streamState.PTSLast = streamState.PTS;
- }
-
- streamState.PTSDiff = streamState.PTS - streamState.DTSPrev;
-
- if (streamState.PTSCount > 0 &&
- stream.IsVideoStream)
- {
- UpdateStreamBitrates(stream.PID, streamState.PTS, streamState.PTSDiff);
- if (streamState.DTSTemp < parser.PTSFirst)
- {
- parser.PTSFirst = streamState.DTSTemp;
- }
- if (streamState.DTSTemp > parser.PTSLast)
- {
- parser.PTSLast = streamState.DTSTemp;
- }
- Length = (double)(parser.PTSLast - parser.PTSFirst) / 90000;
- }
-
- streamState.DTSPrev = streamState.PTS;
- streamState.PTSCount++;
- if (streamState.PESHeaderLength == 0)
- {
- streamState.TransferState = true;
- }
- break;
- }
- }
- else if (streamState.DTSParse > 0)
- {
- --streamState.PacketLength;
- --streamState.PESHeaderLength;
- --streamState.DTSParse;
-
- switch (streamState.DTSParse)
- {
- case 9:
- streamState.PTSTemp =
- ((streamState.Parse & 0xE) << 29);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 8:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 7:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- break;
-
- case 6:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 5:
- streamState.PTSTemp |=
- ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- streamState.PTS = streamState.PTSTemp;
- if (streamState.PTS > streamState.PTSLast)
- {
- streamState.PTSLast = streamState.PTS;
- }
- break;
-
- case 4:
- streamState.DTSTemp =
- ((streamState.Parse & 0xE) << 29);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- break;
-
- case 3:
- streamState.DTSTemp |=
- ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- break;
-
- case 2:
- streamState.DTSTemp |=
- ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- break;
-
- case 1:
- streamState.DTSTemp |=
- ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- break;
-
- case 0:
- streamState.DTSTemp |=
- ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xff);
-#endif
- streamState.PTSDiff = streamState.DTSTemp - streamState.DTSPrev;
-
- if (streamState.PTSCount > 0 &&
- stream.IsVideoStream)
- {
- UpdateStreamBitrates(stream.PID, streamState.DTSTemp, streamState.PTSDiff);
- if (streamState.DTSTemp < parser.PTSFirst)
- {
- parser.PTSFirst = streamState.DTSTemp;
- }
- if (streamState.DTSTemp > parser.PTSLast)
- {
- parser.PTSLast = streamState.DTSTemp;
- }
- Length = (double)(parser.PTSLast - parser.PTSFirst) / 90000;
- }
- streamState.DTSPrev = streamState.DTSTemp;
- streamState.PTSCount++;
- if (streamState.PESHeaderLength == 0)
- {
- streamState.TransferState = true;
- }
- break;
- }
- }
- else if (streamState.PESHeaderLength > 0)
- {
- --streamState.PacketLength;
- --streamState.PESHeaderLength;
-#if DEBUG
- streamState.PESHeader[streamState.PESHeaderIndex++] =
- (byte)(streamState.Parse & 0xFF);
-#endif
- if (streamState.PESHeaderLength == 0)
- {
- streamState.TransferState = true;
- }
- }
- }
- if (parser.PacketLength == 0)
- {
- parser.SyncState = false;
- }
- }
- else
- {
- parser.PacketLength--;
- if ((bufferLength - i) >= parser.PacketLength)
- {
- i = i + parser.PacketLength;
- parser.PacketLength = 0;
- }
- else
- {
- parser.PacketLength -= (byte)((bufferLength - i) + 1);
- i = bufferLength;
- }
- if (parser.PacketLength == 0)
- {
- parser.SyncState = false;
- }
- }
- }
- Size += bufferLength;
- }
-
- ulong PTSLast = 0;
- ulong PTSDiff = 0;
- foreach (var stream in Streams.Values)
- {
- if (!stream.IsVideoStream) continue;
-
- if (StreamStates.ContainsKey(stream.PID) &&
- StreamStates[stream.PID].PTSLast > PTSLast)
- {
- PTSLast = StreamStates[stream.PID].PTSLast;
- PTSDiff = PTSLast - StreamStates[stream.PID].DTSPrev;
- }
- UpdateStreamBitrates(stream.PID, PTSLast, PTSDiff);
- }
- }
- finally
- {
- if (fileStream != null)
- {
- fileStream.Dispose();
- }
- }
- }
-
- private TSStream CreateStream(
- ushort streamPID,
- byte streamType,
- List streamDescriptors)
- {
- TSStream stream = null;
-
- switch ((TSStreamType)streamType)
- {
- case TSStreamType.MVC_VIDEO:
- case TSStreamType.AVC_VIDEO:
- case TSStreamType.MPEG1_VIDEO:
- case TSStreamType.MPEG2_VIDEO:
- case TSStreamType.VC1_VIDEO:
- {
- stream = new TSVideoStream();
- }
- break;
-
- case TSStreamType.AC3_AUDIO:
- case TSStreamType.AC3_PLUS_AUDIO:
- case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
- case TSStreamType.AC3_TRUE_HD_AUDIO:
- case TSStreamType.DTS_AUDIO:
- case TSStreamType.DTS_HD_AUDIO:
- case TSStreamType.DTS_HD_MASTER_AUDIO:
- case TSStreamType.DTS_HD_SECONDARY_AUDIO:
- case TSStreamType.LPCM_AUDIO:
- case TSStreamType.MPEG1_AUDIO:
- case TSStreamType.MPEG2_AUDIO:
- {
- stream = new TSAudioStream();
- }
- break;
-
- case TSStreamType.INTERACTIVE_GRAPHICS:
- case TSStreamType.PRESENTATION_GRAPHICS:
- {
- stream = new TSGraphicsStream();
- }
- break;
-
- case TSStreamType.SUBTITLE:
- {
- stream = new TSTextStream();
- }
- break;
-
- default:
- break;
- }
-
- if (stream != null &&
- !Streams.ContainsKey(streamPID))
- {
- stream.PID = streamPID;
- stream.StreamType = (TSStreamType)streamType;
- stream.Descriptors = streamDescriptors;
- Streams[stream.PID] = stream;
- }
- if (!StreamDiagnostics.ContainsKey(streamPID))
- {
- StreamDiagnostics[streamPID] =
- new List();
- }
-
- return stream;
- }
- }
-}
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index d69e6330bb..800b3d51ff 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -31,6 +31,8 @@
- [fhriley](https://github.com/fhriley)
- [nevado](https://github.com/nevado)
- [mark-monteiro](https://github.com/mark-monteiro)
+ - [ullmie02](https://github.com/ullmie02)
+ - [pR0Ps](https://github.com/pR0Ps)
# Emby Contributors
diff --git a/Dockerfile b/Dockerfile
index 2a60bf1845..0bccd9d646 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
ARG FFMPEG_VERSION=latest
FROM node:alpine as web-builder
@@ -14,7 +14,9 @@ FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION}-buster as builder
WORKDIR /repo
COPY . .
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
-RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
+# because of changes in docker and systemd we need to not build in parallel at the moment
+# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
+RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
FROM jellyfin/ffmpeg:${FFMPEG_VERSION} as ffmpeg
FROM debian:buster-slim
@@ -29,7 +31,7 @@ COPY --from=web-builder /dist /jellyfin/jellyfin-web
# mesa-va-drivers: needed for VAAPI
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
- libfontconfig1 libgomp1 libva-drm2 mesa-va-drivers openssl \
+ libfontconfig1 libgomp1 libva-drm2 mesa-va-drivers openssl ca-certificates \
&& apt-get clean autoclean \
&& apt-get autoremove \
&& rm -rf /var/lib/apt/lists/* \
diff --git a/Dockerfile.arm b/Dockerfile.arm
index fd3d1e0704..e7cbb09094 100644
--- a/Dockerfile.arm
+++ b/Dockerfile.arm
@@ -1,6 +1,4 @@
-# Requires binfm_misc registration
-# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder
@@ -23,11 +21,10 @@ RUN find . -type d -name obj | xargs -r rm -r
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
-FROM multiarch/qemu-user-static:x86_64-arm as qemu
-FROM debian:stretch-slim-arm32v7
-COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
+FROM debian:buster-slim
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
+ libssl-dev ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
diff --git a/Dockerfile.arm64 b/Dockerfile.arm64
index 3c1b2e3eab..a0cd0dacc2 100644
--- a/Dockerfile.arm64
+++ b/Dockerfile.arm64
@@ -1,6 +1,4 @@
-# Requires binfm_misc registration
-# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder
@@ -23,11 +21,10 @@ RUN find . -type d -name obj | xargs -r rm -r
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none"
-FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
-FROM debian:stretch-slim-arm64v8
-COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
+FROM debian:buster-slim
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
+ libssl-dev ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
diff --git a/DvdLib/DvdLib.csproj b/DvdLib/DvdLib.csproj
index 9dbaa9e2f0..f4df6a9f52 100644
--- a/DvdLib/DvdLib.csproj
+++ b/DvdLib/DvdLib.csproj
@@ -9,7 +9,7 @@
- netstandard2.0
+ netstandard2.1
false
true
diff --git a/DvdLib/Ifo/Dvd.cs b/DvdLib/Ifo/Dvd.cs
index 90125fa3e3..157b2e197f 100644
--- a/DvdLib/Ifo/Dvd.cs
+++ b/DvdLib/Ifo/Dvd.cs
@@ -42,7 +42,7 @@ namespace DvdLib.Ifo
}
else
{
- using (var vmgFs = _fileSystem.GetFileStream(vmgPath.FullName, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
+ using (var vmgFs = new FileStream(vmgPath.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var vmgRead = new BigEndianBinaryReader(vmgFs))
{
@@ -95,7 +95,7 @@ namespace DvdLib.Ifo
{
VTSPaths[vtsNum] = vtsPath;
- using (var vtsFs = _fileSystem.GetFileStream(vtsPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
+ using (var vtsFs = new FileStream(vtsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var vtsRead = new BigEndianBinaryReader(vtsFs))
{
diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs
index a451bbcf91..a7ff6e9cfd 100644
--- a/Emby.Dlna/Api/DlnaServerService.cs
+++ b/Emby.Dlna/Api/DlnaServerService.cs
@@ -170,32 +170,32 @@ namespace Emby.Dlna.Api
return _resultFactory.GetResult(Request, xml, XMLContentType);
}
- public object Post(ProcessMediaReceiverRegistrarControlRequest request)
+ public async Task