use single thread and disable framerate normalization (#639)
* try one thread for everything * add (unused) framerate filter * disable framerate normalization by default * update dependencies
This commit is contained in:
@@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Add improved but experimental transcoder logic, which can be toggled on and off in `Settings`
|
||||
- Fix `HLS Segmenter` bug when source video packet contains no duration (`N/A`)
|
||||
|
||||
### Changed
|
||||
- Disable framerate normalization by default and on all ffmpeg profiles
|
||||
- If framerate normalization is desired (not typically needed), it can be re-enabled manually
|
||||
|
||||
## [0.4.1-alpha] - 2022-02-10
|
||||
### Fixed
|
||||
- Normalize smart quotes in search queries as they are unsupported by the search library
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.4.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.5.1" />
|
||||
<PackageReference Include="LanguageExt.Core" Version="4.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.4.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.5.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace ErsatzTV.FFmpeg.Filter;
|
||||
|
||||
public class FrameRateFilter : BaseFilter
|
||||
{
|
||||
private readonly FrameState _currentState;
|
||||
private readonly int _frameRate;
|
||||
|
||||
public FrameRateFilter(FrameState currentState, int frameRate)
|
||||
{
|
||||
_currentState = currentState;
|
||||
_frameRate = frameRate;
|
||||
}
|
||||
|
||||
public override string Filter
|
||||
{
|
||||
get
|
||||
{
|
||||
string frameRate = $"framerate=fps={_frameRate}:flags=-scd";
|
||||
string pixelFormat = _currentState.PixelFormat.Match(pf => pf.FFmpegName, () => string.Empty);
|
||||
|
||||
if (_currentState.FrameDataLocation == FrameDataLocation.Hardware)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(pixelFormat))
|
||||
{
|
||||
return $"hwdownload,format={pixelFormat},{frameRate}";
|
||||
}
|
||||
|
||||
return $"hwdownload,{frameRate}";
|
||||
}
|
||||
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
|
||||
public override FrameState NextState(FrameState currentState) => currentState with { FrameRate = _frameRate };
|
||||
}
|
||||
@@ -8,7 +8,8 @@ public class RealtimeInputOption : IPipelineStep
|
||||
|
||||
// some builds of ffmpeg seem to hang when realtime input is requested with multithreading,
|
||||
// so we force a single thread here
|
||||
public IList<string> GlobalOptions => new List<string> { "-threads", "1" };
|
||||
// public IList<string> GlobalOptions => new List<string> { "-threads", "1" };
|
||||
public IList<string> GlobalOptions => Array.Empty<string>();
|
||||
|
||||
public IList<string> InputOptions => new List<string> { "-re" };
|
||||
public IList<string> FilterOptions => Array.Empty<string>();
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace ErsatzTV.FFmpeg.Option;
|
||||
|
||||
public class ThreadCountOption : GlobalOption
|
||||
{
|
||||
private readonly int _threadCount;
|
||||
|
||||
public ThreadCountOption(int threadCount)
|
||||
{
|
||||
_threadCount = threadCount;
|
||||
}
|
||||
|
||||
public override IList<string> GlobalOptions => new List<string> { "-threads", _threadCount.ToString() };
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class PipelineBuilder
|
||||
{
|
||||
_pipelineSteps = new List<IPipelineStep>
|
||||
{
|
||||
new ThreadCountOption(1), // try everything single-threaded
|
||||
new NoStandardInputOption(),
|
||||
new HideBannerOption(),
|
||||
new NoStatsOption(),
|
||||
|
||||
@@ -6,6 +6,12 @@ namespace ErsatzTV.Infrastructure.Data.Configurations
|
||||
{
|
||||
public class FFmpegProfileConfiguration : IEntityTypeConfiguration<FFmpegProfile>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<FFmpegProfile> builder) => builder.ToTable("FFmpegProfile");
|
||||
public void Configure(EntityTypeBuilder<FFmpegProfile> builder)
|
||||
{
|
||||
builder.ToTable("FFmpegProfile");
|
||||
|
||||
builder.Property(p => p.NormalizeFramerate)
|
||||
.HasDefaultValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3863
File diff suppressed because it is too large
Load Diff
+33
@@ -0,0 +1,33 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class Disable_FrameRateNormalization_ByDefault : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "NormalizeFramerate",
|
||||
table: "FFmpegProfile",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<bool>(
|
||||
name: "NormalizeFramerate",
|
||||
table: "FFmpegProfile",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(bool),
|
||||
oldType: "INTEGER",
|
||||
oldDefaultValue: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+3863
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class TurnOff_FrameRateNormalization : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("UPDATE FFmpegProfile SET NormalizeFramerate = 0");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.1");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.2");
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b =>
|
||||
{
|
||||
@@ -506,7 +506,9 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("NormalizeFramerate")
|
||||
.HasColumnType("INTEGER");
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<bool>("NormalizeLoudness")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -648,7 +650,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("SongMetadataId");
|
||||
|
||||
b.ToTable("Genre", (string)null);
|
||||
b.ToTable("Genre");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b =>
|
||||
@@ -1055,7 +1057,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("ArtistMetadataId");
|
||||
|
||||
b.ToTable("Mood", (string)null);
|
||||
b.ToTable("Mood");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b =>
|
||||
@@ -1163,7 +1165,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("SmartCollectionId");
|
||||
|
||||
b.ToTable("MultiCollectionSmartItem", (string)null);
|
||||
b.ToTable("MultiCollectionSmartItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
|
||||
@@ -1771,7 +1773,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("ArtistMetadataId");
|
||||
|
||||
b.ToTable("Style", (string)null);
|
||||
b.ToTable("Style");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b =>
|
||||
@@ -1825,7 +1827,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("SongMetadataId");
|
||||
|
||||
b.ToTable("Tag", (string)null);
|
||||
b.ToTable("Tag");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b =>
|
||||
@@ -2846,7 +2848,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.OwnsOne("ErsatzTV.Core.Domain.Playout.Anchor#ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 =>
|
||||
b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 =>
|
||||
{
|
||||
b1.Property<int>("PlayoutId")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2949,7 +2951,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
.WithMany()
|
||||
.HasForeignKey("SmartCollectionId");
|
||||
|
||||
b.OwnsOne("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor.EnumeratorState#ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 =>
|
||||
b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 =>
|
||||
{
|
||||
b1.Property<int>("PlayoutProgramScheduleAnchorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=fontfile/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fprobe/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=genpts/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwdownload/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwupload/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=igndts/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jellyfin/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<PackageReference Include="PPioli.FluentValidation.Blazor" Version="5.0.0" />
|
||||
<PackageReference Include="Refit.HttpClientFactory" Version="6.3.2" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
|
||||
<PackageReference Include="Serilog.Sinks.SQLite" Version="6.0.0" />
|
||||
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
|
||||
|
||||
Reference in New Issue
Block a user