Aborting a foreach loop containing a stabilisation effect

Jack S wrote on 3/13/2025, 6:38 AM

@jetdv Edward, I wonder if you can help me with this. I'm not sure if it's even possible. I have a batch stabilisation module in my application extension. It processes selected video events using a foreach loop. I want to have the ability to abort the process if necessary. I have an 'Abort' button that sets an abort boolean to true and this boolean is tested at the start of the foreach loop. If the boolean is true, I invoke a return command to exit the function. The problem is, during the process, it's impossible to activate the button. I've searched the API to see if I can access the 'Cancel' function on the stabilisation progress UI which I could use to intercept the loop, but I can't find anything. Do you have any ideas?

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

Comments

jetdv wrote on 3/13/2025, 8:25 AM

I'm assuming the "abort" button just gives a windows beep indicating it's not available to click? That would probably be because "VEGAS" is working so the extension isn't accepting input. You might be able to put it on a separate thread but then the current process would probably still need to finish unless you manually click on the "Cancel" button too.

Jack S wrote on 3/13/2025, 8:48 AM

No, there's no Windows beep when I attempt to click it. It just isn't responsive because the pointer is a hourglass. I don't mind having to click the Cancel button for the current iteration if I could then get the Abort button to accept an input. I don't know what you mean by 'put it on a separate thread'. Can you explain please?

Last changed by Jack S on 3/13/2025, 8:56 AM, changed a total of 1 times.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

bvideo wrote on 3/13/2025, 10:39 AM

Does this scenario match your stabilize loop and can you use it to exit the loop:

Somewhere in your loop, your code does "ParameterChanged" to the "AnalyzeMotion" parameter. At your next statement, the analyze has finished. You can then test the "HasMotionData" parameter. If it is true, the analyze completed. If you hit [Cancel] during the stabilize dialog, "HasMotionData" will be false. Then you can quit your loop. (I presume you have done OpenVideoEffectUI() so you can watch the stabilize operation running and see the cancel button.)

Aside from that, it's not clear that multithreaded code could intercept your own "quit" button and safely terminate the analyze process.

Jack S wrote on 3/13/2025, 10:48 AM

@bvideo Thanks for that. I think I know what you mean. I'll give it a go and report back.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

Jack S wrote on 3/14/2025, 11:23 AM

@bvideo OK. After many hours of trying to figure this out, I'm stumped. I can usually muddle my way through after being given some hints, but this time I'm lost. This is what I have at the moment after your advice.
 

                                        OFXParameter myOFXParameterAlt = myOFXEffect.FindParameterByName("AnalyzeMotion");  //Define the parameter
                                        myOFXParameterAlt.ParameterChanged();                                               //Acivate stabilisation
                                        OFXParameter myOFXParameterRes = myOFXEffect.FindParameterByName("HasMotionData");  //Define the parameter
                                        myOFXParameterRes.ParameterChanged(contProcess);                                    //Load the result into the boolean 'contProcess'
                                        MessageBox.Show("contProcess = " + contProcess);                                    //Display the state of the 'HasMotionData' parameter
                                        if (!contProcess)                                                                   //If it is false ...
                                        {
                                            return;                                                                         //... break out of the calling procedure.
                                        }
  

Unfortunately, clicking cancel results in 'HasMotionData' being true. It is never false, so the foreach loop continues. Am I doing this correct? Thanks in advance.

 

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

jetdv wrote on 3/14/2025, 2:34 PM

That is now how you would check the value of the boolean parameter. Convert it to a boolean parameter:

OFXBooleanParameter fit = (OFXBooleanParameter)ofx.FindParameterByName("HasMotionData");

and then just read the value:

Boolean HasMotionData = fit.Value;

 

bvideo wrote on 3/14/2025, 2:59 PM

@Jack S Another thought: when I want to analyze motion data, I first check to see if "HasMotionData" is already true. If it is true, either I don't run the analyze (not needed) or I do the "ParameterChanged" operation on the "CLearMotionData" (crazy spelling) pushbutton parameter first to erase the preexisting motion data. I don't know what would happen if the "AnalyzeMotion" parameter is pushed when there is already motion data present. Would it run the analyze or not? And if so, would [Cancel] restore the previous motion data or leave it cleared?

Sorry I have not written this in clear C++ & scripting API language. Thanks to @jetdv for spelling things out clearly, as always!

Last changed by bvideo on 3/14/2025, 3:01 PM, changed a total of 1 times.

Dedicated: Vegas 20, 21, & 22, i7 8700k (UHD 630), 32 gig ram, ssd & 2 spinning units.

General purpose: i5 11400 (UHD 730), 32 gigs, ssd, 1 spinning unit (Vegas 21 & 22)

Jack S wrote on 3/15/2025, 6:59 AM

@jetdv Thanks Edward, that did it. I had to make a small change to suit my code, replacing ofx.FindParameterByName to myOFXEffect.FindParameterByName, but that was all.
The foreach loop now exits when I click the cancel button. I've marked your answer as the solution.

@bvideo Before activating stabilisation, I check whether it's already in the chain. If it is, I remove it. This has worked for me since I introduced the module into my application extension, so I'm not going to change that.

Thanks to you both for your input, it's most appreciated.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE