Browse Source

remove framerate normalization (#253)

pull/255/head
Jason Dove 5 years ago committed by GitHub
parent
commit
5b36252dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfile.cs
  3. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/CreateFFmpegProfileHandler.cs
  4. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfile.cs
  5. 1
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfileHandler.cs
  6. 3
      ErsatzTV.Application/FFmpegProfiles/FFmpegProfileViewModel.cs
  7. 3
      ErsatzTV.Application/FFmpegProfiles/Mapper.cs
  8. 30
      ErsatzTV.Core.Tests/FFmpeg/FFmpegPlaybackSettingsCalculatorTests.cs
  9. 2
      ErsatzTV.Core/Domain/FFmpegProfile.cs
  10. 9
      ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs
  11. 1
      ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettings.cs
  12. 6
      ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs
  13. 6
      ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
  14. 1
      ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs
  15. 2886
      ErsatzTV.Infrastructure/Migrations/20210611214836_Remove_FFmpegProfileFrameRate.Designer.cs
  16. 23
      ErsatzTV.Infrastructure/Migrations/20210611214836_Remove_FFmpegProfileFrameRate.cs
  17. 3
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  18. 3
      ErsatzTV/Pages/FFmpegEditor.razor
  19. 8
      ErsatzTV/ViewModels/FFmpegProfileEditViewModel.cs

3
CHANGELOG.md

@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add experimental `HLS Hybrid` channel mode - Add experimental `HLS Hybrid` channel mode
- Media items are transcoded using the channel's ffmpeg profile and served using HLS - Media items are transcoded using the channel's ffmpeg profile and served using HLS
### Changed
- Remove framerate normalization; it caused more problems than it solved
### Fixed ### Fixed
- Fix serving channels.m3u with missing content ratings - Fix serving channels.m3u with missing content ratings

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

@ -21,6 +21,5 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
bool NormalizeLoudness, bool NormalizeLoudness,
int AudioChannels, int AudioChannels,
int AudioSampleRate, int AudioSampleRate,
bool NormalizeAudio, bool NormalizeAudio) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
string FrameRate) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
} }

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

@ -53,8 +53,7 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
NormalizeLoudness = request.NormalizeLoudness, NormalizeLoudness = request.NormalizeLoudness,
AudioChannels = request.AudioChannels, AudioChannels = request.AudioChannels,
AudioSampleRate = request.AudioSampleRate, AudioSampleRate = request.AudioSampleRate,
NormalizeAudio = request.NormalizeAudio, NormalizeAudio = request.NormalizeAudio
FrameRate = request.FrameRate
}); });
private Validation<BaseError, string> ValidateName(CreateFFmpegProfile createFFmpegProfile) => private Validation<BaseError, string> ValidateName(CreateFFmpegProfile createFFmpegProfile) =>

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

@ -22,6 +22,5 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
bool NormalizeLoudness, bool NormalizeLoudness,
int AudioChannels, int AudioChannels,
int AudioSampleRate, int AudioSampleRate,
bool NormalizeAudio, bool NormalizeAudio) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
string FrameRate) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
} }

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

@ -48,7 +48,6 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
p.AudioChannels = update.AudioChannels; p.AudioChannels = update.AudioChannels;
p.AudioSampleRate = update.AudioSampleRate; p.AudioSampleRate = update.AudioSampleRate;
p.NormalizeAudio = update.NormalizeAudio; p.NormalizeAudio = update.NormalizeAudio;
p.FrameRate = update.FrameRate;
await _ffmpegProfileRepository.Update(p); await _ffmpegProfileRepository.Update(p);
return ProjectToViewModel(p); return ProjectToViewModel(p);
} }

3
ErsatzTV.Application/FFmpegProfiles/FFmpegProfileViewModel.cs

@ -20,6 +20,5 @@ namespace ErsatzTV.Application.FFmpegProfiles
bool NormalizeLoudness, bool NormalizeLoudness,
int AudioChannels, int AudioChannels,
int AudioSampleRate, int AudioSampleRate,
bool NormalizeAudio, bool NormalizeAudio);
string FrameRate);
} }

3
ErsatzTV.Application/FFmpegProfiles/Mapper.cs

@ -23,8 +23,7 @@ namespace ErsatzTV.Application.FFmpegProfiles
profile.NormalizeLoudness, profile.NormalizeLoudness,
profile.AudioChannels, profile.AudioChannels,
profile.AudioSampleRate, profile.AudioSampleRate,
profile.NormalizeAudio, profile.NormalizeAudio);
profile.FrameRate);
private static ResolutionViewModel Project(Resolution resolution) => private static ResolutionViewModel Project(Resolution resolution) =>
new(resolution.Id, resolution.Name, resolution.Width, resolution.Height); new(resolution.Id, resolution.Name, resolution.Width, resolution.Height);

30
ErsatzTV.Core.Tests/FFmpeg/FFmpegPlaybackSettingsCalculatorTests.cs

