Browse Source

fix vaapi pipeline with mpeg4 content (#51)

pull/1213/head
Jason Dove 5 years ago committed by GitHub
parent
commit
e874e0e53b
  1. 53
      ErsatzTV.Core.Tests/FFmpeg/FFmpegComplexFilterBuilderTests.cs
  2. 1
      ErsatzTV.Core/Domain/MediaItem/MediaVersion.cs
  3. 23
      ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs
  4. 2
      ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
  5. 3
      ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs
  6. 1497
      ErsatzTV.Infrastructure/Migrations/20210308215756_Add_MediaVersionVideoProfile.Designer.cs
  7. 19
      ErsatzTV.Infrastructure/Migrations/20210308215756_Add_MediaVersionVideoProfile.cs
  8. 1497
      ErsatzTV.Infrastructure/Migrations/20210308215926_Reset_MediaVersionDateUpdated.Designer.cs
  9. 14
      ErsatzTV.Infrastructure/Migrations/20210308215926_Reset_MediaVersionDateUpdated.cs
  10. 3
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  11. 1
      ErsatzTV.Infrastructure/Plex/Models/PlexMediaResponse.cs
  12. 1
      ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs

53
ErsatzTV.Core.Tests/FFmpeg/FFmpegComplexFilterBuilderTests.cs

@ -275,44 +275,94 @@ namespace ErsatzTV.Core.Tests.FFmpeg @@ -275,44 +275,94 @@ namespace ErsatzTV.Core.Tests.FFmpeg
}
[Test]
[TestCase(true, false, false, "[0:v]deinterlace_vaapi[v]", "[v]")]
[TestCase("h264", true, false, false, "[0:v]deinterlace_vaapi[v]", "[v]")]
[TestCase(
"h264",
true,
true,
false,
"[0:v]deinterlace_vaapi,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,hwupload[v]",
"[v]")]
[TestCase(
"h264",
true,
false,
true,
"[0:v]deinterlace_vaapi,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"h264",
true,
true,
true,
"[0:v]deinterlace_vaapi,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"h264",
false,
true,
false,
"[0:v]scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,hwupload[v]",
"[v]")]
[TestCase(
"h264",
false,
false,
true,
"[0:v]hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"h264",
false,
true,
true,
"[0:v]scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase("mpeg4", true, false, false, "[0:v]hwupload,deinterlace_vaapi[v]", "[v]")]
[TestCase(
"mpeg4",
true,
true,
false,
"[0:v]hwupload,deinterlace_vaapi,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,hwupload[v]",
"[v]")]
[TestCase(
"mpeg4",
true,
false,
true,
"[0:v]hwupload,deinterlace_vaapi,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"mpeg4",
true,
true,
true,
"[0:v]hwupload,deinterlace_vaapi,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"mpeg4",
false,
true,
false,
"[0:v]hwupload,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,hwupload[v]",
"[v]")]
[TestCase(
"mpeg4",
false,
false,
true,
"[0:v]setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
[TestCase(
"mpeg4",
false,
true,
true,
"[0:v]hwupload,scale_vaapi=w=1920:h=1000,hwdownload,format=nv12|vaapi,setsar=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,hwupload[v]",
"[v]")]
public void Should_Return_VAAPI_Video_Filter(
string codec,
bool deinterlace,
bool scale,
bool pad,
@ -321,6 +371,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg @@ -321,6 +371,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
{
FFmpegComplexFilterBuilder builder = new FFmpegComplexFilterBuilder()
.WithHardwareAcceleration(HardwareAccelerationKind.Vaapi)
.WithInputCodec(codec)
.WithDeinterlace(deinterlace);
if (scale)

1
ErsatzTV.Core/Domain/MediaItem/MediaVersion.cs

@ -15,6 +15,7 @@ namespace ErsatzTV.Core.Domain @@ -15,6 +15,7 @@ namespace ErsatzTV.Core.Domain
public string SampleAspectRatio { get; set; }
public string DisplayAspectRatio { get; set; }
public string VideoCodec { get; set; }
public string VideoProfile { get; set; }
public string AudioCodec { get; set; }
public VideoScanKind VideoScanKind { get; set; }
public DateTime DateAdded { get; set; }

23
ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs

@ -14,6 +14,7 @@ namespace ErsatzTV.Core.FFmpeg @@ -14,6 +14,7 @@ namespace ErsatzTV.Core.FFmpeg
private Option<TimeSpan> _audioDuration = None;
private bool _deinterlace;
private Option<HardwareAccelerationKind> _hardwareAccelerationKind = None;
private string _inputCodec;
private Option<IDisplaySize> _padToSize = None;
private Option<IDisplaySize> _scaleToSize = None;
@ -47,6 +48,12 @@ namespace ErsatzTV.Core.FFmpeg @@ -47,6 +48,12 @@ namespace ErsatzTV.Core.FFmpeg
return this;
}
public FFmpegComplexFilterBuilder WithInputCodec(string codec)
{
_inputCodec = codec;
return this;
}
public Option<FFmpegComplexFilter> Build()
{
var complexFilter = new StringBuilder();
@ -55,6 +62,13 @@ namespace ErsatzTV.Core.FFmpeg @@ -55,6 +62,13 @@ namespace ErsatzTV.Core.FFmpeg
var audioLabel = "0:a";
HardwareAccelerationKind acceleration = _hardwareAccelerationKind.IfNone(HardwareAccelerationKind.None);
bool isHardwareDecode = acceleration switch
{
HardwareAccelerationKind.Vaapi => _inputCodec != "mpeg4",
HardwareAccelerationKind.Nvenc => true,
HardwareAccelerationKind.Qsv => true,
_ => false
};
_audioDuration.IfSome(
audioDuration =>
@ -67,6 +81,13 @@ namespace ErsatzTV.Core.FFmpeg @@ -67,6 +81,13 @@ namespace ErsatzTV.Core.FFmpeg
var filterQueue = new List<string>();
bool usesHardwareFilters = acceleration != HardwareAccelerationKind.None && !isHardwareDecode &&
(_deinterlace || _scaleToSize.IsSome);
if (usesHardwareFilters)
{
filterQueue.Add("hwupload");
}
if (_deinterlace)
{
string filter = acceleration switch
@ -102,7 +123,7 @@ namespace ErsatzTV.Core.FFmpeg @@ -102,7 +123,7 @@ namespace ErsatzTV.Core.FFmpeg
if (_scaleToSize.IsSome || _padToSize.IsSome)
{
if (acceleration != HardwareAccelerationKind.None)
if (acceleration != HardwareAccelerationKind.None && (isHardwareDecode || usesHardwareFilters))
{
filterQueue.Add("hwdownload");
string format = acceleration switch

2
ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs

@ -153,6 +153,8 @@ namespace ErsatzTV.Core.FFmpeg @@ -153,6 +153,8 @@ namespace ErsatzTV.Core.FFmpeg
_arguments.Add(qsvCodec);
}
_complexFilterBuilder = _complexFilterBuilder.WithInputCodec(codec);
_arguments.Add("-i");
_arguments.Add($"{input}");
return this;

3
ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs

@ -70,6 +70,7 @@ namespace ErsatzTV.Core.Metadata @@ -70,6 +70,7 @@ namespace ErsatzTV.Core.Metadata
mediaItemVersion.Width = version.Width;
mediaItemVersion.Height = version.Height;
mediaItemVersion.VideoCodec = version.VideoCodec;
mediaItemVersion.VideoProfile = version.VideoProfile;
mediaItemVersion.VideoScanKind = version.VideoScanKind;
return await _mediaItemRepository.Update(mediaItem) && durationChange;
@ -134,6 +135,7 @@ namespace ErsatzTV.Core.Metadata @@ -134,6 +135,7 @@ namespace ErsatzTV.Core.Metadata
version.Width = videoStream.width;
version.Height = videoStream.height;
version.VideoCodec = videoStream.codec_name;
version.VideoProfile = (videoStream.profile ?? string.Empty).ToLowerInvariant();
version.VideoScanKind = ScanKindFromFieldOrder(videoStream.field_order);
}
@ -157,6 +159,7 @@ namespace ErsatzTV.Core.Metadata @@ -157,6 +159,7 @@ namespace ErsatzTV.Core.Metadata
public record FFprobeStream(
int index,
string codec_name,
string profile,
string codec_type,
int width,
int height,

1497
ErsatzTV.Infrastructure/Migrations/20210308215756_Add_MediaVersionVideoProfile.Designer.cs generated

File diff suppressed because it is too large Load Diff

19
ErsatzTV.Infrastructure/Migrations/20210308215756_Add_MediaVersionVideoProfile.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Add_MediaVersionVideoProfile : Migration
{
protected override void Up(MigrationBuilder migrationBuilder) =>
migrationBuilder.AddColumn<string>(
"VideoProfile",
"MediaVersion",
"TEXT",
nullable: true);
protected override void Down(MigrationBuilder migrationBuilder) =>
migrationBuilder.DropColumn(
"VideoProfile",
"MediaVersion");
}
}

1497
ErsatzTV.Infrastructure/Migrations/20210308215926_Reset_MediaVersionDateUpdated.Designer.cs generated

File diff suppressed because it is too large Load Diff

14
ErsatzTV.Infrastructure/Migrations/20210308215926_Reset_MediaVersionDateUpdated.cs

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Reset_MediaVersionDateUpdated : Migration
{
protected override void Up(MigrationBuilder migrationBuilder) =>
migrationBuilder.Sql(@"UPDATE MediaVersion SET DateUpdated = '0001-01-01 00:00:00'");
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

3
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -418,6 +418,9 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -418,6 +418,9 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<string>("VideoCodec")
.HasColumnType("TEXT");
b.Property<string>("VideoProfile")
.HasColumnType("TEXT");
b.Property<int>("VideoScanKind")
.HasColumnType("INTEGER");

1
ErsatzTV.Infrastructure/Plex/Models/PlexMediaResponse.cs

@ -13,6 +13,7 @@ namespace ErsatzTV.Infrastructure.Plex.Models @@ -13,6 +13,7 @@ namespace ErsatzTV.Infrastructure.Plex.Models
public int AudioChannels { get; set; }
public string AudioCodec { get; set; }
public string VideoCodec { get; set; }
public string VideoProfile { get; set; }
public string Container { get; set; }
public string VideoFrameRate { get; set; }
public List<PlexPartResponse> Part { get; set; }

1
ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs

@ -125,6 +125,7 @@ namespace ErsatzTV.Infrastructure.Plex @@ -125,6 +125,7 @@ namespace ErsatzTV.Infrastructure.Plex
Height = media.Height,
AudioCodec = media.AudioCodec,
VideoCodec = media.VideoCodec,
VideoProfile = media.VideoProfile,
SampleAspectRatio = ConvertToSAR(media.AspectRatio),
MediaFiles = new List<MediaFile>
{

Loading…
Cancel
Save