Browse Source

add deinterlace option to ffmpeg profile (#709)

* update dependencies

* add option to deinterlace video
pull/710/head
Jason Dove 4 years ago committed by GitHub
parent
commit
9b3c24559d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/ErsatzTV.Application.csproj
  3. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfile.cs
  4. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfileHandler.cs
  5. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfile.cs
  6. 1
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfileHandler.cs
  7. 3
      ErsatzTV.Application/FFmpegProfiles/FFmpegProfileViewModel.cs
  8. 3
      ErsatzTV.Application/FFmpegProfiles/Mapper.cs
  9. 2
      ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj
  10. 3
      ErsatzTV.Core/Domain/FFmpegProfile.cs
  11. 11
      ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs
  12. 2
      ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj
  13. 3
      ErsatzTV.Infrastructure/Data/Configurations/FFmpegProfileConfiguration.cs
  14. 2
      ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
  15. 3886
      ErsatzTV.Infrastructure/Migrations/20220318140255_Remove_FFmpegProfileVideoCodecAudioCodec.Designer.cs
  16. 35
      ErsatzTV.Infrastructure/Migrations/20220318140255_Remove_FFmpegProfileVideoCodecAudioCodec.cs
  17. 3889
      ErsatzTV.Infrastructure/Migrations/20220318140403_Add_FFmpegProfileDeinterlaceVideo.Designer.cs
  18. 26
      ErsatzTV.Infrastructure/Migrations/20220318140403_Add_FFmpegProfileDeinterlaceVideo.cs
  19. 3891
      ErsatzTV.Infrastructure/Migrations/20220318142924_Fix_FFmpegProfileDeinterlaceVideoDefaultValue.Designer.cs
  20. 33
      ErsatzTV.Infrastructure/Migrations/20220318142924_Fix_FFmpegProfileDeinterlaceVideoDefaultValue.cs
  21. 11
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  22. 3
      ErsatzTV/Pages/FFmpegEditor.razor
  23. 8
      ErsatzTV/ViewModels/FFmpegProfileEditViewModel.cs

5
CHANGELOG.md

@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- Fix streaming mode inconsistencies when `mode` parameter is unspecified
### Added
- Add option to automatically deinterlace video when transcoding
- Previously, this was always enabled; the purpose of the option is to allow disabling any deinterlace filters
- Note that there is no performance gain to disabling the option with progressive content; filters are only ever applied to interlaced content
## [0.4.4-alpha] - 2022-03-10
### Fixed
- Fix `HLS Direct` streaming mode

2
ErsatzTV.Application/ErsatzTV.Application.csproj

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Bugsnag" Version="3.0.0" />
<PackageReference Include="CliWrap" Version="3.4.1" />
<PackageReference Include="CliWrap" Version="3.4.2" />
<PackageReference Include="MediatR" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.1.46">

3
ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfile.cs

@ -23,4 +23,5 @@ public record CreateFFmpegProfile( @@ -23,4 +23,5 @@ public record CreateFFmpegProfile(
int AudioChannels,
int AudioSampleRate,
bool NormalizeAudio,
bool NormalizeFramerate) : IRequest<Either<BaseError, CreateFFmpegProfileResult>>;
bool NormalizeFramerate,
bool DeinterlaceVideo) : IRequest<Either<BaseError, CreateFFmpegProfileResult>>;

3
ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfileHandler.cs

@ -55,7 +55,8 @@ public class CreateFFmpegProfileHandler : @@ -55,7 +55,8 @@ public class CreateFFmpegProfileHandler :
AudioChannels = request.AudioChannels,
AudioSampleRate = request.AudioSampleRate,
NormalizeAudio = request.NormalizeAudio,
NormalizeFramerate = request.NormalizeFramerate
NormalizeFramerate = request.NormalizeFramerate,
DeinterlaceVideo = request.DeinterlaceVideo
});
private static Validation<BaseError, string> ValidateName(CreateFFmpegProfile createFFmpegProfile) =>

3
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfile.cs

@ -24,4 +24,5 @@ public record UpdateFFmpegProfile( @@ -24,4 +24,5 @@ public record UpdateFFmpegProfile(
int AudioChannels,
int AudioSampleRate,
bool NormalizeAudio,
bool NormalizeFramerate) : IRequest<Either<BaseError, UpdateFFmpegProfileResult>>;
bool NormalizeFramerate,
bool DeinterlaceVideo) : IRequest<Either<BaseError, UpdateFFmpegProfileResult>>;

1
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfileHandler.cs

@ -47,6 +47,7 @@ public class @@ -47,6 +47,7 @@ public class
p.AudioSampleRate = update.AudioSampleRate;
p.NormalizeAudio = update.Transcode && update.NormalizeAudio;
p.NormalizeFramerate = update.Transcode && update.NormalizeFramerate;
p.DeinterlaceVideo = update.Transcode && update.DeinterlaceVideo;
await dbContext.SaveChangesAsync();
return new UpdateFFmpegProfileResult(p.Id);
}

3
ErsatzTV.Application/FFmpegProfiles/FFmpegProfileViewModel.cs

