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