diff --git a/AVQt/src/common/PixelFormat.cpp b/AVQt/src/common/PixelFormat.cpp
index 95a712fcb35037d0152f631cf1682adfd62f620c..d4972f392808ca19301e618eac938c31f9569811 100644
--- a/AVQt/src/common/PixelFormat.cpp
+++ b/AVQt/src/common/PixelFormat.cpp
@@ -80,7 +80,7 @@ namespace AVQt::common {
 
             AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_MMAL, .nativeFormat = nullptr});
             AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_MEDIACODEC, .nativeFormat = nullptr});
-            AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_QSV, .nativeFormat = &FullFormatPixelFormatOf});
+            AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_QSV, .nativeFormat = &OneInterleavedPlanePixelFormatOf});
             AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_VDPAU, .nativeFormat = nullptr});
             AVQt::common::PixelFormat::registerGPUFormat({.format = AV_PIX_FMT_VIDEOTOOLBOX, .nativeFormat = nullptr});
 
diff --git a/AVQt/src/decoder/QSVDecoderImpl.cpp b/AVQt/src/decoder/QSVDecoderImpl.cpp
index 1df16402d67e3047d035e82caad64a5b10ba21bd..14a71c9143ed67dd51455d6d045ac7bde2026edc 100644
--- a/AVQt/src/decoder/QSVDecoderImpl.cpp
+++ b/AVQt/src/decoder/QSVDecoderImpl.cpp
@@ -6,13 +6,14 @@
 #include "private/QSVDecoderImpl_p.hpp"
 
 #include "common/PixelFormat.hpp"
