RenderHeads / UnityPlugin-AVProDeckLink

AVPro DeckLink is a Unity plugin for broadcast CG using Blackmagic capture hardware
https://renderheads.com/products/avpro-decklink/
9 stars 1 forks source link

Device.StopInput() never returns / freezes application #68

Closed pilzinho closed 8 months ago

pilzinho commented 1 year ago

We encountered an issue when stopping an input via script calling Device.StopInput() using version 1.9.6. In this case the application freezes. Debugging revealed that DeckLinkPlugin.StopInputStream(_deviceIndex) never returns. It happens almost every time and makes the plugin unusable for us. With version 1.9.3 it seems to work fine. So maybe there's some threading/locking issue going on. The InputExplorerDemo also seems to work fine with version 1.9.6. Maybe because of the way/the time the device is stopped using the button in OnGUI(). But we need to be able to stop the device any time via script.

When adding this Coroutine to Start() of the InputExplorerDemo the same freeze happens:

public void Start()
{
    Application.runInBackground = true;       
    EnumerateDevices();
    StartCoroutine(StartStopDevices());
}

private IEnumerator StartStopDevices()
{
    while (true)
    {
        yield return new WaitForSeconds(5);
        foreach (var instance in _instances)
        {
            instance.decklink.Device.StopInput();
        }

        yield return new WaitForSeconds(5);
        foreach (var instance in _instances)
        {
            instance.decklink.Begin();
        }
    }
}

Running this Coroutine with version 1.9.3. stops and starts the devices correctly for a while but crashes at some point with this crash log:

-----------------------------------------------------------------------------------------------------
      at <unknown> <0xffffffff>
      at RenderHeads.Media.AVProDeckLink.DeckLinkPlugin:GetTexturePointer <0x000e3>
      at RenderHeads.Media.AVProDeckLink.FormatConverter:Update <0x00152>
      at RenderHeads.Media.AVProDeckLink.Device:Update <0x00902>
      at RenderHeads.Media.AVProDeckLink.DeckLink:Update <0x002ca>
      at System.Object:runtime_invoke_void__this__ <0x00187>
-----------------------------------------------------------------------------------------------------
Received signal SIGSEGV
Obtained 34 stack frames
0x00007ff995d2f786 (d3d11) D3DKMTWaitForVerticalBlankEvent
0x00007ff995cdcf70 (d3d11) D3D11CoreCreateDevice
0x00007ff995ce3569 (d3d11) D3D11CoreCreateDevice
0x00007ff995ce3b52 (d3d11) D3D11CoreCreateDevice
0x00007ff995ce3fdc (d3d11) D3D11CoreCreateDevice
0x00007ff995cd866e (d3d11) D3D11CoreCreateDevice
0x00007ff995cfecb1 (d3d11) D3D11CoreCreateDevice
0x000002483299eb74 (AVProDeckLink) GetHealthStatus
0x0000024832a89b94 (Mono JIT Code) (wrapper managed-to-native) RenderHeads.Media.AVProDeckLink.DeckLinkPlugin:GetTexturePointer (int)
0x0000024832a99913 (Mono JIT Code) RenderHeads.Media.AVProDeckLink.FormatConverter:Update () (at D:/Development/Unity/AVProVideo/DecklinkTest/Assets/AVProDeckLink/Scripts/Internal/FormatConverter.cs:220)
0x0000024832a98ed3 (Mono JIT Code) RenderHeads.Media.AVProDeckLink.Device:Update () (at D:/Development/Unity/AVProVideo/DecklinkTest/Assets/AVProDeckLink/Scripts/Internal/Device.cs:1058)
0x0000024832a9512b (Mono JIT Code) RenderHeads.Media.AVProDeckLink.DeckLink:Update () (at D:/Development/Unity/AVProVideo/DecklinkTest/Assets/AVProDeckLink/Scripts/Internal/DeckLink.cs:595)

I hope you can reproduce the issue and provide a fix for this since we have time pressure supporting DeckLink cards for a client and bought the asset for this reason because the AVPro Live Camera plugin which we are using for a while already was no adequate solution either.

pilzinho commented 1 year ago

So when writing this up I had another idea to try out. I figured that the work done in the Update() methods of the various involved components in the plugin maybe cause problems when calling StopInput(). Since OnGUI() is called after Update() (UnityExecutionOrder) this may be the reason that it works. So calling StopInput() after an WaitForEndOfFrame() also seems to work. So this may be a workaround for us. But it would be good if you could confirm this and of course it would be nice if the plugin would handle this on its own.

pilzinho commented 11 months ago

Unfortunately, we encountered new problems when using multiple (3-4) inputs. In this case our previous workaround doesn't work anymore and the application freezes again at the same spot: DeckLinkPlugin.StopInputStream(_deviceIndex) in Device.StopInput(). We suspect that rendering the inputs in DeckLinkManager takes longer and the devices may not be ready/released to be stopped yet. So for now we stop the devices in FixedUpdate() which happens before Update() what seems to work. But stopping multiple devices at once halts the application for up to 3-4 seconds which is also quite bad.

RichRH commented 10 months ago

Hi @pilzinho,

Apologies for taking some time to get back to you and thanks for the reproduction steps - I've managed to replicate here.

As you suggest, calling 'StopInput()' after 'WaitForEndOfFrame()' can help alleviate in some situations, but will only go so far - it's fundamentally down to Unity/native GPU resource synchronisation and compounded by multiple inputs. I'm currently looking into a fix.

Cheers,

RichRH commented 9 months ago

FYI.. I have a fix for the above currently in testing.

Cheers,

Chris-RH commented 9 months ago

This issue has been fixed in the latest release (AVPro Decklink version 1.9.7). Please let us know if this issue has not been fixed for you.