From ad097a744759c6a78e1b33ea9d2b4b2af01c529d Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 18 Jan 2023 19:55:25 +0100 Subject: Consistent cancellation API across the library: S_OK = continue, S_FALSE = stop --- Examples/WhisperDesktop/CaptureDlg.cpp | 4 ++-- Whisper/API/MfStructs.h | 3 +++ Whisper/API/sFullParams.h | 2 ++ Whisper/API/sLoadModelCallbacks.h | 1 + Whisper/Whisper/ContextImpl.capture.cpp | 4 ++-- Whisper/Whisper/ContextImpl.cpp | 6 +++++- WhisperNet/CaptureCallbacks.cs | 2 +- WhisperNet/Internal/sCaptureCallbacks.cs | 1 + 8 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Examples/WhisperDesktop/CaptureDlg.cpp b/Examples/WhisperDesktop/CaptureDlg.cpp index 3c22078..0bd86f7 100644 --- a/Examples/WhisperDesktop/CaptureDlg.cpp +++ b/Examples/WhisperDesktop/CaptureDlg.cpp @@ -442,8 +442,8 @@ LRESULT CaptureDlg::onThreadStatus( UINT nMessage, WPARAM wParam, LPARAM lParam, HRESULT __stdcall CaptureDlg::cbCancel( void* pv ) noexcept { - CaptureDlg& dialog = *(CaptureDlg*)pv; - return dialog.threadState.stopRequested ? S_OK : S_FALSE; + const bool stopRequested = ( (CaptureDlg*)pv )->threadState.stopRequested; + return stopRequested ? S_FALSE : S_OK; } HRESULT __stdcall CaptureDlg::cbStatus( void* pv, Whisper::eCaptureStatus status ) noexcept diff --git a/Whisper/API/MfStructs.h b/Whisper/API/MfStructs.h index cd27659..39255de 100644 --- a/Whisper/API/MfStructs.h +++ b/Whisper/API/MfStructs.h @@ -40,8 +40,11 @@ namespace Whisper Stalled = 0x80, }; + // Return S_OK to continue, or S_FALSE to stop the capture session using pfnShouldCancel = HRESULT( __stdcall* )( void* pv ) noexcept; + using pfnCaptureStatus = HRESULT( __stdcall* )( void* pv, eCaptureStatus status ) noexcept; + struct sCaptureCallbacks { pfnShouldCancel shouldCancel; diff --git a/Whisper/API/sFullParams.h b/Whisper/API/sFullParams.h index 0a1d352..42d48a4 100644 --- a/Whisper/API/sFullParams.h +++ b/Whisper/API/sFullParams.h @@ -14,6 +14,8 @@ namespace Whisper }; using pfnNewSegment = HRESULT( __cdecl* )( iContext* ctx, uint32_t n_new, void* user_data ) noexcept; + + // Return S_OK to proceed, or S_FALSE to stop the process and return S_OK from runFull / runStreamed method using pfnEncoderBegin = HRESULT( __cdecl* )( iContext* ctx, void* user_data ) noexcept; enum struct eFullParamsFlags : uint32_t diff --git a/Whisper/API/sLoadModelCallbacks.h b/Whisper/API/sLoadModelCallbacks.h index f5248c6..8f274c6 100644 --- a/Whisper/API/sLoadModelCallbacks.h +++ b/Whisper/API/sLoadModelCallbacks.h @@ -3,6 +3,7 @@ namespace Whisper { using pfnLoadProgress = HRESULT( __stdcall* )( double val, void* pv ) noexcept; + // Return S_OK to continue, or S_FALSE to fail with "The operation was canceled by the user" status code using pfnCancel = HRESULT( __stdcall* )( void* pv ) noexcept; struct sLoadModelCallbacks diff --git a/Whisper/Whisper/ContextImpl.capture.cpp b/Whisper/Whisper/ContextImpl.capture.cpp index 617c1f3..0062c2a 100644 --- a/Whisper/Whisper/ContextImpl.capture.cpp +++ b/Whisper/Whisper/ContextImpl.capture.cpp @@ -171,7 +171,7 @@ namespace HRESULT checkCancel() noexcept { if( nullptr == callbacks.shouldCancel ) - return S_FALSE; + return S_OK; return callbacks.shouldCancel( callbacks.pv ); } @@ -415,7 +415,7 @@ HRESULT COMLIGHTCALL ContextImpl::runCapture( const sFullParams& params, const s { HRESULT hr = capture.checkCancel(); CHECK( hr ); - if( hr == S_OK ) + if( hr != S_OK ) return S_OK; CHECK( capture.run() ); } diff --git a/Whisper/Whisper/ContextImpl.cpp b/Whisper/Whisper/ContextImpl.cpp index 175af74..59d644b 100644 --- a/Whisper/Whisper/ContextImpl.cpp +++ b/Whisper/Whisper/ContextImpl.cpp @@ -257,6 +257,7 @@ HRESULT COMLIGHTCALL ContextImpl::runFullImpl( const sFullParams& params, const int seek = seek_start; // Start measuring "Run" profiler value, both CPU and GPU times auto prof = context.completeProfiler(); + bool stoppedPrematurely = false; while( true ) { if( nullptr != progress.pfn ) @@ -278,7 +279,10 @@ HRESULT COMLIGHTCALL ContextImpl::runFullImpl( const sFullParams& params, const if( FAILED( hr ) ) return hr; if( hr != S_OK ) + { + stoppedPrematurely = true; break; + } } // encode audio features starting at offset seek @@ -511,7 +515,7 @@ HRESULT COMLIGHTCALL ContextImpl::runFullImpl( const sFullParams& params, const seek += seek_delta; } - if( nullptr != progress.pfn ) + if( nullptr != progress.pfn && !stoppedPrematurely ) { auto cb = profiler.cpuBlock( eCpuBlock::Callbacks ); CHECK( progress.pfn( 1.0, this, progress.pv ) ); diff --git a/WhisperNet/CaptureCallbacks.cs b/WhisperNet/CaptureCallbacks.cs index 26013f9..f2528e4 100644 --- a/WhisperNet/CaptureCallbacks.cs +++ b/WhisperNet/CaptureCallbacks.cs @@ -19,7 +19,7 @@ namespace Whisper { try { - return shouldCancel( sender ) ? S_OK : S_FALSE; + return shouldCancel( sender ) ? S_FALSE : S_OK; } catch( Exception ex ) { diff --git a/WhisperNet/Internal/sCaptureCallbacks.cs b/WhisperNet/Internal/sCaptureCallbacks.cs index 483c2f2..0865a5a 100644 --- a/WhisperNet/Internal/sCaptureCallbacks.cs +++ b/WhisperNet/Internal/sCaptureCallbacks.cs @@ -3,6 +3,7 @@ namespace Whisper.Internal { /// Unmanaged code calls this to check for cancellation + /// Return 0 to proceed, or 1 to stop the process and return from Context.runFull method [UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int pfnShouldCancel( IntPtr pv ); -- cgit v1.2.3