@ -467,36 +467,6 @@ namespace ErsatzTV.Core.Tests.FFmpeg
actual.VideoCodec.Should().Be("copy"); actual.VideoCodec.Should().Be("copy");
} }
[Test]
public void
Should_SetCorrectVideoCodec_When_ContentIsCorrectSize_And_CorrectCodec_And_Framerate_ForTransportStream()
{
var ffmpegProfile = new FFmpegProfile
{
NormalizeVideo = true,
Resolution = new Resolution { Width = 1920, Height = 1080 },
VideoCodec = "libx264",
FrameRate = "24"
};
// not anamorphic
var version = new MediaVersion
{ Width = 1920, Height = 1080, SampleAspectRatio = "1:1" };
FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
StreamingMode.TransportStream,
ffmpegProfile,
version,
new MediaStream { Codec = "libx264" },
new MediaStream(),
DateTimeOffset.Now,
DateTimeOffset.Now);
actual.ScaledSize.IsNone.Should().BeTrue();
actual.PadToDesiredResolution.Should().BeFalse();
actual.VideoCodec.Should().Be("libx264");
}
[Test] [Test]
public void public void
Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NotNormalizingVideo_ForTransportStream() Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NotNormalizingVideo_ForTransportStream()

2
ErsatzTV.Core/Domain/FFmpegProfile.cs

@ -13,7 +13,6 @@
public bool NormalizeVideo { get; set; } public bool NormalizeVideo { get; set; }
public int VideoBitrate { get; set; } public int VideoBitrate { get; set; }
public int VideoBufferSize { get; set; } public int VideoBufferSize { get; set; }
public string FrameRate { get; set; }
public string AudioCodec { get; set; } public string AudioCodec { get; set; }
public int AudioBitrate { get; set; } public int AudioBitrate { get; set; }
public int AudioBufferSize { get; set; } public int AudioBufferSize { get; set; }
@ -40,7 +39,6 @@
AudioChannels = 2, AudioChannels = 2,
AudioSampleRate = 48, AudioSampleRate = 48,
NormalizeVideo = true, NormalizeVideo = true,
FrameRate = "24",
NormalizeAudio = true NormalizeAudio = true
}; };
} }

9
ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs

