Skip to content

Commit d862808

Browse files
committed
feat: use a pipe between ffmpeg and dovi_tool again.
1 parent 65bfdb7 commit d862808

File tree

1 file changed

+55
-18
lines changed

1 file changed

+55
-18
lines changed

Jellyfin.Plugin.DoViRemux/DownmuxWorkflow.cs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
4444
"-dn",
4545
"-c:v copy",
4646
"-f hevc", // trivia: using the hevc muxer automatically adds the hevc_mp4toannexb bitstream filter
47-
ffmpegOutputPath
47+
"-"
4848
]),
49-
RedirectStandardError = true
49+
RedirectStandardError = true,
50+
RedirectStandardOutput = true
5051
}
5152
};
52-
53+
5354
_logger.LogInformation("{Command} {Arguments}", ffmpeg.StartInfo.FileName, ffmpeg.StartInfo.Arguments);
5455
ffmpeg.Start();
5556

@@ -58,9 +59,7 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
5859
ffmpeg,
5960
token)
6061
.ConfigureAwait(false);
61-
62-
await ffmpeg.WaitForExitAsync().ConfigureAwait(false);
63-
62+
6463
// and feed it into dovi_tool, discarding the enhancement layer
6564
using var doviTool = new Process()
6665
{
@@ -70,13 +69,14 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
7069
"-m 2", // convert RPU to 8.1
7170
"convert", // modify RPU
7271
"--discard", // discard EL
73-
$"--input {ffmpegOutputPath}",
74-
$"--output {doviToolOutputPath}"
72+
$"-",
73+
$"-o {doviToolOutputPath}"
7574
]),
75+
RedirectStandardInput = true,
7676
RedirectStandardError = true
7777
}
7878
};
79-
79+
8080
_logger.LogInformation("{Command} {Arguments}", doviTool.StartInfo.FileName, doviTool.StartInfo.Arguments);
8181
doviTool.Start();
8282

@@ -86,18 +86,42 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
8686
token)
8787
.ConfigureAwait(false);
8888

89-
await doviTool.WaitForExitAsync();
89+
var pipeTask = Task.Run(() =>
90+
{
91+
var buffer = new byte[4 * 1024 * 1024];
92+
93+
while (!token.IsCancellationRequested
94+
&& ffmpeg.StandardOutput.BaseStream.CanRead
95+
&& doviTool.StandardInput.BaseStream.CanWrite)
96+
{
97+
var bytesRead = ffmpeg.StandardOutput.BaseStream.Read(buffer, 0, 4 * 1024 * 1024);
98+
if (bytesRead <= 0)
99+
{
100+
break;
101+
}
102+
103+
doviTool.StandardInput.BaseStream.Write(buffer, 0, bytesRead);
104+
doviTool.StandardInput.BaseStream.Flush();
105+
}
90106

91-
try
107+
doviTool.StandardInput.BaseStream.Close();
108+
}, token)
109+
.ContinueWith(t =>
92110
{
93-
if (!File.Exists(doviToolOutputPath))
111+
if (t.IsFaulted)
94112
{
95-
throw new Exception("dovi_tool failed");
113+
ffmpeg.Kill();
114+
doviTool.Kill();
96115
}
97-
}
98-
finally
116+
});
117+
118+
await Task.WhenAll(RunToExit(ffmpeg),
119+
RunToExit(doviTool),
120+
pipeTask);
121+
122+
if (!File.Exists(doviToolOutputPath))
99123
{
100-
File.Delete(ffmpegOutputPath);
124+
throw new Exception("HEVC extraction failed");
101125
}
102126

103127
// then remux the HEVC stream into an MP4 with the right DoVi side data
@@ -119,7 +143,7 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
119143
RedirectStandardError = true
120144
}
121145
};
122-
146+
123147
_logger.LogInformation("{Command} {Arguments}", mp4box.StartInfo.FileName, mp4box.StartInfo.Arguments);
124148
mp4box.Start();
125149

@@ -129,11 +153,24 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
129153
token)
130154
.ConfigureAwait(false);
131155

132-
await mp4box.WaitForExitAsync(token);
156+
await RunToExit(mp4box);
133157

134158
File.Delete(doviToolOutputPath);
135159

136160
return mp4boxOutputPath;
161+
162+
async Task RunToExit(Process p)
163+
{
164+
try
165+
{
166+
await p.WaitForExitAsync(token).ConfigureAwait(false);
167+
}
168+
catch (OperationCanceledException)
169+
{
170+
p.Kill();
171+
throw;
172+
}
173+
}
137174
}
138175

139176
private async Task WriteStreamToLog(string logPath, Stream logStream, Process logProcess, CancellationToken token)

0 commit comments

Comments
 (0)