@ -24,4 +24,5 @@ public record FFmpegProfileViewModel( @@ -24,4 +24,5 @@ public record FFmpegProfileViewModel(
int AudioChannels,
int AudioSampleRate,
bool NormalizeAudio,
bool NormalizeFramerate);
bool NormalizeFramerate,
bool DeinterlaceVideo);

3
ErsatzTV.Application/FFmpegProfiles/Mapper.cs

@ -26,7 +26,8 @@ internal static class Mapper @@ -26,7 +26,8 @@ internal static class Mapper
profile.AudioChannels,
profile.AudioSampleRate,
profile.NormalizeAudio,
profile.NormalizeVideo && profile.NormalizeFramerate);
profile.NormalizeVideo && profile.NormalizeFramerate,
profile.DeinterlaceVideo);
private static ResolutionViewModel Project(Resolution resolution) =>
new(resolution.Id, resolution.Name, resolution.Width, resolution.Height);

2
ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Bugsnag" Version="3.0.0" />
<PackageReference Include="CliWrap" Version="3.4.1" />
<PackageReference Include="CliWrap" Version="3.4.2" />
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<PackageReference Include="LanguageExt.Core" Version="4.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />

3
ErsatzTV.Core/Domain/FFmpegProfile.cs

@ -25,6 +25,7 @@ public record FFmpegProfile @@ -25,6 +25,7 @@ public record FFmpegProfile
public int AudioSampleRate { get; set; }
public bool NormalizeAudio { get; set; }
public bool NormalizeFramerate { get; set; }
public bool DeinterlaceVideo { get; set; }
public static FFmpegProfile New(string name, Resolution resolution) =>
new()
@ -45,6 +46,8 @@ public record FFmpegProfile @@ -45,6 +46,8 @@ public record FFmpegProfile
AudioSampleRate = 48,
NormalizeVideo = true,
NormalizeAudio = true,
DeinterlaceVideo = true,
NormalizeFramerate = false,
HardwareAcceleration = HardwareAccelerationKind.None
};
}

11
ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs

@ -98,12 +98,13 @@ public class FFmpegPlaybackSettingsCalculator @@ -98,12 +98,13 @@ public class FFmpegPlaybackSettingsCalculator
{
int fixedHeight = scaledSize.Height + scaledSize.Height % 2;
int fixedWidth = scaledSize.Width + scaledSize.Width % 2;
result.ScaledSize = Some((IDisplaySize) new DisplaySize(fixedWidth, fixedHeight));
result.ScaledSize = Some((IDisplaySize)new DisplaySize(fixedWidth, fixedHeight));
}
}
IDisplaySize sizeAfterScaling = result.ScaledSize.IfNone(videoVersion);
if (ffmpegProfile.Transcode && ffmpegProfile.NormalizeVideo && !sizeAfterScaling.IsSameSizeAs(ffmpegProfile.Resolution))
if (ffmpegProfile.Transcode && ffmpegProfile.NormalizeVideo &&
!sizeAfterScaling.IsSameSizeAs(ffmpegProfile.Resolution))
{
result.PadToDesiredResolution = true;
}
@ -179,10 +180,8 @@ public class FFmpegPlaybackSettingsCalculator @@ -179,10 +180,8 @@ public class FFmpegPlaybackSettingsCalculator
result.AudioFormat = FFmpegProfileAudioFormat.Copy;
}
if (videoVersion.VideoScanKind == VideoScanKind.Interlaced)
{
result.Deinterlace = true;
}
result.Deinterlace = ffmpegProfile.DeinterlaceVideo &&
videoVersion.VideoScanKind == VideoScanKind.Interlaced;
break;
}

2
ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.4.1" />
<PackageReference Include="CliWrap" Version="3.4.2" />
<PackageReference Include="LanguageExt.Core" Version="4.0.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
</ItemGroup>

3
ErsatzTV.Infrastructure/Data/Configurations/FFmpegProfileConfiguration.cs

@ -12,5 +12,8 @@ public class FFmpegProfileConfiguration : IEntityTypeConfiguration<FFmpegProfile @@ -12,5 +12,8 @@ public class FFmpegProfileConfiguration : IEntityTypeConfiguration<FFmpegProfile
builder.Property(p => p.NormalizeFramerate)
.HasDefaultValue(false);
builder.Property(p => p.DeinterlaceVideo)
.HasDefaultValue(true);
}
}

2
ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
<ItemGroup>
<PackageReference Include="Blurhash.ImageSharp" Version="1.1.1" />
<PackageReference Include="CliWrap" Version="3.4.1" />
<PackageReference Include="CliWrap" Version="3.4.2" />
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Lucene.Net" Version="4.8.0-beta00016" />
<PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00016" />

3886
ErsatzTV.Infrastructure/Migrations/20220318140255_Remove_FFmpegProfileVideoCodecAudioCodec.Designer.cs generated

File diff suppressed because it is too large Load Diff