+#include "decoder/VideoDecoderFactory.hpp"
 
 namespace AVQt {
     const api::VideoDecoderInfo &QSVDecoderImpl::info() {
         static const api::VideoDecoderInfo info = {
                 .metaObject = QSVDecoderImpl::staticMetaObject,
-                .name = "VAAPI",
-                .platforms = {common::Platform::Linux_X11, common::Platform::Linux_Wayland},
+                .name = "QSV",
+                .platforms = {common::Platform::Linux_X11, common::Platform::Linux_Wayland, common::Platform::Windows},
                 .supportedInputPixelFormats = {
                         {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
                         {AV_PIX_FMT_YUV420P10, AV_PIX_FMT_NONE},
@@ -102,7 +103,7 @@ namespace AVQt {
 
             auto *framesContext = reinterpret_cast<AVHWFramesContext *>(framesCtxRef->data);
             framesContext->format = AV_PIX_FMT_QSV;
-            framesContext->sw_format = static_cast<AVPixelFormat>(d->codecParams->format);
+            framesContext->sw_format = common::PixelFormat{static_cast<AVPixelFormat>(d->codecParams->format), AV_PIX_FMT_QSV}.toNativeFormat().getCPUFormat();
             framesContext->width = d->codecParams->width;
             framesContext->height = d->codecParams->height;
             framesContext->initial_pool_size = 32;
@@ -128,6 +129,13 @@ namespace AVQt {
                 goto fail;
             }
 
+            d->frameFetcher = std::make_unique<QSVDecoderImplPrivate::FrameFetcher>(d);
+            d->frameFetcher->start();
+            if (!d->frameFetcher->isRunning()) {
+                qWarning() << "[AVQt::QSVDecoderImpl] Failed to start frame fetcher";
+                goto fail;
+            }
+
             return true;
         } else {
             qWarning("[AVQt::QSVDecoderImpl] Already opened");
@@ -135,6 +143,7 @@ namespace AVQt {
         }
     fail:
         d->open = false;
+        d->frameFetcher.reset();
         d->codecContext.reset();
         d->hwDeviceContext.reset();
         d->hwFramesContext.reset();
@@ -146,6 +155,7 @@ namespace AVQt {
 
         bool shouldBe = false;
         if (d->open.compare_exchange_strong(shouldBe, false)) {
+            d->frameFetcher.reset();
             d->codecContext.reset();
             d->hwDeviceContext.reset();
             d->hwFramesContext.reset();
@@ -308,3 +318,7 @@ namespace AVQt {
         qDebug() << "FrameFetcher stopped";
     }
 }// namespace AVQt
+
+static_block {
+    AVQt::VideoDecoderFactory::getInstance().registerDecoder(AVQt::QSVDecoderImpl::info());
+}
diff --git a/AVQt/src/decoder/QSVDecoderImpl.hpp b/AVQt/src/decoder/QSVDecoderImpl.hpp
index e26fff260c904a30912bb462f077a955c2a741ac..3915d738093fba372436afe745ba9e0375e9e890 100644
--- a/AVQt/src/decoder/QSVDecoderImpl.hpp
+++ b/AVQt/src/decoder/QSVDecoderImpl.hpp
@@ -14,10 +14,11 @@ namespace AVQt {
     class QSVDecoderImpl : public QObject, public api::IVideoDecoderImpl {
         Q_OBJECT
         Q_DECLARE_PRIVATE(QSVDecoderImpl)
+        Q_INTERFACES(AVQt::api::IVideoDecoderImpl)
     public:
         static const api::VideoDecoderInfo &info();
 
-        explicit QSVDecoderImpl(AVCodecID codecId, QObject *parent = nullptr);
+        Q_INVOKABLE explicit QSVDecoderImpl(AVCodecID codecId, QObject *parent = nullptr);
         ~QSVDecoderImpl() override;
         bool open(std::shared_ptr<AVCodecParameters> codecParams) override;
         void close() override;
diff --git a/AVQt/src/decoder/private/QSVDecoderImpl_p.hpp b/AVQt/src/decoder/private/QSVDecoderImpl_p.hpp
index b047224130f07c87f5f36da1333454c67964a5f1..f159008ffbabdb9037b2daffdd0f67117fe25c0f 100644
--- a/AVQt/src/decoder/private/QSVDecoderImpl_p.hpp
+++ b/AVQt/src/decoder/private/QSVDecoderImpl_p.hpp
@@ -50,6 +50,8 @@ namespace AVQt {
         std::shared_ptr<AVBufferRef> hwFramesContext{nullptr, &destroyAVBufferRef};
 
         std::atomic_bool open{false}, firstFrame{true};
+
+        std::unique_ptr<FrameFetcher> frameFetcher{};
     };
 }// namespace AVQt
 
diff --git a/AVQt/src/renderers/FallbackFrameMapper.cpp b/AVQt/src/renderers/FallbackFrameMapper.cpp
index ed4157b44d96aa6e6318b235f1ef823f826508cc..860b4f95362fa79dc90d6ba65fd0e61e77b98a7d 100644
--- a/AVQt/src/renderers/FallbackFrameMapper.cpp
+++ b/AVQt/src/renderers/FallbackFrameMapper.cpp
@@ -209,6 +209,7 @@ namespace AVQt {
         QMutexLocker lock(&d->renderMutex);
         bool shouldBe = true;
         if (d->running.compare_exchange_strong(shouldBe, false)) {
+            d->afterStopThread = QThread::currentThread();
             lock.unlock();
             QThread::quit();
             QThread::wait();
@@ -382,6 +383,9 @@ namespace AVQt {
             emit frameReady(frame->pts, fbo);
             qDebug("Frame ready");
         }
+        if (d->afterStopThread) {
+            d->context->moveToThread(d->afterStopThread);
+        }
     }
 
     void FallbackFrameMapperPrivate::bindResources() {
diff --git a/AVQt/src/renderers/private/FallbackFrameMapper_p.hpp b/AVQt/src/renderers/private/FallbackFrameMapper_p.hpp
index 97f1f75ecf2daa647b95053020928c347aa8e768..d86791b38e5958269812642e671fcbf4c1696fc8 100644
--- a/AVQt/src/renderers/private/FallbackFrameMapper_p.hpp
+++ b/AVQt/src/renderers/private/FallbackFrameMapper_p.hpp
@@ -73,6 +73,8 @@ namespace AVQt {
         QOpenGLBuffer vbo{};
         QOpenGLBuffer ibo{};
 
+        QThread *afterStopThread{nullptr};
+
         std::unique_ptr<SwsContext, decltype(&destroySwsContext)> pSwsContext{nullptr, &destroySwsContext};
 
         std::atomic_bool paused{false}, firstFrame{true}, running{false};
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b6fb8c837f51ab82344dd39a58d2b017e7faef2..5296a9e2db8e6e6e3ad89a25fe70774cdbc2919d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ if (NOT QT_VERSION)
 endif ()
 set(PGRAPH_QT_VERSION "${QT_VERSION}" CACHE INTERNAL "PGRAPH_QT_VERSION")
 set(SC_QT_VERSION "${QT_VERSION}" CACHE INTERNAL "SC_QT_VERSION")
-#set(CMAKE_PREFIX_PATH "/home/silas/ffmpeg_build/" CACHE INTERNAL "CMAKE_PREFIX_PATH")
+set(CMAKE_PREFIX_PATH "/home/silas/ffmpeg_build/" CACHE INTERNAL "CMAKE_PREFIX_PATH")
 
 add_subdirectory(libpgraph_network)
 
diff --git a/Player/OpenGlWidgetRenderer.cpp b/Player/OpenGlWidgetRenderer.cpp
index 9fe931511c8cc80c2982b8d87b7ac47efe78b331..7e637cd79f33426a77c63e9d8c95adb41a1de773 100644
--- a/Player/OpenGlWidgetRenderer.cpp
+++ b/Player/OpenGlWidgetRenderer.cpp
@@ -246,8 +246,8 @@ bool OpenGLWidgetRenderer::isPaused() const {
 bool OpenGLWidgetRenderer::open() {
     Q_D(OpenGLWidgetRenderer);
 
-    d->mapper = AVQt::OpenGLFrameMapperFactory::getInstance().create({d->params.isHWAccel ? d->params.swPixelFormat : d->params.pixelFormat, d->params.isHWAccel ? d->params.pixelFormat : AV_PIX_FMT_NONE},
-                                                                     QStringList() << "VAAPI");
+    d->mapper = AVQt::OpenGLFrameMapperFactory::getInstance()
+                        .create({d->params.isHWAccel ? d->params.swPixelFormat : d->params.pixelFormat, d->params.isHWAccel ? d->params.pixelFormat : AV_PIX_FMT_NONE});
     // clang-format off
     // Preserve normalized form of Qt SIGNAL/SLOT macro
     connect(std::dynamic_pointer_cast<QObject>(d->mapper).get(), SIGNAL(frameReady(qint64,std::shared_ptr<QOpenGLFramebufferObject>)),
diff --git a/Player/main.cpp b/Player/main.cpp
index ae94d15d7ba39a6a2efe16cab1f0529d0a62aa27..4046b4df1593eadf90bf349d7f3f2d3efdb7660c 100644
--- a/Player/main.cpp
+++ b/Player/main.cpp
@@ -53,9 +53,9 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
         logFile.open(QIODevice::WriteOnly);
     }
 
-    //#ifndef QT_DEBUG
+#ifndef QT_DEBUG
     if (type > QtMsgType::QtDebugMsg)
-    //#endif
+#endif
     {
         QString output;
         QTextStream os(&output);
@@ -144,7 +144,7 @@ int main(int argc, char *argv[]) {
     auto muxer = std::make_shared<AVQt::Muxer>(std::move(muxerConfig), registry);
 
     AVQt::VideoDecoder::Config videoDecoderConfig{};
-    videoDecoderConfig.decoderPriority << "VAAPI";
+    videoDecoderConfig.decoderPriority << "QSV";
     auto decoder1 = std::make_shared<AVQt::VideoDecoder>(videoDecoderConfig, registry);
     auto decoder2 = std::make_shared<AVQt::VideoDecoder>(videoDecoderConfig, registry);
     //    auto decoder3 = std::make_shared<AVQt::VideoDecoder>("VAAPI", registry);
@@ -220,9 +220,9 @@ int main(int argc, char *argv[]) {
         //    encoderInPad->link(decoder1OutPad);
         //    decoder2InPad->link(encoderOutPad);
         decoder1InPad->link(demuxerOutPad);
-        //    ccInPad->link(decoder1OutPad);
-        encoder1InPad->link(decoder1OutPad);
-        encoder2InPad->link(decoder1OutPad);
+        ccInPad->link(decoder1OutPad);
+        //        encoder1InPad->link(decoder1OutPad);
+        //        encoder2InPad->link(decoder1OutPad);
         //    yuvrgbconverterInPad->link(decoder1OutPad);
         //    renderer2InPad->link(decoder1OutPad);
         renderer1InPad->link(decoder1OutPad);
@@ -231,8 +231,8 @@ int main(int argc, char *argv[]) {
         //    renderer2InPad->link(decoder2OutPad);
         //    yuvrgbconverterOutPad->link(frameSaverInPad);
 
-        muxerInPad1->link(encoder1OutPad);
-        muxerInPad2->link(encoder2OutPad);
+        //        muxerInPad1->link(encoder1OutPad);
+        //        muxerInPad2->link(encoder2OutPad);
 
         demuxer->open();
 
@@ -241,9 +241,9 @@ int main(int argc, char *argv[]) {
 
         demuxer->start();
 
-        QTimer::singleShot(5000, [demuxer]() {
-            QApplication::quit();
-        });
+        //        QTimer::singleShot(5000, [demuxer]() {
+        //            QApplication::quit();
+        //        });
 
         //    QTimer::singleShot(4000, [demuxer]{
         //        demuxer->pause(true);