mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-12-27 18:06:43 +00:00
Add MediaStream.ReferenceFrameRate for problematic video files (#12603)
Co-authored-by: Nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
parent
57452d65ef
commit
5a8a19e07b
|
@ -738,7 +738,7 @@ public class DynamicHlsHelper
|
||||||
{
|
{
|
||||||
var width = state.VideoStream.Width ?? 0;
|
var width = state.VideoStream.Width ?? 0;
|
||||||
var height = state.VideoStream.Height ?? 0;
|
var height = state.VideoStream.Height ?? 0;
|
||||||
var framerate = state.VideoStream.AverageFrameRate ?? 30;
|
var framerate = state.VideoStream.ReferenceFrameRate ?? 30;
|
||||||
var bitDepth = state.VideoStream.BitDepth ?? 8;
|
var bitDepth = state.VideoStream.BitDepth ?? 8;
|
||||||
return HlsCodecStringHelpers.GetVp9String(
|
return HlsCodecStringHelpers.GetVp9String(
|
||||||
width,
|
width,
|
||||||
|
|
|
@ -1534,7 +1534,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
|
||||||
if (maxrate.HasValue && state.VideoStream is not null)
|
if (maxrate.HasValue && state.VideoStream is not null)
|
||||||
{
|
{
|
||||||
var contentRate = state.VideoStream.AverageFrameRate ?? state.VideoStream.RealFrameRate;
|
var contentRate = state.VideoStream.ReferenceFrameRate;
|
||||||
|
|
||||||
if (contentRate.HasValue && contentRate.Value > maxrate.Value)
|
if (contentRate.HasValue && contentRate.Value > maxrate.Value)
|
||||||
{
|
{
|
||||||
|
@ -2218,7 +2218,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
var requestedFramerate = request.MaxFramerate ?? request.Framerate;
|
var requestedFramerate = request.MaxFramerate ?? request.Framerate;
|
||||||
if (requestedFramerate.HasValue)
|
if (requestedFramerate.HasValue)
|
||||||
{
|
{
|
||||||
var videoFrameRate = videoStream.AverageFrameRate ?? videoStream.RealFrameRate;
|
var videoFrameRate = videoStream.ReferenceFrameRate;
|
||||||
|
|
||||||
if (!videoFrameRate.HasValue || videoFrameRate.Value > requestedFramerate.Value)
|
if (!videoFrameRate.HasValue || videoFrameRate.Value > requestedFramerate.Value)
|
||||||
{
|
{
|
||||||
|
@ -3234,7 +3234,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
|
||||||
public static string GetSwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options)
|
public static string GetSwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options)
|
||||||
{
|
{
|
||||||
var doubleRateDeint = options.DeinterlaceDoubleRate && state.VideoStream?.AverageFrameRate <= 30;
|
var doubleRateDeint = options.DeinterlaceDoubleRate && state.VideoStream?.ReferenceFrameRate <= 30;
|
||||||
return string.Format(
|
return string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
"{0}={1}:-1:0",
|
"{0}={1}:-1:0",
|
||||||
|
@ -3244,7 +3244,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
|
|
||||||
public string GetHwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options, string hwDeintSuffix)
|
public string GetHwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options, string hwDeintSuffix)
|
||||||
{
|
{
|
||||||
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.AverageFrameRate ?? 60) <= 30;
|
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.ReferenceFrameRate ?? 60) <= 30;
|
||||||
if (hwDeintSuffix.Contains("cuda", StringComparison.OrdinalIgnoreCase))
|
if (hwDeintSuffix.Contains("cuda", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var useBwdif = string.Equals(options.DeinterlaceMethod, "bwdif", StringComparison.OrdinalIgnoreCase)
|
var useBwdif = string.Equals(options.DeinterlaceMethod, "bwdif", StringComparison.OrdinalIgnoreCase)
|
||||||
|
@ -3598,7 +3598,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
var isSwEncoder = !isNvencEncoder;
|
var isSwEncoder = !isNvencEncoder;
|
||||||
var isCuInCuOut = isNvDecoder && isNvencEncoder;
|
var isCuInCuOut = isNvDecoder && isNvencEncoder;
|
||||||
|
|
||||||
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.AverageFrameRate ?? 60) <= 30;
|
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.ReferenceFrameRate ?? 60) <= 30;
|
||||||
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
|
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
|
||||||
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
|
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
|
||||||
var doDeintH2645 = doDeintH264 || doDeintHevc;
|
var doDeintH2645 = doDeintH264 || doDeintHevc;
|
||||||
|
|
|
@ -305,7 +305,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
if (BaseRequest.Static
|
if (BaseRequest.Static
|
||||||
|| EncodingHelper.IsCopyCodec(OutputVideoCodec))
|
|| EncodingHelper.IsCopyCodec(OutputVideoCodec))
|
||||||
{
|
{
|
||||||
return VideoStream is null ? null : (VideoStream.AverageFrameRate ?? VideoStream.RealFrameRate);
|
return VideoStream?.ReferenceFrameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BaseRequest.MaxFramerate ?? BaseRequest.Framerate;
|
return BaseRequest.MaxFramerate ?? BaseRequest.Framerate;
|
||||||
|
|
|
@ -810,7 +810,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
if (options.AllowVideoStreamCopy)
|
if (options.AllowVideoStreamCopy)
|
||||||
{
|
{
|
||||||
// prefer direct copy profile
|
// prefer direct copy profile
|
||||||
float videoFramerate = videoStream?.AverageFrameRate ?? videoStream?.RealFrameRate ?? 0;
|
float videoFramerate = videoStream?.ReferenceFrameRate ?? 0;
|
||||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
||||||
int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio);
|
int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio);
|
||||||
int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video);
|
int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video);
|
||||||
|
@ -875,7 +875,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem.VideoCodecs = videoCodecs;
|
playlistItem.VideoCodecs = videoCodecs;
|
||||||
|
|
||||||
// Copy video codec options as a starting point, this applies to transcode and direct-stream
|
// Copy video codec options as a starting point, this applies to transcode and direct-stream
|
||||||
playlistItem.MaxFramerate = videoStream?.AverageFrameRate;
|
playlistItem.MaxFramerate = videoStream?.ReferenceFrameRate;
|
||||||
var qualifier = videoStream?.Codec;
|
var qualifier = videoStream?.Codec;
|
||||||
if (videoStream?.Level is not null)
|
if (videoStream?.Level is not null)
|
||||||
{
|
{
|
||||||
|
@ -949,7 +949,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
double? videoLevel = videoStream?.Level;
|
double? videoLevel = videoStream?.Level;
|
||||||
string? videoProfile = videoStream?.Profile;
|
string? videoProfile = videoStream?.Profile;
|
||||||
VideoRangeType? videoRangeType = videoStream?.VideoRangeType;
|
VideoRangeType? videoRangeType = videoStream?.VideoRangeType;
|
||||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
float videoFramerate = videoStream is null ? 0 : videoStream.ReferenceFrameRate ?? 0;
|
||||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string? videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
|
@ -1208,7 +1208,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
double? videoLevel = videoStream?.Level;
|
double? videoLevel = videoStream?.Level;
|
||||||
string? videoProfile = videoStream?.Profile;
|
string? videoProfile = videoStream?.Profile;
|
||||||
VideoRangeType? videoRangeType = videoStream?.VideoRangeType;
|
VideoRangeType? videoRangeType = videoStream?.VideoRangeType;
|
||||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
float videoFramerate = videoStream is null ? 0 : videoStream.ReferenceFrameRate ?? 0;
|
||||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string? videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
|
|
|
@ -217,7 +217,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
var stream = TargetVideoStream;
|
var stream = TargetVideoStream;
|
||||||
return MaxFramerate.HasValue && !IsDirectStream
|
return MaxFramerate.HasValue && !IsDirectStream
|
||||||
? MaxFramerate
|
? MaxFramerate
|
||||||
: stream is null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
|
: stream?.ReferenceFrameRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -525,6 +525,23 @@ namespace MediaBrowser.Model.Entities
|
||||||
/// <value>The real frame rate.</value>
|
/// <value>The real frame rate.</value>
|
||||||
public float? RealFrameRate { get; set; }
|
public float? RealFrameRate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the framerate used as reference.
|
||||||
|
/// Prefer AverageFrameRate, if that is null or an unrealistic value
|
||||||
|
/// then fallback to RealFrameRate.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The reference frame rate.</value>
|
||||||
|
public float? ReferenceFrameRate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// In some cases AverageFrameRate for videos will be read as 1000fps even if it is not.
|
||||||
|
// This is probably due to a library compatability issue.
|
||||||
|
// See https://github.com/jellyfin/jellyfin/pull/12603#discussion_r1748044018 for more info.
|
||||||
|
return AverageFrameRate < 1000 ? AverageFrameRate : RealFrameRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the profile.
|
/// Gets or sets the profile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
writer.WriteElementString("aspectratio", stream.AspectRatio);
|
writer.WriteElementString("aspectratio", stream.AspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
var framerate = stream.AverageFrameRate ?? stream.RealFrameRate;
|
var framerate = stream.ReferenceFrameRate;
|
||||||
|
|
||||||
if (framerate.HasValue)
|
if (framerate.HasValue)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue