aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs')
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs86
1 files changed, 53 insertions, 33 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index 8c0a7b0b5..32cd950af 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -42,8 +42,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
IFileSystem fileSystem,
IIsoManager isoManager,
ILibraryManager libraryManager,
- ISessionManager sessionManager,
- ISubtitleEncoder subtitleEncoder,
+ ISessionManager sessionManager,
+ ISubtitleEncoder subtitleEncoder,
IMediaSourceManager mediaSourceManager)
{
MediaEncoder = mediaEncoder;
@@ -71,12 +71,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
await AcquireResources(encodingJob, cancellationToken).ConfigureAwait(false);
- var commandLineArgs = GetCommandLineArguments(encodingJob);
-
- if (GetEncodingOptions().EnableDebugLogging)
- {
- commandLineArgs = "-loglevel debug " + commandLineArgs;
- }
+ var commandLineArgs = await GetCommandLineArguments(encodingJob).ConfigureAwait(false);
var process = new Process
{
@@ -86,7 +81,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
UseShellExecute = false,
// Must consume both stdout and stderr or deadlocks may occur
- RedirectStandardOutput = true,
+ //RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
@@ -136,15 +131,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
cancellationToken.Register(() => Cancel(process, encodingJob));
-
+
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
- process.BeginOutputReadLine();
+ //process.BeginOutputReadLine();
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
new JobLogger(Logger).StartStreamingLog(encodingJob, process.StandardError.BaseStream, encodingJob.LogFileStream);
// Wait for the file to exist before proceeeding
- while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
+ while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
{
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
@@ -269,11 +264,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
return ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
}
- protected abstract string GetCommandLineArguments(EncodingJob job);
+ protected abstract Task<string> GetCommandLineArguments(EncodingJob job);
private string GetOutputFilePath(EncodingJob state)
{
- var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ?
+ var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ?
ConfigurationManager.ApplicationPaths.TranscodingTempPath :
state.Options.OutputDirectory;
@@ -366,9 +361,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <returns>System.String.</returns>
protected string GetVideoDecoder(EncodingJob state)
{
- if (string.Equals(GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ // Only use alternative encoders for video files.
+ // When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
+ // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
+ if (state.VideoType != VideoType.VideoFile)
+ {
+ return null;
+ }
+
+ if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec))
{
- if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec))
+ if (string.Equals(GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
{
switch (state.MediaSource.VideoStream.Codec.ToLower())
{
@@ -376,6 +384,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
case "h264":
if (MediaEncoder.SupportsDecoder("h264_qsv"))
{
+ // Seeing stalls and failures with decoding. Not worth it compared to encoding.
return "-c:v h264_qsv ";
}
break;
@@ -535,7 +544,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="state">The state.</param>
/// <param name="outputVideoCodec">The output video codec.</param>
/// <returns>System.String.</returns>
- protected string GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
+ protected async Task<string> GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
{
var outputSizeParam = string.Empty;
@@ -544,7 +553,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Add resolution params, if specified
if (request.Width.HasValue || request.Height.HasValue || request.MaxHeight.HasValue || request.MaxWidth.HasValue)
{
- outputSizeParam = GetOutputSizeParam(state, outputVideoCodec).TrimEnd('"');
+ outputSizeParam = await GetOutputSizeParam(state, outputVideoCodec).ConfigureAwait(false);
+ outputSizeParam = outputSizeParam.TrimEnd('"');
outputSizeParam = "," + outputSizeParam.Substring(outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase));
}
@@ -605,10 +615,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
- // h264 (libnvenc)
- else if (string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase))
+ // h264 (h264_nvenc)
+ else if (string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
{
- param = "-preset high-performance";
+ param = "-preset llhq";
}
// webm
@@ -670,17 +680,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrEmpty(state.Options.Profile))
{
- param += " -profile:v " + state.Options.Profile;
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
+ {
+ // not supported by h264_omx
+ param += " -profile:v " + state.Options.Profile;
+ }
}
var levelString = state.Options.Level.HasValue ? state.Options.Level.Value.ToString(CultureInfo.InvariantCulture) : null;
if (!string.IsNullOrEmpty(levelString))
{
- var h264Encoder = EncodingJobFactory.GetH264Encoder(state, GetEncodingOptions());
-
- // h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
- if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase))
+ // h264_qsv and h264_nvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
+ if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
{
switch (levelString)
{
@@ -716,13 +729,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
break;
}
}
- else
+ else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
{
param += " -level " + levelString;
}
}
- return "-pix_fmt yuv420p " + param;
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
+ {
+ param = "-pix_fmt yuv420p " + param;
+ }
+
+ return param;
}
protected string GetVideoBitrateParam(EncodingJob state, string videoCodec)
@@ -857,7 +877,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="outputVideoCodec">The output video codec.</param>
/// <param name="allowTimeStampCopy">if set to <c>true</c> [allow time stamp copy].</param>
/// <returns>System.String.</returns>
- protected string GetOutputSizeParam(EncodingJob state,
+ protected async Task<string> GetOutputSizeParam(EncodingJob state,
string outputVideoCodec,
bool allowTimeStampCopy = true)
{
@@ -934,7 +954,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{
- var subParam = GetTextSubtitleParam(state);
+ var subParam = await GetTextSubtitleParam(state).ConfigureAwait(false);
filters.Add(subParam);
@@ -957,7 +977,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
/// <param name="state">The state.</param>
/// <returns>System.String.</returns>
- protected string GetTextSubtitleParam(EncodingJob state)
+ protected async Task<string> GetTextSubtitleParam(EncodingJob state)
{
var seconds = Math.Round(TimeSpan.FromTicks(state.Options.StartTimeTicks ?? 0).TotalSeconds);
@@ -969,7 +989,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrEmpty(state.SubtitleStream.Language))
{
- var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.MediaSource.Protocol, CancellationToken.None).Result;
+ var charenc = await SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).ConfigureAwait(false);
if (!string.IsNullOrEmpty(charenc))
{
@@ -1002,7 +1022,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Boost volume to 200% when downsampling from 6ch to 2ch
if (channels.HasValue && channels.Value <= 2)
{
- if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5)
+ if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5 && !GetEncodingOptions().DownMixAudioBoost.Equals(1))
{
volParam = ",volume=" + GetEncodingOptions().DownMixAudioBoost.ToString(UsCulture);
}