stop inference on stop pressed

small fixes
This commit is contained in:
Alex Bezdieniezhnykh
2025-03-24 10:52:32 +02:00
parent 6429ad62c2
commit 73c2ab5374
11 changed files with 40 additions and 29 deletions
+7 -6
View File
@@ -393,6 +393,7 @@ public partial class Annotator
private void OnFormClosed(object? sender, EventArgs e)
{
MainCancellationSource.Cancel();
_inferenceService.StopInference();
DetectionCancellationSource.Cancel();
_mediaPlayer.Stop();
_mediaPlayer.Dispose();
@@ -500,30 +501,30 @@ public partial class Annotator
IsInferenceNow = true;
FollowAI = true;
DetectionCancellationSource = new CancellationTokenSource();
var ct = DetectionCancellationSource.Token;
var detectToken = DetectionCancellationSource.Token;
_ = Task.Run(async () =>
{
while (!ct.IsCancellationRequested)
while (!detectToken.IsCancellationRequested)
{
var files = new List<string>();
await Dispatcher.Invoke(async () =>
{
//Take not annotataed medias
//Take all medias
files = (LvFiles.ItemsSource as IEnumerable<MediaFileInfo>)?.Skip(LvFiles.SelectedIndex)
.Where(x => !x.HasAnnotations)
//.Where(x => !x.HasAnnotations)
.Take(Constants.DETECTION_BATCH_SIZE)
.Select(x => x.Path)
.ToList() ?? [];
if (files.Count != 0)
{
await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play), ct);
await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play), detectToken);
await ReloadAnnotations();
}
});
if (files.Count == 0)
break;
await _inferenceService.RunInference(files, async annotationImage => await ProcessDetection(annotationImage, ct), ct);
await _inferenceService.RunInference(files, async annotationImage => await ProcessDetection(annotationImage, detectToken), detectToken);
Dispatcher.Invoke(() =>
{
+3 -1
View File
@@ -25,7 +25,8 @@ public class AnnotatorEventHandler(
FormState formState,
AnnotationService annotationService,
ILogger<AnnotatorEventHandler> logger,
IOptions<DirectoriesConfig> dirConfig)
IOptions<DirectoriesConfig> dirConfig,
IInferenceService inferenceService)
:
INotificationHandler<KeyEvent>,
INotificationHandler<AnnClassSelectedEvent>,
@@ -141,6 +142,7 @@ public class AnnotatorEventHandler(
}
break;
case PlaybackControlEnum.Stop:
inferenceService.StopInference();
await mainWindow.DetectionCancellationSource.CancelAsync();
mediaPlayer.Stop();
break;
@@ -144,6 +144,9 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
.Where(x => x.Name == fName)
.Set(x => x.Source, source)
.Set(x => x.AnnotationStatus, status)
.Set(x => x.CreatedDate, createdDate)
.Set(x => x.CreatedEmail, createdEmail)
.Set(x => x.CreatedRole, userRole)
.UpdateAsync(token: token);
ann.Detections = detections;
}
+11 -5
View File
@@ -13,30 +13,31 @@ namespace Azaion.Common.Services;
public interface IInferenceService
{
Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken ct = default);
Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken detectToken = default);
void StopInference();
}
public class InferenceService(ILogger<InferenceService> logger, [FromKeyedServices(SecurityConstants.EXTERNAL_INFERENCE_PATH)] IExternalClient externalClient, IOptions<AIRecognitionConfig> aiConfigOptions) : IInferenceService
{
public async Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken ct = default)
public async Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken detectToken = default)
{
var aiConfig = aiConfigOptions.Value;
aiConfig.Paths = mediaPaths;
externalClient.Send(RemoteCommand.Create(CommandType.Inference, aiConfig));
while (!ct.IsCancellationRequested)
while (!detectToken.IsCancellationRequested)
{
try
{
var bytes = externalClient.GetBytes(ct: ct);
var bytes = externalClient.GetBytes(ct: detectToken);
if (bytes == null)
throw new Exception("Can't get bytes from inference client");
if (bytes.Length == 4 && Encoding.UTF8.GetString(bytes) == "DONE")
return;
var annotationImage = MessagePackSerializer.Deserialize<AnnotationImage>(bytes, cancellationToken: ct);
var annotationImage = MessagePackSerializer.Deserialize<AnnotationImage>(bytes, cancellationToken: detectToken);
await processAnnotation(annotationImage);
}
@@ -47,4 +48,9 @@ public class InferenceService(ILogger<InferenceService> logger, [FromKeyedServic
}
}
}
public void StopInference()
{
externalClient.Send(RemoteCommand.Create(CommandType.StopInference));
}
}
@@ -11,11 +11,11 @@ public class RemoteCommand(CommandType commandType, byte[]? data = null)
[Key("Data")]
public byte[]? Data { get; set; } = data;
public static RemoteCommand Create<T>(CommandType commandType, T data) where T : class
{
var dataBytes = MessagePackSerializer.Serialize(data);
return new RemoteCommand(commandType, dataBytes);
}
public static RemoteCommand Create(CommandType commandType) =>
new(commandType);
public static RemoteCommand Create<T>(CommandType commandType, T data) where T : class =>
new(commandType, MessagePackSerializer.Serialize(data));
}
[MessagePackObject]
-2
View File
@@ -11,8 +11,6 @@ cdef str QUEUE_CONFIG_FILENAME = "secured-config.json"
cdef str AI_MODEL_FILE_BIG = "azaion.onnx.big"
cdef str AI_MODEL_FILE_SMALL = "azaion.onnx.small"
cdef bytes DONE_SIGNAL = b"DONE"
cdef log(str log_message, bytes client_id=None):
local_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
client_str = '' if client_id is None else f' {client_id}'
+1
View File
@@ -1,3 +1,4 @@
pyinstaller
Cython
opencv-python
numpy
+5 -4
View File
@@ -12,6 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GMap.NET.WinPresentation" Version="2.1.7" />
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
<PackageReference Include="MediatR" Version="12.4.1" />
@@ -31,8 +32,8 @@
<ItemGroup>
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
<ProjectReference Include="..\Azaion.Annotator\Azaion.Annotator.csproj" />
<ProjectReference Include="..\Azaion.Dataset\Azaion.Dataset.csproj" />
<ProjectReference Include="..\dummy\Azaion.Annotator\Azaion.Annotator.csproj" />
<ProjectReference Include="..\dummy\Azaion.Dataset\Azaion.Dataset.csproj" />
</ItemGroup>
<ItemGroup>
@@ -60,8 +61,8 @@
<Target Name="PostBuild" AfterTargets="Build">
<MakeDir Directories="$(TargetDir)dummy" />
<Copy SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
<Copy SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
<Move SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
<Exec Command="upload.cmd $(ConfigurationName) stage" />
</Target>
+2 -2
View File
@@ -37,8 +37,8 @@
{ "Id": 13, "Name": "Маскування гілками", "ShortName": "Гілки" }
],
"LastSelectedExplorerClass": null,
"VideoFormats": [ "mp4", "mov", "avi" ],
"ImageFormats": [ "jpg", "jpeg", "png", "bmp" ],
"VideoFormats": [ ".mp4", ".mov", ".avi" ],
"ImageFormats": [ ".jpg", ".jpeg", ".png", ".bmp" ],
"AnnotationsDbFile": "annotations.db",
"LeftPanelWidth": 220.0,
"RightPanelWidth": 230.0
+2 -2
View File
@@ -37,8 +37,8 @@
{ "Id": 13, "Name": "Маскування гілками", "ShortName": "Гілки" }
],
"LastSelectedExplorerClass": null,
"VideoFormats": [ "mp4", "mov", "avi" ],
"ImageFormats": [ "jpg", "jpeg", "png", "bmp" ],
"VideoFormats": [ ".mp4", ".mov", ".avi" ],
"ImageFormats": [ ".jpg", ".jpeg", ".png", ".bmp" ],
"AnnotationsDbFile": "annotations.db",
"LeftPanelWidth": 240.0,
"RightPanelWidth": 240.0
+1 -2
View File
@@ -21,8 +21,7 @@ move dist\Azaion.Dataset.dll dist\dummy\
echo Build Cython app
cd Azaion.Inference
call ".\venv\Scripts\activate.bat"
pyinstaller --onefile ^
.\venv\Scripts\pyinstaller --onefile ^
--collect-all jwt ^
--collect-all requests ^
--collect-all psutil ^