Skip to content
This repository was archived by the owner on Nov 27, 2024. It is now read-only.

Commit 38028b8

Browse files
committed
StableDiffusionPipeline video stream
1 parent 3cab2f6 commit 38028b8

File tree

7 files changed

+166
-2
lines changed

7 files changed

+166
-2
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using OnnxStack.Core.Video;
2+
using OnnxStack.FeatureExtractor.Pipelines;
3+
using OnnxStack.StableDiffusion.Config;
4+
using OnnxStack.StableDiffusion.Enums;
5+
using OnnxStack.StableDiffusion.Pipelines;
6+
7+
namespace OnnxStack.Console.Runner
8+
{
9+
public sealed class VideoToVideoStreamExample : IExampleRunner
10+
{
11+
private readonly string _outputDirectory;
12+
private readonly StableDiffusionConfig _configuration;
13+
14+
public VideoToVideoStreamExample(StableDiffusionConfig configuration)
15+
{
16+
_configuration = configuration;
17+
_outputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Examples", nameof(VideoToVideoStreamExample));
18+
Directory.CreateDirectory(_outputDirectory);
19+
}
20+
21+
public int Index => 4;
22+
23+
public string Name => "Video To Video Stream Demo";
24+
25+
public string Description => "Video Stream Stable Diffusion Inference";
26+
27+
public async Task RunAsync()
28+
{
29+
30+
// Read Video
31+
var videoFile = "C:\\Users\\Deven\\Pictures\\gidsgphy.gif";
32+
var videoInfo = await VideoHelper.ReadVideoInfoAsync(videoFile);
33+
34+
// Loop though the appsettings.json model sets
35+
foreach (var modelSet in _configuration.ModelSets)
36+
{
37+
OutputHelpers.WriteConsole($"Loading Model `{modelSet.Name}`...", ConsoleColor.Cyan);
38+
39+
// Create Pipeline
40+
var pipeline = PipelineBase.CreatePipeline(modelSet);
41+
42+
// Preload Models (optional)
43+
await pipeline.LoadAsync();
44+
45+
// Add text and video to prompt
46+
var promptOptions = new PromptOptions
47+
{
48+
Prompt = "Iron Man",
49+
DiffuserType = DiffuserType.ImageToImage
50+
};
51+
52+
53+
// Create Video Stream
54+
var videoStream = VideoHelper.ReadVideoStreamAsync(videoFile, videoInfo.FrameRate);
55+
56+
// Create Pipeline Stream
57+
var pipelineStream = pipeline.GenerateVideoStreamAsync(videoStream, promptOptions, progressCallback:OutputHelpers.ProgressCallback);
58+
59+
// Write Video Stream
60+
await VideoHelper.WriteVideoStreamAsync(videoInfo, pipelineStream, Path.Combine(_outputDirectory, $"{modelSet.PipelineType}.mp4"));
61+
62+
//Unload
63+
await pipeline.UnloadAsync();
64+
}
65+
}
66+
}
67+
}

OnnxStack.Core/Image/OnnxImage.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,28 @@ public async Task<Stream> GetImageStreamAsync()
182182
}
183183

184184

185+
/// <summary>
186+
/// Copies the image to stream.
187+
/// </summary>
188+
/// <param name="destination">The destination.</param>
189+
/// <returns></returns>
190+
public void CopyToStream(Stream destination)
191+
{
192+
_imageData.SaveAsPng(destination);
193+
}
194+
195+
196+
/// <summary>
197+
/// Copies the image to stream.
198+
/// </summary>
199+
/// <param name="destination">The destination.</param>
200+
/// <returns></returns>
201+
public Task CopyToStreamAsync(Stream destination)
202+
{
203+
return _imageData.SaveAsPngAsync(destination);
204+
}
205+
206+
185207
/// <summary>
186208
/// Gets the image as tensor.
187209
/// </summary>