@ -13,7 +13,6 @@ namespace ErsatzTV.Core.FFmpeg
{ {
private Option<TimeSpan> _audioDuration = None; private Option<TimeSpan> _audioDuration = None;
private bool _deinterlace; private bool _deinterlace;
private Option<string> _frameRate = None;
private Option<HardwareAccelerationKind> _hardwareAccelerationKind = None; private Option<HardwareAccelerationKind> _hardwareAccelerationKind = None;
private string _inputCodec; private string _inputCodec;
private bool _normalizeLoudness; private bool _normalizeLoudness;
@ -62,12 +61,6 @@ namespace ErsatzTV.Core.FFmpeg
return this; return this;
} }
public FFmpegComplexFilterBuilder WithFrameRate(Option<string> frameRate)
{
_frameRate = frameRate;
return this;
}
public Option<FFmpegComplexFilter> Build(int videoStreamIndex, Option<int> audioStreamIndex) public Option<FFmpegComplexFilter> Build(int videoStreamIndex, Option<int> audioStreamIndex)
{ {
var complexFilter = new StringBuilder(); var complexFilter = new StringBuilder();
@ -118,8 +111,6 @@ namespace ErsatzTV.Core.FFmpeg
} }
} }
_frameRate.IfSome(frameRate => videoFilterQueue.Add($"fps=fps={frameRate}"));
_scaleToSize.IfSome( _scaleToSize.IfSome(
size => size =>
{ {

1
ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettings.cs

@ -26,7 +26,6 @@ namespace ErsatzTV.Core.FFmpeg
public Option<TimeSpan> AudioDuration { get; set; } public Option<TimeSpan> AudioDuration { get; set; }
public string AudioCodec { get; set; } public string AudioCodec { get; set; }
public bool Deinterlace { get; set; } public bool Deinterlace { get; set; }
public Option<string> FrameRate { get; set; }
public Option<int> VideoTrackTimeScale { get; set; } public Option<int> VideoTrackTimeScale { get; set; }
public bool NormalizeLoudness { get; set; } public bool NormalizeLoudness { get; set; }
} }

6
ErsatzTV.Core/FFmpeg/FFmpegPlaybackSettingsCalculator.cs

@ -92,15 +92,11 @@ namespace ErsatzTV.Core.FFmpeg
if (ffmpegProfile.NormalizeVideo) if (ffmpegProfile.NormalizeVideo)
{ {
result.FrameRate = string.IsNullOrWhiteSpace(ffmpegProfile.FrameRate)
? None
: Some(ffmpegProfile.FrameRate);
result.VideoTrackTimeScale = 90000; result.VideoTrackTimeScale = 90000;
} }
if (result.ScaledSize.IsSome || result.PadToDesiredResolution || if (result.ScaledSize.IsSome || result.PadToDesiredResolution ||
NeedToNormalizeVideoCodec(ffmpegProfile, videoStream) || result.FrameRate.IsSome) NeedToNormalizeVideoCodec(ffmpegProfile, videoStream))
{ {
result.VideoCodec = ffmpegProfile.VideoCodec; result.VideoCodec = ffmpegProfile.VideoCodec;
result.VideoBitrate = ffmpegProfile.VideoBitrate; result.VideoBitrate = ffmpegProfile.VideoBitrate;

6
ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs

@ -332,12 +332,6 @@ namespace ErsatzTV.Core.FFmpeg
return this; return this;
} }
public FFmpegProcessBuilder WithFrameRate(Option<string> frameRate)
{
_complexFilterBuilder = _complexFilterBuilder.WithFrameRate(frameRate);
return this;
}
public FFmpegProcessBuilder WithVideoTrackTimeScale(Option<int> videoTrackTimeScale) public FFmpegProcessBuilder WithVideoTrackTimeScale(Option<int> videoTrackTimeScale)
{ {
videoTrackTimeScale.IfSome( videoTrackTimeScale.IfSome(

1
ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs

@ -50,7 +50,6 @@ namespace ErsatzTV.Core.FFmpeg
.WithRealtimeOutput(playbackSettings.RealtimeOutput) .WithRealtimeOutput(playbackSettings.RealtimeOutput)
.WithSeek(playbackSettings.StreamSeek) .WithSeek(playbackSettings.StreamSeek)
.WithInputCodec(path, playbackSettings.HardwareAcceleration, videoStream.Codec) .WithInputCodec(path, playbackSettings.HardwareAcceleration, videoStream.Codec)
.WithFrameRate(playbackSettings.FrameRate)
.WithVideoTrackTimeScale(playbackSettings.VideoTrackTimeScale) .WithVideoTrackTimeScale(playbackSettings.VideoTrackTimeScale)
.WithAlignedAudio(playbackSettings.AudioDuration) .WithAlignedAudio(playbackSettings.AudioDuration)
.WithNormalizeLoudness(playbackSettings.NormalizeLoudness); .WithNormalizeLoudness(playbackSettings.NormalizeLoudness);

2886
ErsatzTV.Infrastructure/Migrations/20210611214836_Remove_FFmpegProfileFrameRate.Designer.cs generated

File diff suppressed because it is too large Load Diff

23
ErsatzTV.Infrastructure/Migrations/20210611214836_Remove_FFmpegProfileFrameRate.cs

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

3
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -406,9 +406,6 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int>("AudioSampleRate") b.Property<int>("AudioSampleRate")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("FrameRate")
.HasColumnType("TEXT");
b.Property<int>("HardwareAcceleration") b.Property<int>("HardwareAcceleration")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");

3
ErsatzTV/Pages/FFmpegEditor.razor

@ -58,9 +58,6 @@
} }
</MudSelect> </MudSelect>
</MudElement> </MudElement>
<MudElement HtmlTag="div" Class="mt-3">
<MudTextField Disabled="@(!_model.Transcode)" Label="Frame Rate" @bind-Value="_model.FrameRate" For="@(() => _model.FrameRate)" Adornment="Adornment.End" AdornmentText="fps"/>
</MudElement>
<MudElement HtmlTag="div" Class="mt-3"> <MudElement HtmlTag="div" Class="mt-3">
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Video" @bind-Checked="@_model.NormalizeVideo" For="@(() => _model.NormalizeVideo)"/> <MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Video" @bind-Checked="@_model.NormalizeVideo" For="@(() => _model.NormalizeVideo)"/>
</MudElement> </MudElement>

8
ErsatzTV/ViewModels/FFmpegProfileEditViewModel.cs

@ -30,7 +30,6 @@ namespace ErsatzTV.ViewModels
VideoBitrate = viewModel.VideoBitrate; VideoBitrate = viewModel.VideoBitrate;
VideoBufferSize = viewModel.VideoBufferSize; VideoBufferSize = viewModel.VideoBufferSize;
VideoCodec = viewModel.VideoCodec; VideoCodec = viewModel.VideoCodec;
FrameRate = viewModel.FrameRate;
} }
public int AudioBitrate { get; set; } public int AudioBitrate { get; set; }
@ -50,7 +49,6 @@ namespace ErsatzTV.ViewModels
public int VideoBitrate { get; set; } public int VideoBitrate { get; set; }
public int VideoBufferSize { get; set; } public int VideoBufferSize { get; set; }
public string VideoCodec { get; set; } public string VideoCodec { get; set; }
public string FrameRate { get; set; }
public CreateFFmpegProfile ToCreate() => public CreateFFmpegProfile ToCreate() =>
new( new(
@ -69,8 +67,7 @@ namespace ErsatzTV.ViewModels
NormalizeLoudness, NormalizeLoudness,
AudioChannels, AudioChannels,
AudioSampleRate, AudioSampleRate,
NormalizeAudio, NormalizeAudio
FrameRate
); );
public UpdateFFmpegProfile ToUpdate() => public UpdateFFmpegProfile ToUpdate() =>
@ -91,8 +88,7 @@ namespace ErsatzTV.ViewModels
NormalizeLoudness, NormalizeLoudness,
AudioChannels, AudioChannels,
AudioSampleRate, AudioSampleRate,
NormalizeAudio, NormalizeAudio
FrameRate
); );
} }
} }

Loading…
Cancel
Save