[vlc-devel] [PATCH 4/7] qt: allow video to be sent to a detached windows with DComp

Pierre Lamot pierre at videolabs.io
Mon Aug 17 09:22:19 CEST 2020


On 2020-08-17 09:01, Steve Lhomme wrote:
> On 2020-08-14 18:49, Pierre Lamot wrote:
>> ---
>>   .../gui/qt/maininterface/compositor_dcomp.cpp | 94 
>> +++++++++++++++++--
>>   .../gui/qt/maininterface/compositor_dcomp.hpp |  8 ++
>>   2 files changed, 92 insertions(+), 10 deletions(-)
>> 
>> diff --git a/modules/gui/qt/maininterface/compositor_dcomp.cpp 
>> b/modules/gui/qt/maininterface/compositor_dcomp.cpp
>> index 1b0b3d6517..06dedc1a4b 100644
>> --- a/modules/gui/qt/maininterface/compositor_dcomp.cpp
>> +++ b/modules/gui/qt/maininterface/compositor_dcomp.cpp
>> @@ -29,6 +29,7 @@
>>   #include <QApplication>
>>   #include <QDesktopWidget>
>>   #include <QQuickWidget>
>> +#include <QScreen>
>>     #include <QOpenGLFunctions>
>>   #include <QOpenGLFramebufferObject>
>> @@ -57,9 +58,9 @@ int 
>> CompositorDirectComposition::window_enable(struct vout_window_t * 
>> p_wnd, con
>>         try
>>       {
>> +        //default new window to EMBED for now
>>           that->m_qmlVideoSurfaceProvider->enable(p_wnd);
>> -        HR(that->m_rootVisual->AddVisual(that->m_videoVisual.Get(), 
>> FALSE, that->m_uiVisual.Get()), "add video visual to root");
>> -        HR(that->m_dcompDevice->Commit(), "commit");
>> +        that->setVideoSurface(VideoSurfaceTarget::EMBED);
>>       }
>>       catch (const DXError& err)
>>       {
>> @@ -74,11 +75,10 @@ void 
>> CompositorDirectComposition::window_disable(struct vout_window_t * 
>> p_wnd)
>>       CompositorDirectComposition* that = 
>> static_cast<CompositorDirectComposition*>(p_wnd->sys);
>>       try
>>       {
>> +        msg_Dbg(that->m_intf, "window_disable");
>> +        that->setVideoSurface(VideoSurfaceTarget::UNDEF);
>>           that->m_qmlVideoSurfaceProvider->disable();
>>           that->m_videoWindowHandler->disable();
>> -        msg_Dbg(that->m_intf, "window_disable");
>> -        
>> HR(that->m_rootVisual->RemoveVisual(that->m_videoVisual.Get()), 
>> "remove video visual from root");
>> -        HR(that->m_dcompDevice->Commit(), "commit");
>>       }
>>       catch (const DXError& err)
>>       {
>> @@ -123,7 +123,7 @@ void 
>> CompositorDirectComposition::window_set_fullscreen(struct 
>> vout_window_t * p
>>   }
>>     CompositorDirectComposition::CompositorDirectComposition( 
>> intf_thread_t* p_intf,  QObject *parent)
>> -    : QObject(parent)
>> +    : Compositor(parent)
>>       , m_intf(p_intf)
>>   {
>>   }
>> @@ -309,19 +309,93 @@ bool 
>> CompositorDirectComposition::setupVoutWindow(vout_window_t *p_wnd)
>>     Compositor::VideoSurfaceTarget 
>> CompositorDirectComposition::getSupportedVideoSurfaceModes() const
>>   {
>> -    return VideoSurfaceTarget::UNDEF;
>> +    return static_cast<VideoSurfaceTarget>(VideoSurfaceTarget::EMBED 
>> | VideoSurfaceTarget::WINDOWED | VideoSurfaceTarget::FULLSCREEN);
>>   }
>>     void 
>> CompositorDirectComposition::setVideoSurface(VideoSurfaceTarget 
>> target, QVariant targetParam)
>>   {
>> -    //N/A
>> +    if (!m_videoVisual)
>> +        return; //no video to attach
> 
> You may want to check that target != m_currentVideoSurface before
> doing all that.

Yes, ditto for the Win7 version.

>> +    try {
>> +
>> +    switch (m_currentVideoSurface)
>> +    {
>> +        case VideoSurfaceTarget::EMBED:
>> +            //no longer respond to events from the QML surface
>> +            m_qmlVideoSurfaceProvider->setVideoEmbed(false);
>> +            m_videoWindowHandler->setWindow(nullptr);
>> +            HR(m_rootVisual->RemoveVisual(m_videoVisual.Get()), 
>> "remove video visual from root");
>> +            msg_Dbg(m_intf, "disable EMBED video surface");
>> +        break;
>> +        case VideoSurfaceTarget::FULLSCREEN:
>> +        case VideoSurfaceTarget::WINDOWED:
>> +            m_videoWindowHandler->setWindow(nullptr);
>> +            HR(m_dcompDetachedVideoTarget->SetRoot(nullptr), "remove 
>> root video visual");
>> +            m_dcompDetachedVideoTarget.Reset();
>> +            m_detachedVideoWindow.reset();
>> +            msg_Dbg(m_intf, "disable WINDOWED video surface");
>> +        break;
>> +        default:
>> +        //N/A
>> +        break;
>> +
>> +    }
>> +
>> +    switch (target)
>> +    {
>> +        case VideoSurfaceTarget::EMBED:
>> +            HR(m_rootVisual->AddVisual(m_videoVisual.Get(), FALSE, 
>> m_uiVisual.Get()), "add video visual to root");
>> +            
>> m_videoWindowHandler->setWindow(m_rootWindow->windowHandle());
>> +            m_qmlVideoSurfaceProvider->setVideoEmbed(true);
>> +            msg_Dbg(m_intf, "enable EMBED video surface");
>> +        break;
>> +        case VideoSurfaceTarget::FULLSCREEN:
>> +        case VideoSurfaceTarget::WINDOWED:
>> +        {
>> +            m_detachedVideoWindow = 
>> std::make_unique<DetachedVideoWindow>(m_intf, m_window);
>> +            m_detachedVideoWindow->winId();
>> +            
>> HR(m_dcompDevice->CreateTargetForHwnd((HWND)m_detachedVideoWindow->winId(), 
>> TRUE, &m_dcompDetachedVideoTarget), "create target");
>> +            
>> HR(m_dcompDetachedVideoTarget->SetRoot(m_videoVisual.Get()), "root 
>> video visual");
>> +            
>> m_videoWindowHandler->setWindow(m_detachedVideoWindow->windowHandle());
>> +            connect(m_detachedVideoWindow.get(), 
>> &DetachedVideoWindow::windowClosed,
>> +                    this, [this]() {
>> +                
>> this->setVideoSurface(vlc::Compositor::VideoSurfaceTarget::EMBED);
>> +            }, Qt::QueuedConnection);
>> +            if (target == VideoSurfaceTarget::FULLSCREEN)
>> +            {
>> +                QString screename = targetParam.toString();
>> +                m_detachedVideoWindow->showFSOnScreen(screename, 
>> m_rootWindow->windowHandle());
>> +            }
>> +            else
>> +            {
>> +                m_detachedVideoWindow->show();
>> +            }
>> +            msg_Dbg(m_intf, "enable WINDOWED video surface");
>> +            break;
>> +        }
>> +        default:
>> +        //N/A
>> +        break;
>> +    }
>> +
>> +    HR(m_dcompDevice->Commit(), "commit");
>> +    m_currentVideoSurface = target;
>> +    m_currentVideoSurfaceParam = targetParam;
>> +    emit videoSurfaceChanged(m_currentVideoSurface, 
>> m_currentVideoSurfaceParam);
>> +
>> +} catch ( const DXError& err)
>> +{
>> +    msg_Err(m_intf, "failed to change video surface: %s, code 0x%lX", 
>> err.what(), err.code());
> 
> What kind of error can happen here ? It seems you can potentially be
> left in an "unfinished" state.

I'll add an assert unreachable

>> +}
>>   }
>>     Compositor::VideoSurfaceTarget 
>> CompositorDirectComposition::getVideoSurface(QVariant* param)
>>   {
>>       if (param)
>> -        *param = QVariant();
>> -    return VideoSurfaceTarget::UNDEF;
>> +        *param = m_currentVideoSurfaceParam;
>> +    return m_currentVideoSurface;
>>   }
>>   +
>>   }
>> diff --git a/modules/gui/qt/maininterface/compositor_dcomp.hpp 
>> b/modules/gui/qt/maininterface/compositor_dcomp.hpp
>> index 47ab504fb2..ec54a97ea9 100644
>> --- a/modules/gui/qt/maininterface/compositor_dcomp.hpp
>> +++ b/modules/gui/qt/maininterface/compositor_dcomp.hpp
>> @@ -31,6 +31,7 @@
>>   #include "videosurface.hpp"
>>   #include "interface_window_handler.hpp"
>>   #include "video_window_handler.hpp"
>> +#include "detached_video_window.hpp"
>>     #include <QOpenGLContext>
>>   @@ -83,6 +84,13 @@ private:
>>       Microsoft::WRL::ComPtr<IDCompositionVisual> m_rootVisual;
>>       Microsoft::WRL::ComPtr<IDCompositionVisual> m_uiVisual;
>>       Microsoft::WRL::ComPtr<IDCompositionVisual> m_videoVisual;
>> +
>> +    VideoSurfaceTarget m_currentVideoSurface = 
>> VideoSurfaceTarget::UNDEF;
>> +    QVariant m_currentVideoSurfaceParam;
>> +
>> +    //detached video window
>> +    std::unique_ptr<DetachedVideoWindow> m_detachedVideoWindow;
>> +    Microsoft::WRL::ComPtr<IDCompositionTarget> 
>> m_dcompDetachedVideoTarget;
>>   };
>>     }
>> -- 2.25.1
>> 
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
>> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list