35
ErsatzTV.Infrastructure/Migrations/20220318140255_Remove_FFmpegProfileVideoCodecAudioCodec.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Remove_FFmpegProfileVideoCodecAudioCodec : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AudioCodec",
table: "FFmpegProfile");
migrationBuilder.DropColumn(
name: "VideoCodec",
table: "FFmpegProfile");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "AudioCodec",
table: "FFmpegProfile",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "VideoCodec",
table: "FFmpegProfile",
type: "TEXT",
nullable: true);
}
}
}

3889
ErsatzTV.Infrastructure/Migrations/20220318140403_Add_FFmpegProfileDeinterlaceVideo.Designer.cs generated

File diff suppressed because it is too large Load Diff

26
ErsatzTV.Infrastructure/Migrations/20220318140403_Add_FFmpegProfileDeinterlaceVideo.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Add_FFmpegProfileDeinterlaceVideo : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "DeinterlaceVideo",
table: "FFmpegProfile",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DeinterlaceVideo",
table: "FFmpegProfile");
}
}
}

3891
ErsatzTV.Infrastructure/Migrations/20220318142924_Fix_FFmpegProfileDeinterlaceVideoDefaultValue.Designer.cs generated

File diff suppressed because it is too large Load Diff

33
ErsatzTV.Infrastructure/Migrations/20220318142924_Fix_FFmpegProfileDeinterlaceVideoDefaultValue.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Fix_FFmpegProfileDeinterlaceVideoDefaultValue : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<bool>(
name: "DeinterlaceVideo",
table: "FFmpegProfile",
type: "INTEGER",
nullable: false,
defaultValue: true,
oldClrType: typeof(bool),
oldType: "INTEGER");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<bool>(
name: "DeinterlaceVideo",
table: "FFmpegProfile",
type: "INTEGER",
nullable: false,
oldClrType: typeof(bool),
oldType: "INTEGER",
oldDefaultValue: true);
}
}
}

11
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -499,15 +499,17 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -499,15 +499,17 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int>("AudioChannels")
.HasColumnType("INTEGER");
b.Property<string>("AudioCodec")
.HasColumnType("TEXT");
b.Property<int>("AudioFormat")
.HasColumnType("INTEGER");
b.Property<int>("AudioSampleRate")
.HasColumnType("INTEGER");
b.Property<bool>("DeinterlaceVideo")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(true);
b.Property<int>("HardwareAcceleration")
.HasColumnType("INTEGER");
@ -549,9 +551,6 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -549,9 +551,6 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int>("VideoBufferSize")
.HasColumnType("INTEGER");
b.Property<string>("VideoCodec")
.HasColumnType("TEXT");
b.Property<int>("VideoFormat")
.HasColumnType("INTEGER");

3
ErsatzTV/Pages/FFmpegEditor.razor

@ -85,6 +85,9 @@ @@ -85,6 +85,9 @@
<MudElement HtmlTag="div" Class="mt-3">
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Frame Rate" @bind-Checked="@_model.NormalizeFramerate" For="@(() => _model.NormalizeFramerate)"/>
</MudElement>
<MudElement HtmlTag="div" Class="mt-3">
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Auto Deinterlace Video" @bind-Checked="@_model.DeinterlaceVideo" For="@(() => _model.DeinterlaceVideo)"/>
</MudElement>
</MudItem>
<MudItem>
<MudText Typo="Typo.h6">Audio</MudText>

8
ErsatzTV/ViewModels/FFmpegProfileEditViewModel.cs

@ -24,6 +24,7 @@ public class FFmpegProfileEditViewModel @@ -24,6 +24,7 @@ public class FFmpegProfileEditViewModel
NormalizeAudio = viewModel.NormalizeAudio;
NormalizeVideo = viewModel.NormalizeVideo;
NormalizeFramerate = viewModel.NormalizeFramerate;
DeinterlaceVideo = viewModel.DeinterlaceVideo;
Resolution = viewModel.Resolution;
ThreadCount = viewModel.ThreadCount;
Transcode = viewModel.Transcode;
@ -46,6 +47,7 @@ public class FFmpegProfileEditViewModel @@ -46,6 +47,7 @@ public class FFmpegProfileEditViewModel
public bool NormalizeAudio { get; set; }
public bool NormalizeVideo { get; set; }
public bool NormalizeFramerate { get; set; }
public bool DeinterlaceVideo { get; set; }
public ResolutionViewModel Resolution { get; set; }
public int ThreadCount { get; set; }
public bool Transcode { get; set; }
@ -76,7 +78,8 @@ public class FFmpegProfileEditViewModel @@ -76,7 +78,8 @@ public class FFmpegProfileEditViewModel
AudioChannels,
AudioSampleRate,
NormalizeAudio,
NormalizeFramerate
NormalizeFramerate,
DeinterlaceVideo
);
public UpdateFFmpegProfile ToUpdate() =>
@ -100,6 +103,7 @@ public class FFmpegProfileEditViewModel @@ -100,6 +103,7 @@ public class FFmpegProfileEditViewModel
AudioChannels,
AudioSampleRate,
NormalizeAudio,
NormalizeFramerate
NormalizeFramerate,
DeinterlaceVideo
);
}
Loading…
Cancel
Save