STDMETHODIMP CSubPicAllocatorPresenterImpl::Connect(ISubRenderProvider* subtitleRenderer)
{
    HRESULT hr = E_FAIL;

    if (m_pSubPicProvider) {
        return hr;
    }

    hr = subtitleRenderer->SetBool("combineBitmaps", true);
    if (FAILED(hr)) {
        return hr;
    }

    if (CComQIPtr<ISubRenderConsumer> pSubConsumer = m_pSubPicQueue) {
        hr = pSubConsumer->Connect(subtitleRenderer);
    } else {
        CComPtr<ISubPicProvider> pSubPicProvider = (ISubPicProvider*)DEBUG_NEW CXySubPicProvider(subtitleRenderer);

        /* Disable subpic buffer until XySubFilter implements subtitle invalidation
        CComPtr<ISubPicQueue> pSubPicQueue = GetRenderersSettings().nSPCSize > 0
                                             ? (ISubPicQueue*)DEBUG_NEW CXySubPicQueue(GetRenderersSettings().nSPCSize, m_pAllocator, &hr)
                                             : (ISubPicQueue*)DEBUG_NEW CXySubPicQueueNoThread(m_pAllocator, &hr);
        */

        // Lock and wait for m_pAllocator to be ready.
        CAutoLock cAutoLock(this);
        if (!m_pAllocator) {
            std::mutex mutexAllocator;
            std::unique_lock<std::mutex> lock(mutexAllocator);
            if (!m_condAllocatorReady.wait_for(lock, std::chrono::seconds(1), [&]() {return !!m_pAllocator;})) {
                // Return early, CXySubPicQueueNoThread ctor would fail anyway.
                ASSERT(FALSE);
                return E_FAIL;
            }
        }

        CComPtr<ISubPicQueue> pSubPicQueue = (ISubPicQueue*)DEBUG_NEW CXySubPicQueueNoThread(m_pAllocator, &hr);

        if (SUCCEEDED(hr)) {
            pSubPicQueue->SetSubPicProvider(pSubPicProvider);
            m_pSubPicProvider = pSubPicProvider;
            m_pSubPicQueue = pSubPicQueue;
        }
    }

    return hr;
}
STDMETHODIMP CSubPicAllocatorPresenterImpl::Connect(ISubRenderProvider* subtitleRenderer)
{
    HRESULT hr = E_FAIL;

    if (m_pSubPicProvider) {
        return hr;
    }

    hr = subtitleRenderer->SetBool("combineBitmaps", true);
    if (FAILED(hr)) {
        return hr;
    }

    if (CComQIPtr<ISubRenderConsumer> pSubConsumer = m_pSubPicQueue) {
        hr = pSubConsumer->Connect(subtitleRenderer);
    } else {
        CComPtr<ISubPicProvider> pSubPicProvider = (ISubPicProvider*)DEBUG_NEW CXySubPicProvider(subtitleRenderer);

        /* Disable subpic buffer until XySubFilter implements subtitle invalidation
        CComPtr<ISubPicQueue> pSubPicQueue = GetRenderersSettings().nSPCSize > 0
                                             ? (ISubPicQueue*)DEBUG_NEW CXySubPicQueue(GetRenderersSettings().nSPCSize, m_pAllocator, &hr)
                                             : (ISubPicQueue*)DEBUG_NEW CXySubPicQueueNoThread(m_pAllocator, &hr);
        */

        CComPtr<ISubPicQueue> pSubPicQueue = (ISubPicQueue*)DEBUG_NEW CXySubPicQueueNoThread(m_pAllocator, &hr);

        if (SUCCEEDED(hr)) {
            CAutoLock(this);
            pSubPicQueue->SetSubPicProvider(pSubPicProvider);
            m_pSubPicProvider = pSubPicProvider;
            m_pSubPicQueue = pSubPicQueue;
        }
    }

    return hr;
}