OnnxStack.Core/Video/VideoHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public static async Task WriteVideoStreamAsync(VideoInfo videoInfo, IAsyncEnumer
103103
await foreach (var frame in videoStream)
104104
{
105105
// Write each frame to the input stream of FFMPEG
106-
await videoWriter.StandardInput.BaseStream.WriteAsync(frame.GetImageBytes(), cancellationToken);
106+
await frame.CopyToStreamAsync(videoWriter.StandardInput.BaseStream);
107107
}
108108

109109
// Done close stream and wait for app to process

OnnxStack.StableDiffusion/Config/PromptOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace OnnxStack.StableDiffusion.Config
77
{
8-
public class PromptOptions
8+
public record PromptOptions
99
{
1010
public DiffuserType DiffuserType { get; set; }
1111

OnnxStack.StableDiffusion/Pipelines/Base/IPipeline.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ namespace OnnxStack.StableDiffusion.Pipelines
1414
{
1515
public interface IPipeline
1616
{
17+
18+
/// <summary>
19+
/// Gets the name.
20+
/// </summary>
21+
string Name { get; }
22+
23+
1724
/// <summary>
1825
/// Gets the pipelines supported diffusers.
1926
/// </summary>
@@ -127,5 +134,17 @@ public interface IPipeline
127134
/// <param name="cancellationToken">The cancellation token.</param>
128135
/// <returns></returns>
129136
IAsyncEnumerable<BatchVideoResult> GenerateVideoBatchAsync(BatchOptions batchOptions, PromptOptions promptOptions, SchedulerOptions schedulerOptions = default, ControlNetModel controlNet = default, Action<DiffusionProgress> progressCallback = null, CancellationToken cancellationToken = default);
137+
138+
/// <summary>
139+
/// Runs the video stream pipeline returning each frame as an OnnxImage.
140+
/// </summary>
141+
/// <param name="videoFrames">The video frames.</param>
142+
/// <param name="promptOptions">The prompt options.</param>
143+
/// <param name="schedulerOptions">The scheduler options.</param>
144+
/// <param name="controlNet">The control net.</param>
145+
/// <param name="progressCallback">The progress callback.</param>
146+
/// <param name="cancellationToken">The cancellation token.</param>
147+
/// <returns></returns>
148+
IAsyncEnumerable<OnnxImage> GenerateVideoStreamAsync(IAsyncEnumerable<OnnxImage> videoFrames, PromptOptions promptOptions, SchedulerOptions schedulerOptions = default, ControlNetModel controlNet = default, Action<DiffusionProgress> progressCallback = null, CancellationToken cancellationToken = default);
130149
}
131150
}

OnnxStack.StableDiffusion/Pipelines/Base/PipelineBase.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,19 @@ protected PipelineBase(PipelineOptions pipelineOptions, ILogger logger)
161161
public abstract IAsyncEnumerable<BatchVideoResult> GenerateVideoBatchAsync(BatchOptions batchOptions, PromptOptions promptOptions, SchedulerOptions schedulerOptions = default, ControlNetModel controlNet = default, Action<DiffusionProgress> progressCallback = null, CancellationToken cancellationToken = default);
162162

163163

164+
/// <summary>
165+
/// Runs the video stream pipeline returning each frame as an OnnxImage.
166+
/// </summary>
167+
/// <param name="videoFrames">The video frames.</param>
168+
/// <param name="promptOptions">The prompt options.</param>
169+
/// <param name="schedulerOptions">The scheduler options.</param>
170+
/// <param name="controlNet">The control net.</param>
171+
/// <param name="progressCallback">The progress callback.</param>
172+
/// <param name="cancellationToken">The cancellation token.</param>
173+
/// <returns></returns>
174+
public abstract IAsyncEnumerable<OnnxImage> GenerateVideoStreamAsync(IAsyncEnumerable<OnnxImage> videoFrames, PromptOptions promptOptions, SchedulerOptions schedulerOptions = default, ControlNetModel controlNet = default, Action<DiffusionProgress> progressCallback = null, CancellationToken cancellationToken = default);
175+
176+
164177
/// <summary>
165178
/// Creates the diffuser.
166179
/// </summary>

OnnxStack.StableDiffusion/Pipelines/StableDiffusionPipeline.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,49 @@ public override async IAsyncEnumerable<BatchVideoResult> GenerateVideoBatchAsync
266266
}
267267

268268

269+
/// <summary>
270+
/// Runs the video stream pipeline returning each frame as an OnnxImage.
271+
/// </summary>
272+
/// <param name="videoFrames">The video frames.</param>
273+
/// <param name="promptOptions">The prompt options.</param>
274+
/// <param name="schedulerOptions">The scheduler options.</param>
275+
/// <param name="controlNet">The control net.</param>
276+
/// <param name="progressCallback">The progress callback.</param>
277+
/// <param name="cancellationToken">The cancellation token.</param>
278+
/// <returns></returns>
279+
public override async IAsyncEnumerable<OnnxImage> GenerateVideoStreamAsync(IAsyncEnumerable<OnnxImage> videoFrames, PromptOptions promptOptions, SchedulerOptions schedulerOptions = null, ControlNetModel controlNet = null, Action<DiffusionProgress> progressCallback = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
280+
{
281+
var diffuseTime = _logger?.LogBegin("Diffuser starting...");
282+
var options = GetSchedulerOptionsOrDefault(schedulerOptions);
283+
_logger?.Log($"Model: {Name}, Pipeline: {PipelineType}, Diffuser: {promptOptions.DiffuserType}, Scheduler: {options.SchedulerType}");
284+
285+
// Check guidance
286+
var performGuidance = ShouldPerformGuidance(options);
287+
288+
// Process prompts
289+
var promptEmbeddings = await CreatePromptEmbedsAsync(promptOptions, performGuidance);
290+
291+
// Create Diffuser
292+
var diffuser = CreateDiffuser(promptOptions.DiffuserType, controlNet);
293+
294+
// Diffuse
295+
await foreach (var videoFrame in videoFrames)
296+
{
297+
var frameOptions = promptOptions with
298+
{
299+
InputImage = promptOptions.DiffuserType == DiffuserType.ImageToImage || promptOptions.DiffuserType == DiffuserType.ControlNetImage
300+
? videoFrame : default,
301+
InputContolImage = promptOptions.DiffuserType == DiffuserType.ControlNet || promptOptions.DiffuserType == DiffuserType.ControlNetImage
302+
? videoFrame : default,
303+
};
304+
305+
yield return new OnnxImage(await DiffuseImageAsync(diffuser, frameOptions, options, promptEmbeddings, performGuidance, progressCallback, cancellationToken));
306+
}
307+
308+
_logger?.LogEnd($"Diffuser complete", diffuseTime);
309+
}
310+
311+
269312
/// <summary>
270313
/// Runs the pipeline
271314
/// </summary>

0 commit comments

Comments
 (0)