mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* normalize bit depth and color for nvenc * fix hls direct * update changelog * add bit depth option to ffmpeg profilepull/1032/head
42 changed files with 13457 additions and 102 deletions
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
namespace ErsatzTV.Core.Domain; |
||||
|
||||
public enum FFmpegProfileBitDepth |
||||
{ |
||||
EightBit = 0, |
||||
TenBit = 1 |
||||
} |
||||
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
namespace ErsatzTV.FFmpeg; |
||||
|
||||
public record ColorParams(string ColorRange, string ColorSpace, string ColorTransfer, string ColorPrimaries) |
||||
{ |
||||
public static readonly ColorParams Default = new("tv", "bt709", "bt709", "bt709"); |
||||
|
||||
public bool IsHdr => ColorTransfer is "arib-std-b67" or "smpte2084"; |
||||
|
||||
public bool IsUnknown => string.IsNullOrWhiteSpace(ColorSpace) && |
||||
string.IsNullOrWhiteSpace(ColorTransfer) && |
||||
string.IsNullOrWhiteSpace(ColorPrimaries); |
||||
|
||||
public bool IsBt709 => this == Default; |
||||
} |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
using ErsatzTV.FFmpeg.Format; |
||||
|
||||
namespace ErsatzTV.FFmpeg.Filter; |
||||
|
||||
public class ColorspaceFilter : BaseFilter |
||||
{ |
||||
private readonly VideoStream _videoStream; |
||||
private readonly IPixelFormat _desiredPixelFormat; |
||||
|
||||
public ColorspaceFilter(VideoStream videoStream, IPixelFormat desiredPixelFormat) |
||||
{ |
||||
_videoStream = videoStream; |
||||
_desiredPixelFormat = desiredPixelFormat; |
||||
} |
||||
|
||||
public override FrameState NextState(FrameState currentState) => |
||||
currentState with |
||||
{ |
||||
PixelFormat = Some(_desiredPixelFormat), |
||||
FrameDataLocation = FrameDataLocation.Software |
||||
}; |
||||
|
||||
public override string Filter |
||||
{ |
||||
get |
||||
{ |
||||
string setParams = string.Empty; |
||||
if (_videoStream.ColorParams.IsUnknown) |
||||
{ |
||||
setParams = "setparams=range=tv:colorspace=bt709:color_trc=bt709:color_primaries=bt709"; |
||||
} |
||||
|
||||
string colorspace = _desiredPixelFormat.BitDepth switch |
||||
{ |
||||
10 when !_videoStream.ColorParams.IsUnknown => "colorspace=all=bt709:format=yuv420p10", |
||||
8 when !_videoStream.ColorParams.IsUnknown => "colorspace=all=bt709:format=yuv420p", |
||||
_ => string.Empty |
||||
}; |
||||
|
||||
return string.Join(',', new[] { setParams, colorspace }.Filter(s => !string.IsNullOrWhiteSpace(s))); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using ErsatzTV.FFmpeg.Format; |
||||
|
||||
namespace ErsatzTV.FFmpeg.Filter; |
||||
|
||||
public class TonemapFilter : BaseFilter |
||||
{ |
||||
private readonly FrameState _currentState; |
||||
private readonly IPixelFormat _desiredPixelFormat; |
||||
|
||||
public TonemapFilter(FrameState currentState, IPixelFormat desiredPixelFormat) |
||||
{ |
||||
_currentState = currentState; |
||||
_desiredPixelFormat = desiredPixelFormat; |
||||
} |
||||
|
||||
public override FrameState NextState(FrameState currentState) => |
||||
currentState with |
||||
{ |
||||
PixelFormat = Some(_desiredPixelFormat), |
||||
FrameDataLocation = FrameDataLocation.Software |
||||
}; |
||||
|
||||
public override string Filter |
||||
{ |
||||
get |
||||
{ |
||||
string pixelFormat = _currentState.PixelFormat.Match(pf => pf.FFmpegName, () => string.Empty); |
||||
|
||||
var tonemap = |
||||
$"setparams=colorspace=bt2020c,zscale=transfer=linear,tonemap=hable,zscale=transfer=bt709,format={_desiredPixelFormat.FFmpegName}"; |
||||
|
||||
if (_currentState.FrameDataLocation == FrameDataLocation.Hardware) |
||||
{ |
||||
if (!string.IsNullOrWhiteSpace(pixelFormat)) |
||||
{ |
||||
return $"hwdownload,format={pixelFormat},{tonemap}"; |
||||
} |
||||
|
||||
return $"hwdownload,{tonemap}"; |
||||
} |
||||
|
||||
return tonemap; |
||||
} |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
#nullable disable |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class Add_FFmpegProfileBitDepth : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.AddColumn<int>( |
||||
name: "BitDepth", |
||||
table: "FFmpegProfile", |
||||
type: "INTEGER", |
||||
nullable: false, |
||||
defaultValue: 0); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropColumn( |
||||
name: "BitDepth", |
||||
table: "FFmpegProfile"); |
||||
} |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
#nullable disable |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class Add_MediaStreamColor : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.AddColumn<string>( |
||||
name: "ColorPrimaries", |
||||
table: "MediaStream", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
|
||||
migrationBuilder.AddColumn<string>( |
||||
name: "ColorRange", |
||||
table: "MediaStream", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
|
||||
migrationBuilder.AddColumn<string>( |
||||
name: "ColorSpace", |
||||
table: "MediaStream", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
|
||||
migrationBuilder.AddColumn<string>( |
||||
name: "ColorTransfer", |
||||
table: "MediaStream", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropColumn( |
||||
name: "ColorPrimaries", |
||||
table: "MediaStream"); |
||||
|
||||
migrationBuilder.DropColumn( |
||||
name: "ColorRange", |
||||
table: "MediaStream"); |
||||
|
||||
migrationBuilder.DropColumn( |
||||
name: "ColorSpace", |
||||
table: "MediaStream"); |
||||
|
||||
migrationBuilder.DropColumn( |
||||
name: "ColorTransfer", |
||||
table: "MediaStream"); |
||||
} |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
#nullable disable |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class Reset_AllStatistics20221103 : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
// reset all statistics EXCEPT songs since they don't contain video streams
|
||||
|
||||
migrationBuilder.Sql("UPDATE MediaVersion SET DateUpdated = '0001-01-01 00:00:00' WHERE SongId IS NULL"); |
||||
migrationBuilder.Sql("UPDATE LibraryFolder SET Etag = NULL WHERE Id IN (SELECT LF.Id FROM LibraryFolder LF INNER JOIN LibraryPath LP on LP.Id = LF.LibraryPathId INNER JOIN Library L on L.Id = LP.LibraryId WHERE MediaKind != 5)"); |
||||
migrationBuilder.Sql("UPDATE EmbyMovie SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE EmbyShow SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE EmbySeason SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE EmbyEpisode SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE JellyfinMovie SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE JellyfinShow SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE JellyfinSeason SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE JellyfinEpisode SET Etag = NULL"); |
||||
migrationBuilder.Sql("UPDATE LibraryPath SET LastScan = '0001-01-01 00:00:00' WHERE Id IN (SELECT LP.Id FROM LibraryPath LP INNER JOIN Library L on L.Id = LP.LibraryId WHERE MediaKind != 5)"); |
||||
migrationBuilder.Sql("UPDATE Library SET LastScan = '0001-01-01 00:00:00' WHERE MediaKind != 5"); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue