123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751 |
- #nullable disable
- #pragma warning disable CS1591, SA1401
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Globalization;
- using System.Linq;
- using Jellyfin.Data.Enums;
- using Jellyfin.Database.Implementations.Entities;
- using MediaBrowser.Model.Dlna;
- using MediaBrowser.Model.Drawing;
- using MediaBrowser.Model.Dto;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.Model.MediaInfo;
- using MediaBrowser.Model.Net;
- using MediaBrowser.Model.Session;
- namespace MediaBrowser.Controller.MediaEncoding
- {
- // For now, a common base class until the API and MediaEncoding classes are unified
- public class EncodingJobInfo
- {
- public int? OutputAudioBitrate;
- public int? OutputAudioChannels;
- private TranscodeReason? _transcodeReasons = null;
- public EncodingJobInfo(TranscodingJobType jobType)
- {
- TranscodingType = jobType;
- RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- SupportedAudioCodecs = Array.Empty<string>();
- SupportedVideoCodecs = Array.Empty<string>();
- SupportedSubtitleCodecs = Array.Empty<string>();
- }
- public TranscodeReason TranscodeReasons
- {
- get
- {
- if (!_transcodeReasons.HasValue)
- {
- if (BaseRequest.TranscodeReasons is null)
- {
- _transcodeReasons = 0;
- return 0;
- }
- _ = Enum.TryParse<TranscodeReason>(BaseRequest.TranscodeReasons, out var reason);
- _transcodeReasons = reason;
- }
- return _transcodeReasons.Value;
- }
- }
- public IProgress<double> Progress { get; set; }
- public MediaStream VideoStream { get; set; }
- public VideoType VideoType { get; set; }
- public Dictionary<string, string> RemoteHttpHeaders { get; set; }
- public string OutputVideoCodec { get; set; }
- public MediaProtocol InputProtocol { get; set; }
- public string MediaPath { get; set; }
- public bool IsInputVideo { get; set; }
- public string OutputAudioCodec { get; set; }
- public int? OutputVideoBitrate { get; set; }
- public MediaStream SubtitleStream { get; set; }
- public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; }
- public string[] SupportedSubtitleCodecs { get; set; }
- public int InternalSubtitleStreamOffset { get; set; }
- public MediaSourceInfo MediaSource { get; set; }
- public User User { get; set; }
- public long? RunTimeTicks { get; set; }
- public bool ReadInputAtNativeFramerate { get; set; }
- public string OutputFilePath { get; set; }
- public string MimeType { get; set; }
- public bool IgnoreInputDts => MediaSource.IgnoreDts;
- public bool IgnoreInputIndex => MediaSource.IgnoreIndex;
- public bool GenPtsInput => MediaSource.GenPtsInput;
- public bool DiscardCorruptFramesInput => false;
- public bool EnableFastSeekInput => false;
- public bool GenPtsOutput => false;
- public string OutputContainer { get; set; }
- public string OutputVideoSync { get; set; }
- public string AlbumCoverPath { get; set; }
- public string InputAudioSync { get; set; }
- public string InputVideoSync { get; set; }
- public TransportStreamTimestamp InputTimestamp { get; set; }
- public MediaStream AudioStream { get; set; }
- public string[] SupportedAudioCodecs { get; set; }
- public string[] SupportedVideoCodecs { get; set; }
- public string InputContainer { get; set; }
- public IsoType? IsoType { get; set; }
- public BaseEncodingJobOptions BaseRequest { get; set; }
- public bool IsVideoRequest { get; set; }
- public TranscodingJobType TranscodingType { get; set; }
- public long? StartTimeTicks => BaseRequest.StartTimeTicks;
- public bool CopyTimestamps => BaseRequest.CopyTimestamps;
- public bool IsSegmentedLiveStream
- => TranscodingType != TranscodingJobType.Progressive && !RunTimeTicks.HasValue;
- public int? TotalOutputBitrate => (OutputAudioBitrate ?? 0) + (OutputVideoBitrate ?? 0);
- public int? OutputWidth
- {
- get
- {
- if (VideoStream is not null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
- {
- var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
- var newSize = DrawingUtils.Resize(
- size,
- BaseRequest.Width ?? 0,
- BaseRequest.Height ?? 0,
- BaseRequest.MaxWidth ?? 0,
- BaseRequest.MaxHeight ?? 0);
- return newSize.Width;
- }
- if (!IsVideoRequest)
- {
- return null;
- }
- return BaseRequest.MaxWidth ?? BaseRequest.Width;
- }
- }
- public int? OutputHeight
- {
- get
- {
- if (VideoStream is not null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
- {
- var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
- var newSize = DrawingUtils.Resize(
- size,
- BaseRequest.Width ?? 0,
- BaseRequest.Height ?? 0,
- BaseRequest.MaxWidth ?? 0,
- BaseRequest.MaxHeight ?? 0);
- return newSize.Height;
- }
- if (!IsVideoRequest)
- {
- return null;
- }
- return BaseRequest.MaxHeight ?? BaseRequest.Height;
- }
- }
- public int? OutputAudioSampleRate
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputAudioCodec))
- {
- if (AudioStream is not null)
- {
- return AudioStream.SampleRate;
- }
- }
- else if (BaseRequest.AudioSampleRate.HasValue)
- {
- // Don't exceed what the encoder supports
- // Seeing issues of attempting to encode to 88200
- return BaseRequest.AudioSampleRate.Value;
- }
- return null;
- }
- }
- public int? OutputAudioBitDepth
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputAudioCodec))
- {
- if (AudioStream is not null)
- {
- return AudioStream.BitDepth;
- }
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target video level.
- /// </summary>
- public double? TargetVideoLevel
- {
- get
- {
- if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.Level;
- }
- var level = GetRequestedLevel(ActualOutputVideoCodec);
- if (double.TryParse(level, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target video bit depth.
- /// </summary>
- public int? TargetVideoBitDepth
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.BitDepth;
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target reference frames.
- /// </summary>
- /// <value>The target reference frames.</value>
- public int? TargetRefFrames
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.RefFrames;
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target framerate.
- /// </summary>
- public float? TargetFramerate
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.ReferenceFrameRate;
- }
- return BaseRequest.MaxFramerate ?? BaseRequest.Framerate;
- }
- }
- public TransportStreamTimestamp TargetTimestamp
- {
- get
- {
- if (BaseRequest.Static)
- {
- return InputTimestamp;
- }
- return string.Equals(OutputContainer, "m2ts", StringComparison.OrdinalIgnoreCase) ?
- TransportStreamTimestamp.Valid :
- TransportStreamTimestamp.None;
- }
- }
- /// <summary>
- /// Gets the target packet length.
- /// </summary>
- public int? TargetPacketLength
- {
- get
- {
- if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.PacketLength;
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target video profile.
- /// </summary>
- public string TargetVideoProfile
- {
- get
- {
- if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.Profile;
- }
- var requestedProfile = GetRequestedProfiles(ActualOutputVideoCodec).FirstOrDefault();
- if (!string.IsNullOrEmpty(requestedProfile))
- {
- return requestedProfile;
- }
- return null;
- }
- }
- /// <summary>
- /// Gets the target video range type.
- /// </summary>
- public VideoRangeType TargetVideoRangeType
- {
- get
- {
- if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.VideoRangeType ?? VideoRangeType.Unknown;
- }
- if (Enum.TryParse(GetRequestedRangeTypes(ActualOutputVideoCodec).FirstOrDefault() ?? "Unknown", true, out VideoRangeType requestedRangeType))
- {
- return requestedRangeType;
- }
- return VideoRangeType.Unknown;
- }
- }
- public string TargetVideoCodecTag
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.CodecTag;
- }
- return null;
- }
- }
- public bool? IsTargetAnamorphic
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.IsAnamorphic;
- }
- return false;
- }
- }
- public string ActualOutputVideoCodec
- {
- get
- {
- if (VideoStream is null)
- {
- return null;
- }
- if (EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream.Codec;
- }
- return OutputVideoCodec;
- }
- }
- public string ActualOutputAudioCodec
- {
- get
- {
- if (AudioStream is null)
- {
- return null;
- }
- if (EncodingHelper.IsCopyCodec(OutputAudioCodec))
- {
- return AudioStream.Codec;
- }
- return OutputAudioCodec;
- }
- }
- public bool? IsTargetInterlaced
- {
- get
- {
- if (BaseRequest.Static
- || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.IsInterlaced;
- }
- if (DeInterlace(ActualOutputVideoCodec, true))
- {
- return false;
- }
- return VideoStream?.IsInterlaced;
- }
- }
- public bool? IsTargetAVC
- {
- get
- {
- if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec))
- {
- return VideoStream?.IsAVC;
- }
- return false;
- }
- }
- public int? TargetVideoStreamCount
- {
- get
- {
- if (BaseRequest.Static)
- {
- return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
- }
- return GetMediaStreamCount(MediaStreamType.Video, 1);
- }
- }
- public int? TargetAudioStreamCount
- {
- get
- {
- if (BaseRequest.Static)
- {
- return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
- }
- return GetMediaStreamCount(MediaStreamType.Audio, 1);
- }
- }
- public bool EnableAudioVbrEncoding => BaseRequest.EnableAudioVbrEncoding;
- public int HlsListSize => 0;
- public bool EnableBreakOnNonKeyFrames(string videoCodec)
- {
- if (TranscodingType != TranscodingJobType.Progressive)
- {
- if (IsSegmentedLiveStream)
- {
- return false;
- }
- return BaseRequest.BreakOnNonKeyFrames && EncodingHelper.IsCopyCodec(videoCodec);
- }
- return false;
- }
- private int? GetMediaStreamCount(MediaStreamType type, int limit)
- {
- var count = MediaSource.GetStreamCount(type);
- if (count.HasValue)
- {
- count = Math.Min(count.Value, limit);
- }
- return count;
- }
- public string GetMimeType(string outputPath, bool enableStreamDefault = true)
- {
- if (!string.IsNullOrEmpty(MimeType))
- {
- return MimeType;
- }
- if (enableStreamDefault)
- {
- return MimeTypes.GetMimeType(outputPath);
- }
- return MimeTypes.GetMimeType(outputPath, null);
- }
- public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterlaced)
- {
- var videoStream = VideoStream;
- var isInputInterlaced = videoStream is not null && videoStream.IsInterlaced;
- if (!isInputInterlaced)
- {
- return false;
- }
- // Support general param
- if (BaseRequest.DeInterlace)
- {
- return true;
- }
- if (!string.IsNullOrEmpty(videoCodec))
- {
- if (string.Equals(BaseRequest.GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
- return forceDeinterlaceIfSourceIsInterlaced;
- }
- public string[] GetRequestedProfiles(string codec)
- {
- if (!string.IsNullOrEmpty(BaseRequest.Profile))
- {
- return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var profile = BaseRequest.GetOption(codec, "profile");
- if (!string.IsNullOrEmpty(profile))
- {
- return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- }
- return Array.Empty<string>();
- }
- public string[] GetRequestedRangeTypes(string codec)
- {
- if (!string.IsNullOrEmpty(BaseRequest.VideoRangeType))
- {
- return BaseRequest.VideoRangeType.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var rangetype = BaseRequest.GetOption(codec, "rangetype");
- if (!string.IsNullOrEmpty(rangetype))
- {
- return rangetype.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- }
- return Array.Empty<string>();
- }
- public string[] GetRequestedCodecTags(string codec)
- {
- if (!string.IsNullOrEmpty(BaseRequest.CodecTag))
- {
- return BaseRequest.CodecTag.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var codectag = BaseRequest.GetOption(codec, "codectag");
- if (!string.IsNullOrEmpty(codectag))
- {
- return codectag.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
- }
- return Array.Empty<string>();
- }
- public string GetRequestedLevel(string codec)
- {
- if (!string.IsNullOrEmpty(BaseRequest.Level))
- {
- return BaseRequest.Level;
- }
- if (!string.IsNullOrEmpty(codec))
- {
- return BaseRequest.GetOption(codec, "level");
- }
- return null;
- }
- public int? GetRequestedMaxRefFrames(string codec)
- {
- if (BaseRequest.MaxRefFrames.HasValue)
- {
- return BaseRequest.MaxRefFrames;
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var value = BaseRequest.GetOption(codec, "maxrefframes");
- if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
- }
- return null;
- }
- public int? GetRequestedVideoBitDepth(string codec)
- {
- if (BaseRequest.MaxVideoBitDepth.HasValue)
- {
- return BaseRequest.MaxVideoBitDepth;
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var value = BaseRequest.GetOption(codec, "videobitdepth");
- if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
- }
- return null;
- }
- public int? GetRequestedAudioBitDepth(string codec)
- {
- if (BaseRequest.MaxAudioBitDepth.HasValue)
- {
- return BaseRequest.MaxAudioBitDepth;
- }
- if (!string.IsNullOrEmpty(codec))
- {
- var value = BaseRequest.GetOption(codec, "audiobitdepth");
- if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
- }
- return null;
- }
- public int? GetRequestedAudioChannels(string codec)
- {
- if (!string.IsNullOrEmpty(codec))
- {
- var value = BaseRequest.GetOption(codec, "audiochannels");
- if (int.TryParse(value, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
- }
- if (BaseRequest.MaxAudioChannels.HasValue)
- {
- return BaseRequest.MaxAudioChannels;
- }
- if (BaseRequest.AudioChannels.HasValue)
- {
- return BaseRequest.AudioChannels;
- }
- if (BaseRequest.TranscodingMaxAudioChannels.HasValue)
- {
- return BaseRequest.TranscodingMaxAudioChannels;
- }
- return null;
- }
- public virtual void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
- {
- Progress.Report(percentComplete.Value);
- }
- }
- }
|