diff --git a/AVQt/CMakeLists.txt b/AVQt/CMakeLists.txt
index 2d92e7ac4d5e2bf2dd1dbdb869e17b52f9dbbdda..e25acb2bbccaae27fe138b8c508326c4aa8a055c 100644
--- a/AVQt/CMakeLists.txt
+++ b/AVQt/CMakeLists.txt
@@ -63,6 +63,10 @@ set(SOURCES
         filter/private/EncoderVAAPI_p.h
         filter/EncoderVAAPI.cpp
 
+        output/Muxer.h
+        output/private/Muxer_p.h
+        output/Muxer.cpp
+
         output/RenderClock.h
         output/private/RenderClock_p.h
         output/RenderClock.cpp
@@ -85,6 +89,7 @@ target_compile_options(AVQt PRIVATE
         -Werror=all
         -Werror=extra
         -Werror=pedantic
+        -Wno-float-equal
         -ansi
         -Werror=init-self
         -Werror=old-style-cast
diff --git a/AVQt/filter/AudioDecoder.cpp b/AVQt/filter/AudioDecoder.cpp
index 88dbccb5171de9d27f330b56f81482340951314a..f591355a9f1d1a7714f592948ea102b2732cc874 100644
--- a/AVQt/filter/AudioDecoder.cpp
+++ b/AVQt/filter/AudioDecoder.cpp
@@ -10,8 +10,6 @@
 
 #include <QtCore>
 
-#include <AL/al.h>
-#include <AL/alc.h>
 #include <AL/alext.h>
 
 namespace AVQt {
@@ -23,9 +21,12 @@ namespace AVQt {
         Q_D(AVQt::AudioDecoder);
     }
 
-    AudioDecoder::~AudioDecoder() {
-        deinit();
+    AudioDecoder::AudioDecoder(AudioDecoder &&other) noexcept: d_ptr(other.d_ptr) {
+        d_ptr->q_ptr = this;
+        other.d_ptr = nullptr;
+    }
 
+    AudioDecoder::~AudioDecoder() {
         delete d_ptr;
         d_ptr = nullptr;
     }
@@ -128,7 +129,7 @@ namespace AVQt {
         return d->m_paused.load();
     }
 
-    int AudioDecoder::registerCallback(IAudioSink *callback) {
+    qsizetype AudioDecoder::registerCallback(IAudioSink *callback) {
         Q_D(AVQt::AudioDecoder);
 
         QMutexLocker lock(&d->m_cbListMutex);
@@ -142,12 +143,13 @@ namespace AVQt {
             if (d->m_running) {
                 callback->start(this);
             }
+            return d->m_cbList.indexOf(callback);
         }
 
-        return 0;
+        return -1;
     }
 
-    int AudioDecoder::unregisterCallback(IAudioSink *callback) {
+    qsizetype AudioDecoder::unregisterCallback(IAudioSink *callback) {
         Q_D(AVQt::AudioDecoder);
 
         QMutexLocker lock(&d->m_cbListMutex);
@@ -161,10 +163,10 @@ namespace AVQt {
     void AudioDecoder::init(IPacketSource *source, AVRational framerate, AVRational timebase, int64_t duration, AVCodecParameters *vParams,
                             AVCodecParameters *aParams, AVCodecParameters *sParams) {
         Q_D(AVQt::AudioDecoder);
-        Q_UNUSED(source);
-        Q_UNUSED(framerate);
-        Q_UNUSED(vParams);
-        Q_UNUSED(sParams);
+        Q_UNUSED(source)
+        Q_UNUSED(framerate)
+        Q_UNUSED(vParams)
+        Q_UNUSED(sParams)
 
         d->m_timebase = timebase;
         d->m_duration = duration;
@@ -191,21 +193,21 @@ namespace AVQt {
 
     void AudioDecoder::start(IPacketSource *source) {
         Q_D(AVQt::AudioDecoder);
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         start();
     }
 
     void AudioDecoder::stop(IPacketSource *source) {
         Q_D(AVQt::AudioDecoder);
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         stop();
     }
 
     void AudioDecoder::onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) {
         Q_D(AVQt::AudioDecoder);
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         if (packetType == IPacketSource::CB_AUDIO) {
             AVPacket *queuePacket = av_packet_clone(packet);
@@ -225,7 +227,7 @@ namespace AVQt {
                 QTime time1 = QTime::currentTime();
                 qDebug("Audio packet queue size: %lld", d->m_inputQueue.size());
 
-                int ret = 0;
+                int ret;
                 constexpr size_t strBufSize = 64;
                 char strBuf[strBufSize];
 
@@ -291,12 +293,13 @@ namespace AVQt {
                         qDebug("Calling audio frame callback for PTS: %ld, Timebase: %d/%d", cbFrame->pts, d->m_timebase.num,
                                d->m_timebase.den);
                         QTime time = QTime::currentTime();
-                        cb->onAudioFrame(this, cbFrame, frame->nb_samples * 1.0 / frame->sample_rate / frame->channels * 1000.0);
+                        cb->onAudioFrame(this, cbFrame,
+                                         static_cast<uint32_t>(frame->nb_samples * 1.0 / frame->sample_rate / frame->channels * 1000.0));
                         qDebug() << "Audio CB time:" << time.msecsTo(QTime::currentTime());
                         av_frame_unref(cbFrame);
                     }
                     int64_t sleepDuration = (frame->nb_samples / frame->sample_rate * 1000) - time1.msecsTo(QTime::currentTime());
-                    msleep(sleepDuration <= 0 ? 0 : sleepDuration);
+                    msleep(sleepDuration <= 0 ? 0 : static_cast<unsigned long>(sleepDuration));
                     time1 = QTime::currentTime();
                     av_frame_unref(frame);
                 }
diff --git a/AVQt/filter/AudioDecoder.h b/AVQt/filter/AudioDecoder.h
index 44487311c0bcdb733dc03bada30031afc37f3e0a..6b198c176cb685a2796619e19308ec1543ee16b6 100644
--- a/AVQt/filter/AudioDecoder.h
+++ b/AVQt/filter/AudioDecoder.h
@@ -24,13 +24,19 @@ namespace AVQt {
     public:
         explicit AudioDecoder(QObject *parent = nullptr);
 
+        AudioDecoder(AudioDecoder &&other) noexcept;
+
+        AudioDecoder(const AudioDecoder &) = delete;
+
+        void operator=(const AudioDecoder &) = delete;
+
         ~AudioDecoder() Q_DECL_OVERRIDE;
 
         bool isPaused() Q_DECL_OVERRIDE;
 
-        int registerCallback(IAudioSink *callback) Q_DECL_OVERRIDE;
+        qsizetype registerCallback(IAudioSink *callback) Q_DECL_OVERRIDE;
 
-        int unregisterCallback(IAudioSink *callback) Q_DECL_OVERRIDE;
+        qsizetype unregisterCallback(IAudioSink *callback) Q_DECL_OVERRIDE;
 
         void run() Q_DECL_OVERRIDE;
 
@@ -73,4 +79,4 @@ namespace AVQt {
     };
 }
 
-#endif //LIBAVQT_AUDIODECODER_H
+#endif //LIBAVQT_AUDIODECODER_H
\ No newline at end of file
diff --git a/AVQt/filter/DecoderDXVA2.cpp b/AVQt/filter/DecoderDXVA2.cpp
index 3362f7a34e45aba3775aae6a5fcbdc2f6c3027c3..151668d4b02fdcdd3f3ec9aa986422f174b6c9f9 100644
--- a/AVQt/filter/DecoderDXVA2.cpp
+++ b/AVQt/filter/DecoderDXVA2.cpp
@@ -10,12 +10,11 @@
 
 #include <QApplication>
 #include <QtConcurrent>
-#include <QImage>
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-#define NOW() std::chrono::high_resolution_clock::now()
-#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
-#endif
+//#ifndef DOXYGEN_SHOULD_SKIP_THIS
+//#define NOW() std::chrono::high_resolution_clock::now()
+//#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
+//#endif
 
 
 namespace AVQt {
@@ -27,9 +26,12 @@ namespace AVQt {
 
     }
 
-    DecoderDXVA2::~DecoderDXVA2() {
-        deinit();
+    DecoderDXVA2::DecoderDXVA2(DecoderDXVA2 &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
 
+    DecoderDXVA2::~DecoderDXVA2() {
         delete d_ptr;
     }
 
@@ -158,7 +160,7 @@ namespace AVQt {
         return d->m_paused.load();
     }
 
-    int DecoderDXVA2::registerCallback(IFrameSink *frameSink) {
+    qsizetype DecoderDXVA2::registerCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderDXVA2);
 
         QMutexLocker lock(&d->m_cbListMutex);
@@ -173,11 +175,11 @@ namespace AVQt {
         return -1;
     }
 
-    int DecoderDXVA2::unregisterCallback(IFrameSink *frameSink) {
+    qsizetype DecoderDXVA2::unregisterCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderDXVA2);
         QMutexLocker lock(&d->m_cbListMutex);
         if (d->m_cbList.contains(frameSink)) {
-            int result = d->m_cbList.indexOf(frameSink);
+            auto result = d->m_cbList.indexOf(frameSink);
             d->m_cbList.removeOne(frameSink);
             frameSink->stop(this);
             frameSink->deinit(this);
@@ -187,7 +189,7 @@ namespace AVQt {
     }
 
     void DecoderDXVA2::onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) {
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         Q_D(AVQt::DecoderDXVA2);
 
diff --git a/AVQt/filter/DecoderDXVA2.h b/AVQt/filter/DecoderDXVA2.h
index 9079a432095def79cb3ade21224bbdf3d5aa4582..501b565bfb5c70b0c20df2b5edaf1555c8bb4a8d 100644
--- a/AVQt/filter/DecoderDXVA2.h
+++ b/AVQt/filter/DecoderDXVA2.h
@@ -35,10 +35,10 @@ namespace AVQt {
      * that either at least one callback is registered or the decoder is paused, or frames will be dropped
      */
     class DecoderDXVA2 : public QThread, public IDecoder {
-        Q_OBJECT
-            Q_INTERFACES(AVQt::IDecoder)
-    //        Q_INTERFACES(AVQt::IFrameSource)
-    //        Q_INTERFACES(AVQt::IPacketSink)
+    Q_OBJECT
+        Q_INTERFACES(AVQt::IDecoder)
+        //        Q_INTERFACES(AVQt::IFrameSource)
+        //        Q_INTERFACES(AVQt::IPacketSink)
 
         Q_DECLARE_PRIVATE(AVQt::DecoderDXVA2)
 
@@ -52,6 +52,18 @@ namespace AVQt {
          */
         explicit DecoderDXVA2(QObject *parent = nullptr);
 
+        DecoderDXVA2(DecoderDXVA2 &&other) noexcept;
+
+        /*!
+         * \private
+         */
+        DecoderDXVA2(const DecoderDXVA2 &) = delete;
+
+        /*!
+         * \private
+         */
+        void operator=(const DecoderDXVA2 &) = delete;
+
         /*!
          * \private
          */
@@ -69,14 +81,14 @@ namespace AVQt {
          * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE
          * @return Current position in callback list
          */
-        Q_INVOKABLE int registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
         /*!
          * \brief Removes frame sink/filter from registry
          * @param frameSink Frame sink/filter to be removed
          * @return Last position in callback list, -1 when not found
          */
-        Q_INVOKABLE int unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
     public slots:
         /*!
@@ -160,4 +172,4 @@ namespace AVQt {
 
 }
 
-#endif //TRANSCODE_DECODERDXVA2_H
+#endif //TRANSCODE_DECODERDXVA2_H
\ No newline at end of file
diff --git a/AVQt/filter/DecoderQSV.cpp b/AVQt/filter/DecoderQSV.cpp
index 0ed9cf21bf62752952bdc654054c3228382bf02b..f8162528edd595a8db074f2fd399e65092f3331c 100644
--- a/AVQt/filter/DecoderQSV.cpp
+++ b/AVQt/filter/DecoderQSV.cpp
@@ -10,12 +10,11 @@
 
 #include <QApplication>
 #include <QtConcurrent>
-#include <QImage>
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-#define NOW() std::chrono::high_resolution_clock::now()
-#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
-#endif
+//#ifndef DOXYGEN_SHOULD_SKIP_THIS
+//#define NOW() std::chrono::high_resolution_clock::now()
+//#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
+//#endif
 
 
 namespace AVQt {
@@ -27,9 +26,12 @@ namespace AVQt {
 
     }
 
-    DecoderQSV::~DecoderQSV() {
-        deinit();
+    DecoderQSV::DecoderQSV(DecoderQSV &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
 
+    DecoderQSV::~DecoderQSV() {
         delete d_ptr;
     }
 
@@ -158,7 +160,7 @@ namespace AVQt {
         return d->m_paused.load();
     }
 
-    int DecoderQSV::registerCallback(IFrameSink *frameSink) {
+    qsizetype DecoderQSV::registerCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderQSV);
 
         QMutexLocker lock(&d->m_cbListMutex);
@@ -173,11 +175,11 @@ namespace AVQt {
         return -1;
     }
 
-    int DecoderQSV::unregisterCallback(IFrameSink *frameSink) {
+    qsizetype DecoderQSV::unregisterCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderQSV);
         QMutexLocker lock(&d->m_cbListMutex);
         if (d->m_cbList.contains(frameSink)) {
-            int result = d->m_cbList.indexOf(frameSink);
+            auto result = d->m_cbList.indexOf(frameSink);
             d->m_cbList.removeOne(frameSink);
             frameSink->stop(this);
             frameSink->deinit(this);
@@ -187,7 +189,7 @@ namespace AVQt {
     }
 
     void DecoderQSV::onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) {
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         Q_D(AVQt::DecoderQSV);
 
@@ -206,7 +208,7 @@ namespace AVQt {
 
         while (d->m_running) {
             if (!d->m_paused.load() && !d->m_inputQueue.isEmpty()) {
-                int ret = 0;
+                int ret;
                 constexpr size_t strBufSize = 64;
                 char strBuf[strBufSize];
                 // If m_pCodecParams is nullptr, it is not initialized by packet source, if video codec context is nullptr, this is the first packet
diff --git a/AVQt/filter/DecoderQSV.h b/AVQt/filter/DecoderQSV.h
index 30a15ac507470295561b7d843e2af3a2b165e623..b23e824d3d77c272cbfa379ea581c391dcc6a6f8 100644
--- a/AVQt/filter/DecoderQSV.h
+++ b/AVQt/filter/DecoderQSV.h
@@ -52,6 +52,18 @@ namespace AVQt {
          */
         explicit DecoderQSV(QObject *parent = nullptr);
 
+        DecoderQSV(DecoderQSV &&other) noexcept;
+
+        /*!
+         * \private
+         */
+        DecoderQSV(const DecoderQSV &) = delete;
+
+        /*!
+         * \private
+         */
+        void operator=(const DecoderQSV &) = delete;
+
         /*!
          * \private
          */
@@ -69,14 +81,14 @@ namespace AVQt {
          * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE
          * @return Current position in callback list
          */
-        Q_INVOKABLE int registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
         /*!
          * \brief Removes frame sink/filter from registry
          * @param frameSink Frame sink/filter to be removed
          * @return Last position in callback list, -1 when not found
          */
-        Q_INVOKABLE int unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
     public slots:
         /*!
diff --git a/AVQt/filter/DecoderVAAPI.cpp b/AVQt/filter/DecoderVAAPI.cpp
index 7bd0a2e9de25b24eea7a6be0526f9355e1b3918a..9ab4713cc62e6b5515ede7cf17d882e56f1e4b7f 100644
--- a/AVQt/filter/DecoderVAAPI.cpp
+++ b/AVQt/filter/DecoderVAAPI.cpp
@@ -10,12 +10,11 @@
 
 #include <QApplication>
 #include <QtConcurrent>
-#include <QImage>
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-#define NOW() std::chrono::high_resolution_clock::now()
-#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
-#endif
+//#ifndef DOXYGEN_SHOULD_SKIP_THIS
+//#define NOW() std::chrono::high_resolution_clock::now()
+//#define TIME_US(t1, t2) std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
+//#endif
 
 
 namespace AVQt {
@@ -27,9 +26,12 @@ namespace AVQt {
 
     }
 
-    DecoderVAAPI::~DecoderVAAPI() {
-        deinit();
+    DecoderVAAPI::DecoderVAAPI(DecoderVAAPI &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
 
+    DecoderVAAPI::~DecoderVAAPI() {
         delete d_ptr;
     }
 
@@ -158,7 +160,7 @@ namespace AVQt {
         return d->m_paused.load();
     }
 
-    int DecoderVAAPI::registerCallback(IFrameSink *frameSink) {
+    qsizetype DecoderVAAPI::registerCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderVAAPI);
 
         QMutexLocker lock(&d->m_cbListMutex);
@@ -173,11 +175,11 @@ namespace AVQt {
         return -1;
     }
 
-    int DecoderVAAPI::unregisterCallback(IFrameSink *frameSink) {
+    qsizetype DecoderVAAPI::unregisterCallback(IFrameSink *frameSink) {
         Q_D(AVQt::DecoderVAAPI);
         QMutexLocker lock(&d->m_cbListMutex);
         if (d->m_cbList.contains(frameSink)) {
-            int result = d->m_cbList.indexOf(frameSink);
+            auto result = d->m_cbList.indexOf(frameSink);
             d->m_cbList.removeOne(frameSink);
             frameSink->stop(this);
             frameSink->deinit(this);
@@ -187,7 +189,7 @@ namespace AVQt {
     }
 
     void DecoderVAAPI::onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) {
-        Q_UNUSED(source);
+        Q_UNUSED(source)
 
         Q_D(AVQt::DecoderVAAPI);
 
@@ -206,7 +208,7 @@ namespace AVQt {
 
         while (d->m_running) {
             if (!d->m_paused.load() && !d->m_inputQueue.isEmpty()) {
-                int ret = 0;
+                int ret;
                 constexpr size_t strBufSize = 64;
                 char strBuf[strBufSize];
                 // If m_pCodecParams is nullptr, it is not initialized by packet source, if video codec context is nullptr, this is the first packet
@@ -280,16 +282,16 @@ namespace AVQt {
 //                    QList<QFuture<void>> cbFutures;
                     for (const auto &cb: d->m_cbList) {
 //                        cbFutures.append(QtConcurrent::run([=] {
-                            AVFrame *cbFrame = av_frame_clone(frame);
-                            cbFrame->pts = av_rescale_q(frame->pts, d->m_timebase,
-                                                        av_make_q(1, 1000000)); // Rescale pts to microseconds for easier processing
-                            qDebug("Calling video frame callback for PTS: %ld, Timebase: %d/%d", cbFrame->pts, d->m_timebase.num,
-                                   d->m_timebase.den);
-                            QTime time = QTime::currentTime();
-                            cb->onFrame(this, cbFrame, static_cast<int64_t>(av_q2d(av_inv_q(d->m_framerate)) * 1000.0));
-                            qDebug() << "Video CB time:" << time.msecsTo(QTime::currentTime());
-                            av_frame_unref(cbFrame);
-                            av_frame_free(&cbFrame);
+                        AVFrame *cbFrame = av_frame_clone(frame);
+                        cbFrame->pts = av_rescale_q(frame->pts, d->m_timebase,
+                                                    av_make_q(1, 1000000)); // Rescale pts to microseconds for easier processing
+                        qDebug("Calling video frame callback for PTS: %ld, Timebase: %d/%d", cbFrame->pts, d->m_timebase.num,
+                               d->m_timebase.den);
+                        QTime time = QTime::currentTime();
+                        cb->onFrame(this, cbFrame, static_cast<int64_t>(av_q2d(av_inv_q(d->m_framerate)) * 1000.0));
+                        qDebug() << "Video CB time:" << time.msecsTo(QTime::currentTime());
+                        av_frame_unref(cbFrame);
+                        av_frame_free(&cbFrame);
 //                        }));
                     }
 //                    bool cbBusy = true;
diff --git a/AVQt/filter/DecoderVAAPI.h b/AVQt/filter/DecoderVAAPI.h
index 3bb315c57201671f9de1564b70ea3116aece62b2..bab451b6ac12b6dabd6f4881d85b27169e2d1340 100644
--- a/AVQt/filter/DecoderVAAPI.h
+++ b/AVQt/filter/DecoderVAAPI.h
@@ -52,6 +52,18 @@ namespace AVQt {
          */
         explicit DecoderVAAPI(QObject *parent = nullptr);
 
+        DecoderVAAPI(DecoderVAAPI &&other) noexcept;
+
+        /*!
+         * \private
+         */
+        DecoderVAAPI(const DecoderVAAPI &) = delete;
+
+        /*!
+         * \private
+         */
+        void operator=(const DecoderVAAPI &) = delete;
+
         /*!
          * \private
          */
@@ -69,14 +81,14 @@ namespace AVQt {
          * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE
          * @return Current position in callback list
          */
-        Q_INVOKABLE int registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
         /*!
          * \brief Removes frame sink/filter from registry
          * @param frameSink Frame sink/filter to be removed
          * @return Last position in callback list, -1 when not found
          */
-        Q_INVOKABLE int unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE;
 
     public slots:
         /*!
@@ -160,4 +172,4 @@ namespace AVQt {
 
 }
 
-#endif //TRANSCODE_DECODERVAAPI_H
+#endif //TRANSCODE_DECODERVAAPI_H
\ No newline at end of file
diff --git a/AVQt/filter/EncoderVAAPI.cpp b/AVQt/filter/EncoderVAAPI.cpp
index 7ce43ec0c972f188684b8bb75920865a5038ae9a..14acd26f196e12b838758759de4cf57ce9dc5c9d 100644
--- a/AVQt/filter/EncoderVAAPI.cpp
+++ b/AVQt/filter/EncoderVAAPI.cpp
@@ -5,7 +5,6 @@
 #include "private/EncoderVAAPI_p.h"
 #include "EncoderVAAPI.h"
 
-#include <QtCore>
 #include "output/IPacketSink.h"
 
 namespace AVQt {
@@ -19,6 +18,11 @@ namespace AVQt {
 
     }
 
+    EncoderVAAPI::EncoderVAAPI(EncoderVAAPI &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
+
     EncoderVAAPI::~EncoderVAAPI() {
         delete d_ptr;
     }
@@ -120,7 +124,7 @@ namespace AVQt {
     }
 
     int EncoderVAAPI::init(IFrameSource *source, AVRational framerate, int64_t duration) {
-        Q_UNUSED(source);
+        Q_UNUSED(source)
         Q_UNUSED(duration)
         Q_D(AVQt::EncoderVAAPI);
         d->m_framerate = framerate;
@@ -155,7 +159,7 @@ namespace AVQt {
         this->pause(paused);
     }
 
-    qsizetype EncoderVAAPI::registerCallback(IPacketSink *packetSink, uint8_t type) {
+    qsizetype EncoderVAAPI::registerCallback(IPacketSink *packetSink, int8_t type) {
         Q_D(AVQt::EncoderVAAPI);
 
         if (type != IPacketSource::CB_VIDEO) {
@@ -184,7 +188,7 @@ namespace AVQt {
     }
 
     void EncoderVAAPI::onFrame(IFrameSource *source, AVFrame *frame, int64_t frameDuration) {
-        Q_UNUSED(source);
+        Q_UNUSED(source)
         Q_D(AVQt::EncoderVAAPI);
 
         QPair<AVFrame *, int64_t> queueFrame{av_frame_alloc(), frameDuration};
@@ -213,7 +217,7 @@ namespace AVQt {
     void EncoderVAAPI::run() {
         Q_D(AVQt::EncoderVAAPI);
 
-        int ret{0};
+        int ret;
         constexpr auto strBufSize{64};
         char strBuf[strBufSize];
 
@@ -340,12 +344,8 @@ namespace AVQt {
         delete d_ptr;
         d_ptr = other.d_ptr;
         other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
 
         return *this;
     }
-
-    EncoderVAAPI::EncoderVAAPI(EncoderVAAPI &&other) {
-        d_ptr = other.d_ptr;
-        other.d_ptr = nullptr;
-    }
 }
\ No newline at end of file
diff --git a/AVQt/filter/EncoderVAAPI.h b/AVQt/filter/EncoderVAAPI.h
index 1b00d8e9ffa0a1fa179504206330a8c4bfc07c6a..dec1e74bf15450cd259f36a222e3e18d007b7ae9 100644
--- a/AVQt/filter/EncoderVAAPI.h
+++ b/AVQt/filter/EncoderVAAPI.h
@@ -34,19 +34,19 @@ namespace AVQt {
     public:
         explicit EncoderVAAPI(QString encoder, QObject *parent = nullptr);
 
-        explicit EncoderVAAPI(EncoderVAAPI &other) = delete;
+        EncoderVAAPI(EncoderVAAPI &&other) noexcept;
 
-        explicit EncoderVAAPI(EncoderVAAPI &&other);
+        explicit EncoderVAAPI(EncoderVAAPI &other) = delete;
 
-        ~EncoderVAAPI() override;
+        ~EncoderVAAPI() Q_DECL_OVERRIDE;
 
-        bool isPaused() override;
+        bool isPaused() Q_DECL_OVERRIDE;
 
-        qsizetype registerCallback(IPacketSink *packetSink, uint8_t type) override;
+        qsizetype registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE;
 
-        qsizetype unregisterCallback(IPacketSink *packetSink) override;
+        qsizetype unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE;
 
-        void run() override;
+        void run() Q_DECL_OVERRIDE;
 
         EncoderVAAPI &operator=(const EncoderVAAPI &other) = delete;
 
@@ -54,35 +54,35 @@ namespace AVQt {
 
     public slots:
 
-        Q_INVOKABLE int init() override;
+        Q_INVOKABLE int init() Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int deinit() override;
+        Q_INVOKABLE int deinit() Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int start() override;
+        Q_INVOKABLE int start() Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int stop() override;
+        Q_INVOKABLE int stop() Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE void pause(bool pause) override;
+        Q_INVOKABLE void pause(bool pause) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int init(IFrameSource *source, AVRational framerate, int64_t duration) override;
+        Q_INVOKABLE int init(IFrameSource *source, AVRational framerate, int64_t duration) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int deinit(IFrameSource *source) override;
+        Q_INVOKABLE int deinit(IFrameSource *source) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int start(IFrameSource *source) override;
+        Q_INVOKABLE int start(IFrameSource *source) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE int stop(IFrameSource *source) override;
+        Q_INVOKABLE int stop(IFrameSource *source) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE void pause(IFrameSource *source, bool paused) override;
+        Q_INVOKABLE void pause(IFrameSource *source, bool paused) Q_DECL_OVERRIDE;
 
-        Q_INVOKABLE void onFrame(IFrameSource *source, AVFrame *frame, int64_t frameDuration) override;
+        Q_INVOKABLE void onFrame(IFrameSource *source, AVFrame *frame, int64_t frameDuration) Q_DECL_OVERRIDE;
 
     signals:
 
-        void started() override;
+        void started() Q_DECL_OVERRIDE;
 
-        void stopped() override;
+        void stopped() Q_DECL_OVERRIDE;
 
-        void paused(bool pause) override;
+        void paused(bool pause) Q_DECL_OVERRIDE;
 
     protected:
         [[maybe_unused]] explicit EncoderVAAPI(EncoderVAAPIPrivate &p);
diff --git a/AVQt/filter/IDecoder.h b/AVQt/filter/IDecoder.h
index 2751e39d00f9b157f3468901178c73a616e0ad77..a55e45983721ccaf7e04bbe724c4805027cef8a4 100644
--- a/AVQt/filter/IDecoder.h
+++ b/AVQt/filter/IDecoder.h
@@ -9,38 +9,54 @@
 #define LIBAVQT_DECODER_H
 
 namespace AVQt {
-    class IDecoder: public IFrameSource, public IPacketSink {
+    class IDecoder : public IFrameSource, public IPacketSink {
 
 
         // IPacketSink interface
     public:
-        ~IDecoder() override {};
-        virtual bool isPaused() override = 0;
-        virtual void init(IPacketSource *source, AVRational framerate, AVRational timebase, int64_t duration, AVCodecParameters *vParams, AVCodecParameters *aParams, AVCodecParameters *sParams) override = 0;
-        virtual void deinit(IPacketSource *source) override = 0;
-        virtual void start(IPacketSource *source) override = 0;
-        virtual void stop(IPacketSource *source) override = 0;
-        virtual void pause(bool paused) override = 0;
-        virtual void onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) override = 0;
+        ~IDecoder() Q_DECL_OVERRIDE {};
+
+        virtual bool isPaused() Q_DECL_OVERRIDE = 0;
+
+        virtual void init(IPacketSource *source, AVRational framerate, AVRational timebase, int64_t duration, AVCodecParameters *vParams,
+                          AVCodecParameters *aParams, AVCodecParameters *sParams) Q_DECL_OVERRIDE = 0;
+
+        virtual void deinit(IPacketSource *source) Q_DECL_OVERRIDE = 0;
+
+        virtual void start(IPacketSource *source) Q_DECL_OVERRIDE = 0;
+
+        virtual void stop(IPacketSource *source) Q_DECL_OVERRIDE = 0;
+
+        virtual void pause(bool paused) Q_DECL_OVERRIDE = 0;
+
+        virtual void onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) Q_DECL_OVERRIDE = 0;
 
     signals:
-        virtual void started() override = 0;
-        virtual void stopped() override = 0;
+
+        virtual void started() Q_DECL_OVERRIDE = 0;
+
+        virtual void stopped() Q_DECL_OVERRIDE = 0;
 
         // IFrameSource interface
     public:
-        virtual int registerCallback(IFrameSink *frameSink) override = 0;
-        virtual int unregisterCallback(IFrameSink *frameSink) override = 0;
-        virtual int init() override = 0;
-        virtual int deinit() override = 0;
-        virtual int start() override = 0;
-        virtual int stop() override = 0;
+        virtual qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0;
+
+        virtual qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0;
+
+        virtual int init() Q_DECL_OVERRIDE = 0;
+
+        virtual int deinit() Q_DECL_OVERRIDE = 0;
+
+        virtual int start() Q_DECL_OVERRIDE = 0;
+
+        virtual int stop() Q_DECL_OVERRIDE = 0;
 
     signals:
-        virtual void paused(bool pause) override = 0;
+
+        virtual void paused(bool pause) Q_DECL_OVERRIDE = 0;
     };
 }
 
 Q_DECLARE_INTERFACE(AVQt::IDecoder, "AVQt::IDecoder")
 
-#endif //LIBAVQT_DECODER_H
+#endif //LIBAVQT_DECODER_H
\ No newline at end of file
diff --git a/AVQt/filter/IEncoder.h b/AVQt/filter/IEncoder.h
index a262a025e7777991a3b0afdf49759c2d797a04d3..d3e1adafbb504db9aaa27bcb5f7346de2d8b6cbc 100644
--- a/AVQt/filter/IEncoder.h
+++ b/AVQt/filter/IEncoder.h
@@ -46,7 +46,7 @@ namespace AVQt {
 
         Q_INVOKABLE virtual void pause(bool pause) = 0;
 
-        Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, uint8_t type) = 0;
+        Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, int8_t type) = 0;
 
         Q_INVOKABLE virtual qsizetype unregisterCallback(IPacketSink *packetSink) = 0;
 
diff --git a/AVQt/filter/private/AudioDecoder_p.h b/AVQt/filter/private/AudioDecoder_p.h
index b766659c69a94e49902c1e37341165971a64ed80..9e11a3e02456cb3c2e08b3c17efa0fe88d282585 100644
--- a/AVQt/filter/private/AudioDecoder_p.h
+++ b/AVQt/filter/private/AudioDecoder_p.h
@@ -20,29 +20,35 @@ extern "C" {
 
 namespace AVQt {
     class AudioDecoderPrivate {
+    public:
+        AudioDecoderPrivate(const AudioDecoderPrivate &) = delete;
+
+        void operator=(const AudioDecoderPrivate &) = delete;
+
+    private:
         explicit AudioDecoderPrivate(AudioDecoder *q) : q_ptr(q) {};
 
         AudioDecoder *q_ptr;
 
-        QMutex m_inputQueueMutex;
-        QQueue<AVPacket *> m_inputQueue;
-        int64_t m_duration {0};
+        QMutex m_inputQueueMutex{};
+        QQueue<AVPacket *> m_inputQueue{};
+        int64_t m_duration{0};
 
-        AVCodecParameters *m_pCodecParams {nullptr};
-        AVCodec *m_pCodec {nullptr};
-        AVCodecContext *m_pCodecCtx {nullptr};
-        AVRational m_timebase;
+        AVCodecParameters *m_pCodecParams{nullptr};
+        AVCodec *m_pCodec{nullptr};
+        AVCodecContext *m_pCodecCtx{nullptr};
+        AVRational m_timebase{0, 1};
 
         // Callback stuff
-        QMutex m_cbListMutex;
-        QList<IAudioSink *> m_cbList;
+        QMutex m_cbListMutex{};
+        QList<IAudioSink *> m_cbList{};
 
         // Threading stuff
-        std::atomic_bool m_running  {false};
-        std::atomic_bool m_paused  {false};
+        std::atomic_bool m_running{false};
+        std::atomic_bool m_paused{false};
 
         friend class AudioDecoder;
     };
 }
 
-#endif //LIBAVQT_AUDIODECODER_P_H
+#endif //LIBAVQT_AUDIODECODER_P_H
\ No newline at end of file
diff --git a/AVQt/filter/private/DecoderDXVA2_p.h b/AVQt/filter/private/DecoderDXVA2_p.h
index c532b1ca1cb7d7ce8541406dd5dd8f2d50293c9f..87c8cc3f23d40035984c762d8002c4db11fb1138 100644
--- a/AVQt/filter/private/DecoderDXVA2_p.h
+++ b/AVQt/filter/private/DecoderDXVA2_p.h
@@ -16,6 +16,13 @@ namespace AVQt {
     * \private
     */
     class DecoderDXVA2Private {
+    public:
+        DecoderDXVA2Private(const DecoderDXVA2Private &) = delete;
+
+        void operator=(const DecoderDXVA2Private &) = delete;
+
+    private:
+
         explicit DecoderDXVA2Private(DecoderDXVA2 *q) : q_ptr(q) {};
 
         DecoderDXVA2 *q_ptr;
diff --git a/AVQt/filter/private/DecoderQSV_p.h b/AVQt/filter/private/DecoderQSV_p.h
index 0e4112760821a0f900aa6b1b922802cddcc4985d..ef82bc0524eda150b17de6eb0fc7d0a05b6761be 100644
--- a/AVQt/filter/private/DecoderQSV_p.h
+++ b/AVQt/filter/private/DecoderQSV_p.h
@@ -18,15 +18,21 @@ namespace AVQt {
      * \private
      */
     class DecoderQSVPrivate {
+    public:
+        DecoderQSVPrivate(const DecoderQSVPrivate &) = delete;
+
+        void operator=(const DecoderQSVPrivate &) = delete;
+
+    private:
         explicit DecoderQSVPrivate(DecoderQSV *q) : q_ptr(q) {};
 
         DecoderQSV *q_ptr;
 
-        QMutex m_inputQueueMutex;
-        QQueue<AVPacket *> m_inputQueue;
+        QMutex m_inputQueueMutex{};
+        QQueue<AVPacket *> m_inputQueue{};
         int64_t m_duration{0};
-        AVRational m_framerate;
-        AVRational m_timebase;
+        AVRational m_framerate{};
+        AVRational m_timebase{};
 
         AVCodec *m_pCodec{nullptr};
         AVCodecParameters *m_pCodecParams{nullptr};
@@ -34,8 +40,8 @@ namespace AVQt {
         AVBufferRef *m_pDeviceCtx{nullptr};
 
         // Callback stuff
-        QMutex m_cbListMutex;
-        QList<IFrameSink *> m_cbList;
+        QMutex m_cbListMutex{};
+        QList<IFrameSink *> m_cbList{};
 
         // Threading stuff
         std::atomic_bool m_running{false};
diff --git a/AVQt/filter/private/DecoderVAAPI_p.h b/AVQt/filter/private/DecoderVAAPI_p.h
index 12cf4c882a9aabe536cbbcdaebbb4c435cc8f494..4a1f6f9184aa73f03283f9182804ccf9b5e9370f 100644
--- a/AVQt/filter/private/DecoderVAAPI_p.h
+++ b/AVQt/filter/private/DecoderVAAPI_p.h
@@ -18,15 +18,21 @@ namespace AVQt {
      * \private
      */
     class DecoderVAAPIPrivate {
+    public:
+        DecoderVAAPIPrivate(const DecoderVAAPIPrivate &) = delete;
+
+        void operator=(const DecoderVAAPIPrivate &) = delete;
+
+    private:
         explicit DecoderVAAPIPrivate(DecoderVAAPI *q) : q_ptr(q) {};
 
         DecoderVAAPI *q_ptr;
 
-        QMutex m_inputQueueMutex;
-        QQueue<AVPacket *> m_inputQueue;
+        QMutex m_inputQueueMutex{};
+        QQueue<AVPacket *> m_inputQueue{};
         int64_t m_duration{0};
-        AVRational m_framerate;
-        AVRational m_timebase;
+        AVRational m_framerate{};
+        AVRational m_timebase{};
 
         AVCodec *m_pCodec{nullptr};
         AVCodecParameters *m_pCodecParams{nullptr};
@@ -34,8 +40,8 @@ namespace AVQt {
         AVBufferRef *m_pDeviceCtx{nullptr};
 
         // Callback stuff
-        QMutex m_cbListMutex;
-        QList<IFrameSink *> m_cbList;
+        QMutex m_cbListMutex{};
+        QList<IFrameSink *> m_cbList{};
 
         // Threading stuff
         std::atomic_bool m_running{false};
diff --git a/AVQt/filter/private/EncoderVAAPI_p.h b/AVQt/filter/private/EncoderVAAPI_p.h
index d7be7f1186a6113d8c3a5887f39fb4ea5fd59c77..239bd63c8fde9d4705cdf6cfab0dc1cf98660e51 100644
--- a/AVQt/filter/private/EncoderVAAPI_p.h
+++ b/AVQt/filter/private/EncoderVAAPI_p.h
@@ -11,6 +11,12 @@
 
 namespace AVQt {
     class EncoderVAAPIPrivate {
+    public:
+        EncoderVAAPIPrivate(const EncoderVAAPIPrivate &) = delete;
+
+        void operator=(const EncoderVAAPIPrivate &) = delete;
+
+    private:
         explicit EncoderVAAPIPrivate(EncoderVAAPI *q) : q_ptr(q) {};
 
         EncoderVAAPI *q_ptr;
@@ -23,11 +29,11 @@ namespace AVQt {
         AVBufferRef *m_pDeviceCtx{nullptr}, *m_pFramesCtx{nullptr};
         AVFrame *m_pHWFrame{nullptr};
 
-        QMutex m_inputQueueMutex;
-        QQueue<QPair<AVFrame *, int64_t>> m_inputQueue;
+        QMutex m_inputQueueMutex{};
+        QQueue<QPair<AVFrame *, int64_t>> m_inputQueue{};
 
-        QMutex m_cbListMutex;
-        QList<IPacketSink *> m_cbList;
+        QMutex m_cbListMutex{};
+        QList<IPacketSink *> m_cbList{};
 
         std::atomic_bool m_running{false}, m_paused{false}, m_firstFrame{true};
 
diff --git a/AVQt/input/Demuxer.cpp b/AVQt/input/Demuxer.cpp
index a4fc9030b7141c2a48661b3f524ef5120e970f06..881e8063644e53536e332749a123499cd84af6dd 100644
--- a/AVQt/input/Demuxer.cpp
+++ b/AVQt/input/Demuxer.cpp
@@ -34,7 +34,7 @@ namespace AVQt {
         return d->m_paused.load();
     }
 
-    qsizetype Demuxer::registerCallback(IPacketSink *packetSink, uint8_t type) {
+    qsizetype Demuxer::registerCallback(IPacketSink *packetSink, int8_t type) {
         Q_D(AVQt::Demuxer);
 
         QMutexLocker lock(&d->m_cbMutex);
@@ -59,8 +59,9 @@ namespace AVQt {
                 sParams = avcodec_parameters_alloc();
                 avcodec_parameters_copy(sParams, d->m_pFormatCtx->streams[d->m_subtitleStream]->codecpar);
             }
-            packetSink->init(this, d->m_pFormatCtx->streams[d->m_videoStream]->avg_frame_rate, AVRational(),
-                             d->m_pFormatCtx->duration * 1000.0 / AV_TIME_BASE, vParams, aParams, sParams);
+            packetSink->init(this, d->m_pFormatCtx->streams[d->m_videoStream]->avg_frame_rate, av_make_q(1, AV_TIME_BASE),
+                             static_cast<int64_t>(static_cast<double>(d->m_pFormatCtx->duration) * 1000.0 / AV_TIME_BASE), vParams, aParams,
+                             sParams);
             if (vParams) {
                 avcodec_parameters_free(&vParams);
             }
@@ -118,7 +119,7 @@ namespace AVQt {
             avformat_find_stream_info(d->m_pFormatCtx, nullptr);
 //            }
 
-            for (size_t si = 0; si < d->m_pFormatCtx->nb_streams; ++si) {
+            for (int64_t si = 0; si < d->m_pFormatCtx->nb_streams; ++si) {
                 switch (d->m_pFormatCtx->streams[si]->codecpar->codec_type) {
                     case AVMEDIA_TYPE_VIDEO:
                         d->m_videoStreams.append(si);
@@ -163,17 +164,20 @@ namespace AVQt {
             if (vParams) {
                 cb->init(this, d->m_pFormatCtx->streams[d->m_videoStream]->avg_frame_rate,
                          d->m_pFormatCtx->streams[d->m_videoStream]->time_base,
-                         d->m_pFormatCtx->duration * 1000.0 / AV_TIME_BASE, vParams, nullptr, nullptr);
+                         static_cast<int64_t>(static_cast<double>(d->m_pFormatCtx->duration) * 1000.0 / AV_TIME_BASE), vParams, nullptr,
+                         nullptr);
             }
             if (aParams) {
                 cb->init(this, d->m_pFormatCtx->streams[d->m_audioStream]->avg_frame_rate,
                          d->m_pFormatCtx->streams[d->m_audioStream]->time_base,
-                         d->m_pFormatCtx->duration * 1000.0 / AV_TIME_BASE, nullptr, aParams, nullptr);
+                         static_cast<int64_t>(static_cast<double>(d->m_pFormatCtx->duration) * 1000.0 / AV_TIME_BASE), nullptr, aParams,
+                         nullptr);
             }
             if (sParams) {
                 cb->init(this, d->m_pFormatCtx->streams[d->m_subtitleStream]->avg_frame_rate,
                          d->m_pFormatCtx->streams[d->m_subtitleStream]->time_base,
-                         d->m_pFormatCtx->duration * 1000.0 / AV_TIME_BASE, nullptr, nullptr, sParams);
+                         static_cast<int64_t>(static_cast<double>(d->m_pFormatCtx->duration) * 1000.0 / AV_TIME_BASE), nullptr, nullptr,
+                         sParams);
             }
             if (vParams) {
                 avcodec_parameters_free(&vParams);
@@ -300,9 +304,12 @@ namespace AVQt {
                     aP = QString("%1").arg(audioPackets, 12).toLocal8Bit();
                     vP = QString("%1").arg(videoPackets, 12).toLocal8Bit();
                     sP = QString("%1").arg(sttPackets, 12).toLocal8Bit();
-                    aR = QString("%1").arg((audioPackets * 1.0 / packetCount) * 100.0, 10).toLocal8Bit();
-                    vR = QString("%1").arg((videoPackets * 1.0 / packetCount) * 100.0, 10).toLocal8Bit();
-                    sR = QString("%1").arg((sttPackets * 1.0 / packetCount) * 100.0, 10).toLocal8Bit();
+                    aR = QString("%1").arg((static_cast<double>(audioPackets) * 1.0 / static_cast<double>(packetCount)) * 100.0,
+                                           10).toLocal8Bit();
+                    vR = QString("%1").arg((static_cast<double>(videoPackets) * 1.0 / static_cast<double>(packetCount)) * 100.0,
+                                           10).toLocal8Bit();
+                    sR = QString("%1").arg((static_cast<double>(sttPackets) * 1.0 / static_cast<double>(packetCount)) * 100.0,
+                                           10).toLocal8Bit();
 
                     qDebug() << "Packet statistics";
                     qDebug() << "| Packet type | Packet count |   Percentage |";
@@ -318,19 +325,9 @@ namespace AVQt {
         }
     }
 
-    Demuxer::Demuxer(Demuxer &&other) {
-        d_ptr = other.d_ptr;
-        d_ptr->q_ptr = this;
+    Demuxer::Demuxer(Demuxer &&other) noexcept: d_ptr(other.d_ptr) {
         other.d_ptr = nullptr;
-    }
-
-    Demuxer &Demuxer::operator=(Demuxer &&other) noexcept {
-        delete d_ptr;
-        d_ptr = other.d_ptr;
         d_ptr->q_ptr = this;
-        other.d_ptr = nullptr;
-
-        return *this;
     }
 
     int DemuxerPrivate::readFromIO(void *opaque, uint8_t *buf, int bufSize) {
@@ -340,7 +337,7 @@ namespace AVQt {
         if (bytesRead == 0) {
             return AVERROR_EOF;
         } else {
-            return bytesRead;
+            return static_cast<int>(bytesRead);
         }
     }
 
diff --git a/AVQt/input/Demuxer.h b/AVQt/input/Demuxer.h
index 9ab24afa9987055adbf73ea7dc81b2b9df7e9351..2c66a39f53239c90cde299b4e7d3c6f854eb06b8 100644
--- a/AVQt/input/Demuxer.h
+++ b/AVQt/input/Demuxer.h
@@ -20,11 +20,13 @@ namespace AVQt {
         Q_DECLARE_PRIVATE(AVQt::Demuxer)
 
     public:
-        [[maybe_unused]] explicit Demuxer(QIODevice *inputDevice, QObject *parent = nullptr);
+        explicit Demuxer(QIODevice *inputDevice, QObject *parent = nullptr);
 
         explicit Demuxer(Demuxer &other) = delete;
 
-        explicit Demuxer(Demuxer &&other);
+        Demuxer &operator=(const Demuxer &other) = delete;
+
+        Demuxer(Demuxer &&other) noexcept;
 
         /*!
          * \private
@@ -43,7 +45,7 @@ namespace AVQt {
          * @param type Callback type, can be linked with bitwise or to set multiple options
          * @return
          */
-        Q_INVOKABLE qsizetype registerCallback(IPacketSink *packetSink, uint8_t type) Q_DECL_OVERRIDE;
+        Q_INVOKABLE qsizetype registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE;
 
         /*!
          * \brief Removes packet callback \c packetSink from registry
@@ -52,10 +54,6 @@ namespace AVQt {
          */
         Q_INVOKABLE qsizetype unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE;
 
-        Demuxer &operator=(const Demuxer &other) = delete;
-
-        Demuxer &operator=(Demuxer &&other) noexcept;
-
     public slots:
         /*!
          * \brief Initialize packet source (e.g. open files, allocate buffers).
diff --git a/AVQt/input/IAudioSource.h b/AVQt/input/IAudioSource.h
index 76e30c1e18a3366b7fa1f7ebb817b6cff4861186..6c2137e700e3c232fbcfd8f1a7ff7cb3258b742b 100644
--- a/AVQt/input/IAudioSource.h
+++ b/AVQt/input/IAudioSource.h
@@ -18,9 +18,9 @@ namespace AVQt {
 
         virtual bool isPaused() = 0;
 
-        Q_INVOKABLE virtual int registerCallback(IAudioSink *callback) = 0;
+        Q_INVOKABLE virtual qsizetype registerCallback(IAudioSink *callback) = 0;
 
-        Q_INVOKABLE virtual int unregisterCallback(IAudioSink *callback) = 0;
+        Q_INVOKABLE virtual qsizetype unregisterCallback(IAudioSink *callback) = 0;
 
     public slots:
         Q_INVOKABLE virtual int init() = 0;
diff --git a/AVQt/input/IFrameSource.h b/AVQt/input/IFrameSource.h
index fcea49dff7b4c6bd393d2f63c29144ea89a12d8a..740bb0a45260fe1afbba9a6b8f86cb3184b4c0f9 100644
--- a/AVQt/input/IFrameSource.h
+++ b/AVQt/input/IFrameSource.h
@@ -63,14 +63,14 @@ namespace AVQt {
          * @param type Callback type, can be linked with bitwise or to set multiple options
          * @return
          */
-        Q_INVOKABLE virtual int registerCallback(IFrameSink *frameSink) = 0;
+        Q_INVOKABLE virtual qsizetype registerCallback(IFrameSink *frameSink) = 0;
 
         /*!
          * \brief Removes frame callback \c frameSink from registry
          * @param frameSink Frame sink/filter to be removed
          * @return Previous position of the item, is -1 when not in registry
          */
-        Q_INVOKABLE virtual int unregisterCallback(IFrameSink *frameSink) = 0;
+        Q_INVOKABLE virtual qsizetype unregisterCallback(IFrameSink *frameSink) = 0;
 
     public slots:
         /*!
diff --git a/AVQt/input/IPacketSource.h b/AVQt/input/IPacketSource.h
index de6ef2c1b1f09c5c842c5b85b90b97f857395f51..d40ff21fd854846f69cfd6f1ff5d2c7302e71260 100644
--- a/AVQt/input/IPacketSource.h
+++ b/AVQt/input/IPacketSource.h
@@ -57,7 +57,7 @@ namespace AVQt {
          * @param type Callback type, can be linked with bitwise or to set multiple options
          * @return
          */
-        Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, uint8_t type) = 0;
+        Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, int8_t type) = 0;
 
         /*!
          * \brief Removes packet callback \c packetSink from registry
diff --git a/AVQt/input/private/Demuxer_p.h b/AVQt/input/private/Demuxer_p.h
index ff733d2a4c22c0ffc201764bf32a0905959d4d07..aa6cc518b355539e34baecb91b801520db1bc449 100644
--- a/AVQt/input/private/Demuxer_p.h
+++ b/AVQt/input/private/Demuxer_p.h
@@ -16,6 +16,12 @@ extern "C" {
 
 namespace AVQt {
     class DemuxerPrivate {
+    public:
+        DemuxerPrivate(const DemuxerPrivate &) = delete;
+
+        void operator=(const DemuxerPrivate &) = delete;
+
+    private:
         explicit DemuxerPrivate(Demuxer *q) : q_ptr(q) {};
 
         static int readFromIO(void *opaque, uint8_t *buf, int bufSize);
@@ -24,18 +30,18 @@ namespace AVQt {
 
         Demuxer *q_ptr;
 
-        std::atomic_bool m_running {false}, m_paused {false}, m_initialized  {false};
-        QMutex m_cbMutex;
-        QMap<IPacketSink *, int8_t> m_cbMap;
+        std::atomic_bool m_running{false}, m_paused{false}, m_initialized{false};
+        QMutex m_cbMutex{};
+        QMap<IPacketSink *, int8_t> m_cbMap{};
 
-        QList<int> m_videoStreams, m_audioStreams, m_subtitleStreams;
-        int m_videoStream = -1, m_audioStream = -1, m_subtitleStream = -1;
+        QList<int64_t> m_videoStreams{}, m_audioStreams{}, m_subtitleStreams{};
+        int64_t m_videoStream{-1}, m_audioStream{-1}, m_subtitleStream{-1};
 
-        static constexpr size_t BUFFER_SIZE = 1024;
-        uint8_t *m_pBuffer {nullptr};
-        AVFormatContext *m_pFormatCtx {nullptr};
-        AVIOContext *m_pIOCtx {nullptr};
-        QIODevice *m_inputDevice {nullptr};
+        static constexpr size_t BUFFER_SIZE{1024};
+        uint8_t *m_pBuffer{nullptr};
+        AVFormatContext *m_pFormatCtx{nullptr};
+        AVIOContext *m_pIOCtx{nullptr};
+        QIODevice *m_inputDevice{nullptr};
 
         friend class Demuxer;
     };
diff --git a/AVQt/output/IPacketSink.h b/AVQt/output/IPacketSink.h
index 5e9ee3c0ee2378bf0fb7c10f6e4b76d88dbf1339..d922961aa0a66c3018223bc61e134156da4a8056 100644
--- a/AVQt/output/IPacketSink.h
+++ b/AVQt/output/IPacketSink.h
@@ -44,7 +44,7 @@ namespace AVQt {
 
         Q_INVOKABLE virtual void stop(IPacketSource *source) = 0;
 
-        Q_INVOKABLE virtual void pause(bool paused) = 0;
+        Q_INVOKABLE virtual void pause(bool p) = 0;
 
         /*!
          * \brief Callback method, is called for every registered packet type.
@@ -61,6 +61,8 @@ namespace AVQt {
         virtual void started() = 0;
 
         virtual void stopped() = 0;
+
+        virtual void paused(bool pause) = 0;
     };
 }
 
diff --git a/AVQt/output/Muxer.cpp b/AVQt/output/Muxer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cff343960136270af5688c019d4660553c55c588
--- /dev/null
+++ b/AVQt/output/Muxer.cpp
@@ -0,0 +1,252 @@
+//
+// Created by silas on 5/24/21.
+//
+
+#include <input/IPacketSource.h>
+#include "private/Muxer_p.h"
+#include "Muxer.h"
+
+namespace AVQt {
+    Muxer::Muxer(QIODevice *outputDevice, QObject *parent) : QThread(parent), d_ptr(new MuxerPrivate(this)) {
+        Q_D(AVQt::Muxer);
+        d->m_outputDevice = outputDevice;
+    }
+
+    Muxer::Muxer(AVQt::MuxerPrivate &p) : d_ptr(&p) {
+
+    }
+
+    AVQt::Muxer::Muxer(Muxer &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+    }
+
+    bool Muxer::isPaused() {
+        Q_D(AVQt::Muxer);
+        return d->m_paused.load();
+    }
+
+    void Muxer::init(IPacketSource *source, AVRational framerate, AVRational timebase, int64_t duration, AVCodecParameters *vParams,
+                     AVCodecParameters *aParams, AVCodecParameters *sParams) {
+        Q_UNUSED(framerate)
+        Q_UNUSED(duration)
+        Q_D(AVQt::Muxer);
+
+        if ((vParams && aParams) || (vParams && sParams) || (aParams && sParams)) {
+            qWarning("[AVQt::Muxer] init() called for multiple stream types at once. Ignoring call");
+            return;
+        }
+
+        if (d->m_sourceStreamMap.contains(source)) {
+            bool alreadyCalled = false;
+            for (const auto &stream: d->m_sourceStreamMap[source]) {
+                if ((vParams && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
+                    (aParams && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
+                    (sParams && stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+                    alreadyCalled = true;
+                    break;
+                }
+            }
+            if (alreadyCalled) {
+                qWarning("[AVQt::Muxer] init() called multiple times for the same stream type by the same source. Ignoring call");
+                return;
+            }
+        }
+        QMutexLocker lock(&d->m_initMutex);
+        if (!d->m_pFormatContext) {
+            if (!d->m_outputDevice->isOpen()) {
+                if (!d->m_outputDevice->open((d->m_outputDevice->isSequential() ? QIODevice::WriteOnly : QIODevice::ReadWrite))) {
+                    qFatal("[AVQt::Muxer] Could not open output device");
+                }
+            } else if (!d->m_outputDevice->isWritable()) {
+                qFatal("[AVQt::Muxer] Output device is not writable");
+            }
+            d->m_pFormatContext = avformat_alloc_context();
+            d->m_pIOBuffer = static_cast<uint8_t *>(av_malloc(MuxerPrivate::IOBUF_SIZE));
+            d->m_pIOContext = avio_alloc_context(d->m_pIOBuffer, MuxerPrivate::IOBUF_SIZE, 1, d->m_outputDevice, nullptr,
+                                                 &MuxerPrivate::writeToIO, &MuxerPrivate::seekIO);
+            d->m_pIOContext->seekable = !d->m_outputDevice->isSequential();
+            d->m_pFormatContext->pb = d->m_pIOContext;
+            d->m_pFormatContext->flags |= AVFMT_FLAG_CUSTOM_IO;
+        }
+
+        if (!d->m_sourceStreamMap.contains(source)) {
+            d->m_sourceStreamMap[source] = QList<AVStream *>();
+        }
+        if (vParams) {
+            AVStream *videoStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(vParams->codec_id));
+            videoStream->codecpar = avcodec_parameters_alloc();
+            avcodec_parameters_copy(videoStream->codecpar, vParams);
+            videoStream->time_base = timebase;
+            d->m_sourceStreamMap[source].append(videoStream);
+        } else if (aParams) {
+            AVStream *audioStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(aParams->codec_id));
+            audioStream->codecpar = avcodec_parameters_alloc();
+            avcodec_parameters_copy(audioStream->codecpar, aParams);
+            audioStream->time_base = timebase;
+            d->m_sourceStreamMap[source].append(audioStream);
+        } else if (sParams) {
+            AVStream *subtitleStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(sParams->codec_id));
+            subtitleStream->codecpar = avcodec_parameters_alloc();
+            avcodec_parameters_copy(subtitleStream->codecpar, sParams);
+            subtitleStream->time_base = timebase;
+            d->m_sourceStreamMap[source].append(subtitleStream);
+        }
+    }
+
+    void Muxer::deinit(IPacketSource *source) {
+        Q_D(AVQt::Muxer);
+
+        if (d->m_sourceStreamMap.contains(source)) {
+            d->m_sourceStreamMap.remove(source);
+        } else {
+            qWarning("[AVQt::Muxer] deinit() called without preceding init() from source. Ignoring call");
+            return;
+        }
+
+        if (d->m_sourceStreamMap.isEmpty()) {
+            QMutexLocker lock(&d->m_initMutex);
+            if (d->m_pFormatContext) {
+                if (d->m_headerWritten.load()) {
+                    av_write_trailer(d->m_pFormatContext);
+                }
+                int ret = av_interleaved_write_frame(d->m_pFormatContext, nullptr);
+                if (ret != 0) {
+                    constexpr auto strBufSize = 32;
+                    char strBuf[strBufSize];
+                    qWarning("%d: Couldn't flush AVFormatContext packet queue: %s", ret, av_make_error_string(strBuf, strBufSize, ret));
+                }
+                avio_flush(d->m_pFormatContext->pb);
+                avio_closep(&d->m_pIOContext);
+                avformat_free_context(d->m_pFormatContext);
+            }
+        }
+
+    }
+
+    void Muxer::start(IPacketSource *source) {
+        Q_UNUSED(source)
+        Q_D(AVQt::Muxer);
+
+        bool shouldBe = false;
+        if (d->m_running.compare_exchange_strong(shouldBe, true)) {
+            shouldBe = false;
+            if (d->m_headerWritten.compare_exchange_strong(shouldBe, true)) {
+                int ret = avformat_write_header(d->m_pFormatContext, nullptr);
+                if (ret != 0) {
+                    constexpr auto strBufSize = 32;
+                    char strBuf[strBufSize];
+                    qWarning("[AVQt::Muxer] %d: Couldn't init AVFormatContext: %s", ret, av_make_error_string(strBuf, strBufSize, ret));
+                }
+            }
+            d->m_paused.store(false);
+            QThread::start();
+            started();
+        }
+    }
+
+    void Muxer::stop(IPacketSource *source) {
+        Q_UNUSED(source)
+        Q_D(AVQt::Muxer);
+
+        bool shouldBe = true;
+        if (d->m_running.compare_exchange_strong(shouldBe, false)) {
+            d->m_paused.store(false);
+            QThread::wait();
+            stopped();
+        }
+    }
+
+    void Muxer::pause(bool p) {
+        Q_D(AVQt::Muxer);
+
+        bool shouldBe = !p;
+        if (d->m_paused.compare_exchange_strong(shouldBe, p)) {
+            paused(p);
+        }
+    }
+
+    void Muxer::onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) {
+        Q_D(AVQt::Muxer);
+
+        bool unknownSource = !d->m_sourceStreamMap.contains(source);
+        bool initStream = false;
+        AVStream *addStream;
+        if (!unknownSource) {
+            for (const auto &stream : d->m_sourceStreamMap[source]) {
+                if ((packetType == IPacketSource::CB_VIDEO && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
+                    (packetType == IPacketSource::CB_AUDIO && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
+                    (packetType == IPacketSource::CB_SUBTITLE && stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+                    addStream = stream;
+                    initStream = true;
+                    break;
+                }
+            }
+        }
+        if (unknownSource || !initStream) {
+            qWarning("[AVQt::Muxer] onPacket() called without preceding call to init() for stream type. Ignoring packet");
+            return;
+        }
+
+        QPair<AVPacket *, AVStream *> queuePacket{av_packet_clone(packet), addStream};
+        queuePacket.first->stream_index = addStream->index;
+
+        QMutexLocker lock(&d->m_inputQueueMutex);
+        d->m_inputQueue.enqueue(queuePacket);
+    }
+
+    void Muxer::run() {
+        Q_D(AVQt::Muxer);
+
+        while (d->m_running.load()) {
+            if (!d->m_paused.load()) {
+                QPair<AVPacket *, AVStream *> packet;
+                {
+                    QMutexLocker lock(&d->m_inputQueueMutex);
+                    packet = d->m_inputQueue.dequeue();
+                }
+                int ret = av_interleaved_write_frame(d->m_pFormatContext, packet.first);
+                if (ret != 0) {
+                    constexpr auto strBufSize = 32;
+                    char strBuf[strBufSize];
+                    qWarning("%d: Couldn't write packet to AVFormatContext: %s", ret, av_make_error_string(strBuf, strBufSize, ret));
+                }
+            } else {
+                msleep(4);
+            }
+        }
+    }
+
+    int MuxerPrivate::writeToIO(void *opaque, uint8_t *buf, int buf_size) {
+        auto *outputDevice = reinterpret_cast<QIODevice *>(opaque);
+
+        auto bytesWritten = outputDevice->write(reinterpret_cast<const char *>(buf), buf_size);
+        return bytesWritten == 0 ? AVERROR_UNKNOWN : static_cast<int>(bytesWritten);
+    }
+
+    int64_t MuxerPrivate::seekIO(void *opaque, int64_t offset, int whence) {
+        auto *outputDevice = reinterpret_cast<QIODevice *>(opaque);
+
+        if (outputDevice->isSequential()) {
+            return AVERROR_UNKNOWN;
+        }
+
+        bool result;
+        switch (whence) {
+            case SEEK_SET:
+                result = outputDevice->seek(offset);
+                break;
+            case SEEK_CUR:
+                result = outputDevice->seek(outputDevice->pos() + offset);
+                break;
+            case SEEK_END:
+                result = outputDevice->seek(outputDevice->size() - offset);
+                break;
+            case AVSEEK_SIZE:
+                return outputDevice->size();
+            default:
+                return AVERROR_UNKNOWN;
+        }
+
+        return result ? outputDevice->pos() : AVERROR_UNKNOWN;
+    }
+}
\ No newline at end of file
diff --git a/AVQt/output/Muxer.h b/AVQt/output/Muxer.h
new file mode 100644
index 0000000000000000000000000000000000000000..f774631aa3505a4c3017aa18bc23af03b1cc6256
--- /dev/null
+++ b/AVQt/output/Muxer.h
@@ -0,0 +1,63 @@
+//
+// Created by silas on 5/24/21.
+//
+
+#include "IPacketSink.h"
+
+#include <QThread>
+
+#ifndef LIBAVQT_MUXER_H
+#define LIBAVQT_MUXER_H
+
+namespace AVQt {
+    class MuxerPrivate;
+
+    class Muxer : public QThread, public IPacketSink {
+    Q_OBJECT
+        Q_INTERFACES(AVQt::IPacketSink)
+
+        Q_DECLARE_PRIVATE(AVQt::Muxer)
+
+    protected:
+        void run() Q_DECL_OVERRIDE;
+
+    public:
+        explicit Muxer(QIODevice *outputDevice, QObject *parent = nullptr);
+
+        Muxer(Muxer &) = delete;
+
+        Muxer(Muxer &&other) noexcept;
+
+        bool isPaused() Q_DECL_OVERRIDE;
+
+        void init(IPacketSource *source, AVRational framerate, AVRational timebase, int64_t duration, AVCodecParameters *vParams,
+                  AVCodecParameters *aParams, AVCodecParameters *sParams) Q_DECL_OVERRIDE;
+
+        void deinit(IPacketSource *source) Q_DECL_OVERRIDE;
+
+        void start(IPacketSource *source) Q_DECL_OVERRIDE;
+
+        void stop(IPacketSource *source) Q_DECL_OVERRIDE;
+
+        void pause(bool p) Q_DECL_OVERRIDE;
+
+        void onPacket(IPacketSource *source, AVPacket *packet, int8_t packetType) Q_DECL_OVERRIDE;
+
+        void operator=(const Muxer &) = delete;
+
+    signals:
+
+        void started() Q_DECL_OVERRIDE;
+
+        void stopped() Q_DECL_OVERRIDE;
+
+        void paused(bool pause) Q_DECL_OVERRIDE;
+
+    protected:
+        [[maybe_unused]] explicit Muxer(MuxerPrivate &p);
+
+        MuxerPrivate *d_ptr;
+    };
+}
+
+#endif //LIBAVQT_MUXER_H
\ No newline at end of file
diff --git a/AVQt/output/OpenALAudioOutput.cpp b/AVQt/output/OpenALAudioOutput.cpp
index 93afef3b12b3258921e92867470fb8fa61343055..66306e41a0b7c26ca88e4526b922b5546be02f13 100644
--- a/AVQt/output/OpenALAudioOutput.cpp
+++ b/AVQt/output/OpenALAudioOutput.cpp
@@ -8,9 +8,6 @@
 #include "filter/private/OpenALErrorHandler.h"
 #include "OpenGLRenderer.h"
 
-#include <QtCore>
-#include <QtConcurrent>
-
 namespace AVQt {
     OpenALAudioOutput::OpenALAudioOutput(QObject *parent) : QThread(parent), d_ptr(new OpenALAudioOutputPrivate(this)) {
         Q_D(AVQt::OpenALAudioOutput);
@@ -18,8 +15,11 @@ namespace AVQt {
     }
 
     [[maybe_unused]] OpenALAudioOutput::OpenALAudioOutput(OpenALAudioOutputPrivate &p) : d_ptr(&p) {
-        Q_D(AVQt::OpenALAudioOutput);
+    }
 
+    OpenALAudioOutput::OpenALAudioOutput(OpenALAudioOutput &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
     }
 
     int OpenALAudioOutput::init(IAudioSource *source, int64_t duration, int sampleRate) {
@@ -54,7 +54,7 @@ namespace AVQt {
             qFatal("Could not make ALC context current");
         }
 
-        d->m_ALBufferCount = static_cast<int>(std::ceil((1000 * 1.0 / 60) * static_cast<double>(d->m_sampleRate / 1536)));
+        d->m_ALBufferCount = static_cast<int>(std::ceil((1000 * 1.0 / 60) * (static_cast<double>(d->m_sampleRate) / 1536.0)));
         qDebug("Using %d OpenAL buffers", d->m_ALBufferCount);
 
         d->m_ALBuffers.resize(d->m_ALBufferCount);
@@ -62,10 +62,10 @@ namespace AVQt {
         alCall(alGenBuffers, d->m_ALBufferCount, d->m_ALBuffers.data());
 
         alCall(alGenSources, 1, &d->m_ALSource);
-        alCall(alSourcef, d->m_ALSource, AL_PITCH, 1);
+        alCall(alSourcef, d->m_ALSource, AL_PITCH, 1.0f);
         alCall(alSourcef, d->m_ALSource, AL_GAIN, 1.0f);
-        alCall(alSource3f, d->m_ALSource, AL_POSITION, 0, 0, 0);
-        alCall(alSource3f, d->m_ALSource, AL_VELOCITY, 0, 0, 0);
+        alCall(alSource3f, d->m_ALSource, AL_POSITION, 0.f, 0.f, 0.f);
+        alCall(alSource3f, d->m_ALSource, AL_VELOCITY, 0.f, 0.f, 0.f);
         alCall(alSourcei, d->m_ALSource, AL_LOOPING, AL_FALSE);
         alCall(alSourcei, d->m_ALSource, AL_BUFFER, 0);
 
@@ -244,8 +244,10 @@ namespace AVQt {
         {
             QMutexLocker lock(&d->m_swrContextMutex);
             if (!d->m_pSwrContext && frame->format != AV_SAMPLE_FMT_S16) {
-                d->m_pSwrContext = swr_alloc_set_opts(nullptr, frame->channel_layout, AV_SAMPLE_FMT_S16, frame->sample_rate,
-                                                      frame->channel_layout, static_cast<AVSampleFormat>(frame->format), frame->sample_rate,
+                d->m_pSwrContext = swr_alloc_set_opts(nullptr, static_cast<int64_t>(frame->channel_layout), AV_SAMPLE_FMT_S16,
+                                                      frame->sample_rate,
+                                                      static_cast<int64_t>(frame->channel_layout),
+                                                      static_cast<AVSampleFormat>(frame->format), frame->sample_rate,
                                                       0, nullptr);
                 swr_init(d->m_pSwrContext);
             }
@@ -307,16 +309,17 @@ namespace AVQt {
 
             d->m_clock.store(renderer->getClock());
             clockIntervalChanged(d->m_clock.load()->getInterval());
-            int newBufferCount = static_cast<int>(std::ceil((1000 * 1.0 / static_cast<double>(d->m_clockInterval) * static_cast<double>(d->m_sampleRate) / 1536)));
+            int newBufferCount = static_cast<int>(std::ceil(
+                    (1000 * 1.0 / static_cast<double>(d->m_clockInterval) * static_cast<double>(d->m_sampleRate) / 1536)));
             if (d->m_ALBuffers.size() != newBufferCount) {
                 ALCboolean contextCurrent = ALC_FALSE;
                 alcCall(alcMakeContextCurrent, contextCurrent, d->m_ALCDevice, d->m_ALCContext);
                 if (d->m_ALBuffers.size() > newBufferCount) {
-                    auto overhead = d->m_ALBuffers.size() - newBufferCount;
+                    int overhead = static_cast<int>(d->m_ALBuffers.size() - newBufferCount);
                     alCall(alDeleteBuffers, overhead, d->m_ALBuffers.data() + d->m_ALBuffers.size() - overhead);
                     d->m_ALBuffers.resize(newBufferCount);
                 } else if (d->m_ALBuffers.size() < newBufferCount) {
-                    auto extraBuffers = newBufferCount - d->m_ALBuffers.size();
+                    int extraBuffers = static_cast<int>(newBufferCount - d->m_ALBuffers.size());
                     d->m_ALBuffers.resize(newBufferCount);
                     alCall(alGenBuffers, extraBuffers, d->m_ALBuffers.data() + d->m_ALBuffers.size() - extraBuffers);
                 }
@@ -369,24 +372,28 @@ namespace AVQt {
             }
             if (!d->m_ALBufferQueue.isEmpty()) {
                 QMutexLocker lock3(&d->m_ALBufferQueueMutex);
-                alCall(alSourceQueueBuffers, d->m_ALSource, std::min(d->m_ALBufferQueue.size(), static_cast<typeof (d->m_ALBufferQueue.size())>(4)), d->m_ALBufferQueue.toVector().data());
-                for (const auto &buf: QList(d->m_ALBufferQueue.end() - std::min(d->m_ALBufferQueue.size(), static_cast<typeof (d->m_ALBufferQueue.size())>(4)), d->m_ALBufferQueue.end())) {
+                alCall(alSourceQueueBuffers, d->m_ALSource, static_cast<int>(qMin(d->m_ALBufferQueue.size(), 4)),
+                       d->m_ALBufferQueue.toVector().data());
+                for (const auto &buf: QList(d->m_ALBufferQueue.end() - static_cast<int>(qMin(d->m_ALBufferQueue.size(), 4)),
+                                            d->m_ALBufferQueue.end())) {
                     d->m_queuedSamples += d->m_ALBufferSampleMap[buf];
                 }
                 if (d->m_ALBufferQueue.size() < 4) {
-                    alCall(alSourceQueueBuffers, d->m_ALSource, std::min(buffers.size(), 4 - d->m_ALBufferQueue.size()), buffers.data());
-                    for (qint64 i = buffers.size() - std::min(buffers.size(), 4 - d->m_ALBufferQueue.size()); i < buffers.size(); ++i) {
+                    alCall(alSourceQueueBuffers, d->m_ALSource, static_cast<int>(qMin(buffers.size(), 4 - d->m_ALBufferQueue.size())),
+                           buffers.data());
+                    for (qint64 i = static_cast<int>(buffers.size() - qMin(buffers.size(), 4 - d->m_ALBufferQueue.size()));
+                         i < buffers.size(); ++i) {
                         d->m_queuedSamples += d->m_ALBufferSampleMap[buffers[i]];
                     }
-                    buffers.remove(buffers.size() - std::min(buffers.size(), 4 - d->m_ALBufferQueue.size()),
-                                   std::min(buffers.size(), 4 - d->m_ALBufferQueue.size()));
+                    buffers.remove(buffers.size() - qMin(buffers.size(), 4 - d->m_ALBufferQueue.size()),
+                                   qMin(buffers.size(), 4 - d->m_ALBufferQueue.size()));
                     d->m_ALBufferQueue.append(buffers.toList());
                 }
                 d->m_ALBufferQueue.clear();
             } else {
                 QMutexLocker lock3(&d->m_ALBufferQueueMutex);
-                alCall(alSourceQueueBuffers, d->m_ALSource, std::min(buffers.size(), static_cast<typeof (d->m_ALBufferQueue.size())>(4)), buffers.data());
-                buffers.remove(buffers.size() - std::min(buffers.size(), static_cast<typeof (d->m_ALBufferQueue.size())>(4)), std::min(buffers.size(), static_cast<typeof (d->m_ALBufferQueue.size())>(4)));
+                alCall(alSourceQueueBuffers, d->m_ALSource, static_cast<int>(qMin(buffers.size(), 4)), buffers.data());
+                buffers.remove(buffers.size() - qMin(buffers.size(), 4), qMin(buffers.size(), 4));
                 d->m_ALBufferQueue.append(buffers.toList());
             }
         } else {
@@ -461,7 +468,8 @@ namespace AVQt {
                 }
                 while (!d->m_inputQueue.isEmpty() &&
                        !d->m_ALBufferQueue.isEmpty()) {
-                    if (d->m_queuedSamples * 1.0 / d->m_inputQueue.front().first->sample_rate < d->m_clockInterval * 1.5) {
+                    if (static_cast<double>(d->m_queuedSamples) * 1.0 / d->m_inputQueue.front().first->sample_rate <
+                        static_cast<double>(d->m_clockInterval) * 1.5) {
                         lock.relock();
                         QMutexLocker lock1(&d->m_inputQueueMutex);
                         QMutexLocker lock2(&d->m_ALBufferSampleMapMutex);
@@ -482,7 +490,7 @@ namespace AVQt {
 //                    } else {
                         frame = d->m_inputQueue.dequeue();
 //                    }
-                        duration += frame.first->nb_samples * 1000.0 / frame.first->sample_rate;
+                        duration += static_cast<int64_t>(std::round(frame.first->nb_samples * 1000.0 / frame.first->sample_rate));
                         lock1.unlock();
                         auto buf = d->m_ALBufferQueue.dequeue();
                         lock.unlock();
diff --git a/AVQt/output/OpenALAudioOutput.h b/AVQt/output/OpenALAudioOutput.h
index 476bcf076196d722070f2b05d96f04f3482e2593..2e05a19dbfce87d2e65f7b3e9e1626adfafc9afd 100644
--- a/AVQt/output/OpenALAudioOutput.h
+++ b/AVQt/output/OpenALAudioOutput.h
@@ -24,6 +24,12 @@ namespace AVQt {
     public:
         explicit OpenALAudioOutput(QObject *parent = nullptr);
 
+        OpenALAudioOutput(OpenALAudioOutput &&other) noexcept;
+
+        OpenALAudioOutput(const OpenALAudioOutput &) = delete;
+
+        void operator=(const OpenALAudioOutput &) = delete;
+
         Q_INVOKABLE bool isPaused() Q_DECL_OVERRIDE;
 
         void run() Q_DECL_OVERRIDE;
@@ -66,4 +72,4 @@ namespace AVQt {
 }
 
 
-#endif //LIBAVQT_OPENALAUDIOOUTPUT_H
+#endif //LIBAVQT_OPENALAUDIOOUTPUT_H
\ No newline at end of file
diff --git a/AVQt/output/OpenGLRenderer.cpp b/AVQt/output/OpenGLRenderer.cpp
index 1a696ba9f72d46779734620cd1ea6eaad4e46d88..b1e9c2cc784c5bab54b281fac179a8e47d8392f7 100644
--- a/AVQt/output/OpenGLRenderer.cpp
+++ b/AVQt/output/OpenGLRenderer.cpp
@@ -6,7 +6,6 @@
 #include "OpenGLRenderer.h"
 
 #include <QtGui>
-#include <iostream>
 
 extern "C" {
 #include <libavutil/frame.h>
@@ -27,6 +26,11 @@ namespace AVQt {
     [[maybe_unused]] [[maybe_unused]] OpenGLRenderer::OpenGLRenderer(OpenGLRendererPrivate &p) : d_ptr(&p) {
     }
 
+    OpenGLRenderer::OpenGLRenderer(OpenGLRenderer &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
+
     OpenGLRenderer::~OpenGLRenderer() noexcept {
         Q_D(AVQt::OpenGLRenderer);
 
@@ -37,14 +41,9 @@ namespace AVQt {
         Q_UNUSED(framerate) // Don't use framerate, because it is not always specified in stream information
         Q_UNUSED(source)
         Q_D(AVQt::OpenGLRenderer);
-        int64_t h = duration / 3600000;
-        int64_t m = (duration - h * 3600000) / 60000;
-        int64_t s = (duration - h * 3600000 - m * 60000) / 1000;
-        int64_t ms = duration - h * 3600000 - m * 60000 - s * 1000;
 
-        d->m_duration = QTime(static_cast<int>(h), static_cast<int>(m), static_cast<int>(s), static_cast<int>(ms));
-        d->m_position = QTime(0, 0, 0, 0);
-        qDebug() << "Duration:" << d->m_duration.toString("hh:mm:ss");
+        d->m_duration = OpenGLRendererPrivate::timeFromMillis(duration);
+        qDebug() << "Duration:" << d->m_duration.toString("hh:mm:ss.zzz");
 
         d->m_clock = new RenderClock;
         d->m_clock->setInterval(16);
@@ -104,20 +103,18 @@ namespace AVQt {
             d->m_vbo.destroy();
             d->m_vao.destroy();
 
-            if (d->m_yTexture) {
 //                d->m_yTexture->destroy();
-                delete d->m_yTexture;
-            }
+            delete d->m_yTexture;
+
 
-            if (d->m_uTexture) {
 //                d->m_uTexture->destroy();
-                delete d->m_uTexture;
-            }
+            delete d->m_uTexture;
+
+
 
-            if (d->m_vTexture) {
 //                d->m_yTexture->destroy();
-                delete d->m_vTexture;
-            }
+            delete d->m_vTexture;
+
 
             stopped();
             return 0;
@@ -510,7 +507,12 @@ namespace AVQt {
 
 //            qDebug() << "Current timestamp:" << d->m_position.toString("hh:mm:ss.zzz");
 
-        QString overlay(d->m_position.toString("hh:mm:ss") + "/" + d->m_duration.toString("hh:mm:ss"));
+        QTime position{0, 0, 0, 0};
+        if (d->m_currentFrame) {
+            position = OpenGLRendererPrivate::timeFromMillis(d->m_currentFrame->pts / 1000);
+        }
+
+        QString overlay(position.toString("hh:mm:ss.zzz") + "/" + d->m_duration.toString("hh:mm:ss.zzz"));
         QFontMetrics fm(roboto);
         p.fillRect(fm.boundingRect(overlay).translated(static_cast<int>(textPosX), static_cast<int>(textPosY)).adjusted(-5, -5, 5, 5),
                    QColor(0xFF, 0xFF, 0xFF, 0x48));
@@ -528,14 +530,6 @@ namespace AVQt {
         }
     }
 
-    void OpenGLRenderer::triggerUpdate(qint64 timestamp) {
-        Q_UNUSED(timestamp)
-        Q_D(AVQt::OpenGLRenderer);
-
-//        d->m_updateRequired.store(true);
-//        d->m_updateTimestamp.store(timestamp);
-    }
-
     RenderClock *OpenGLRenderer::getClock() {
         Q_D(AVQt::OpenGLRenderer);
         return d->m_clock;
@@ -552,7 +546,7 @@ namespace AVQt {
         transformPoint(out, model, in);
         transformPoint(in, proj, out);
 
-        if (in[3] == 0.0)
+        if (in[3] < 0.0001)
             return GL_FALSE;
 
         in[0] /= in[3];
@@ -575,4 +569,12 @@ namespace AVQt {
 #undef M
     }
 
+    QTime OpenGLRendererPrivate::timeFromMillis(int64_t ts) {
+        int ms = static_cast<int>(ts % 1000);
+        int s = static_cast<int>((ts / 1000) % 60);
+        int m = static_cast<int>((ts / 1000 / 60) % 60);
+        int h = static_cast<int>(ts / 1000 / 60 / 60);
+        return QTime(h, m, s, ms);
+    }
+
 }
\ No newline at end of file
diff --git a/AVQt/output/OpenGLRenderer.h b/AVQt/output/OpenGLRenderer.h
index 96216b70d6e902930edc78c59b1ddee910841f8e..a872577af3fb93025e832149b43dc68b52218841 100644
--- a/AVQt/output/OpenGLRenderer.h
+++ b/AVQt/output/OpenGLRenderer.h
@@ -29,6 +29,12 @@ namespace AVQt {
     public:
         explicit OpenGLRenderer(QWindow *parent = nullptr);
 
+        OpenGLRenderer(OpenGLRenderer &&other) noexcept;
+
+        OpenGLRenderer(const OpenGLRenderer &) = delete;
+
+        void operator=(const OpenGLRenderer &) = delete;
+
         ~OpenGLRenderer() noexcept;
 
         bool isPaused() Q_DECL_OVERRIDE;
@@ -88,11 +94,6 @@ namespace AVQt {
          */
         Q_INVOKABLE void onFrame(IFrameSource *source, AVFrame *frame, int64_t frameDuration) Q_DECL_OVERRIDE;
 
-        /*!
-         * \private
-         */
-        void triggerUpdate(qint64 timestamp);
-
     signals:
 
         void started() Q_DECL_OVERRIDE;
@@ -115,4 +116,4 @@ namespace AVQt {
 }
 
 
-#endif //LIBAVQT_OPENGLRENDERER_H
+#endif //LIBAVQT_OPENGLRENDERER_H
\ No newline at end of file
diff --git a/AVQt/output/RenderClock.cpp b/AVQt/output/RenderClock.cpp
index 723b01d6e8a30b26537ea60df2ca9ce2fe8158fe..2d19d3edea4d93af669e2a22dff2158f7e8a7e06 100644
--- a/AVQt/output/RenderClock.cpp
+++ b/AVQt/output/RenderClock.cpp
@@ -24,6 +24,11 @@ namespace AVQt {
         connect(d->m_timer, &QTimer::timeout, this, &RenderClock::timerTimeout);
     }
 
+    RenderClock::RenderClock(RenderClock &&other) noexcept: d_ptr(other.d_ptr) {
+        other.d_ptr = nullptr;
+        d_ptr->q_ptr = this;
+    }
+
     RenderClock::~RenderClock() {
         Q_D(AVQt::RenderClock);
 
@@ -78,13 +83,13 @@ namespace AVQt {
         }
     }
 
-    void RenderClock::setInterval(int64_t interval) {
+    void RenderClock::setInterval(int interval) {
         Q_D(AVQt::RenderClock);
 
-        if (interval > 0 && interval != d->m_interval.load()) {
+        if (interval > 0 && interval != d->m_interval) {
             d->m_interval.store(interval);
 
-            d->m_timer->setInterval(d->m_interval.load());
+            d->m_timer->setInterval(d->m_interval);
             d->m_timer->stop();
             d->m_timer->start();
 
diff --git a/AVQt/output/RenderClock.h b/AVQt/output/RenderClock.h
index 6e1ee39d1ddda44555ea7db5519717fc26aa0c7f..3cb95b65c0d25fa3348e511ad2a1e134365b9360 100644
--- a/AVQt/output/RenderClock.h
+++ b/AVQt/output/RenderClock.h
@@ -18,9 +18,15 @@ namespace AVQt {
     public:
         explicit RenderClock(QObject *parent = nullptr);
 
+        RenderClock(RenderClock &&other) noexcept;
+
+        RenderClock(const RenderClock &) = delete;
+
+        void operator=(const RenderClock &) = delete;
+
         ~RenderClock();
 
-        void setInterval(int64_t interval);
+        void setInterval(int interval);
 
         int64_t getInterval();
 
@@ -55,6 +61,7 @@ namespace AVQt {
         RenderClockPrivate *d_ptr;
 
     private slots:
+
         void timerTimeout();
 
     };
diff --git a/AVQt/output/private/Muxer_p.h b/AVQt/output/private/Muxer_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b0fa50e776d45afcf836ab1f1f58fb10414b188
--- /dev/null
+++ b/AVQt/output/private/Muxer_p.h
@@ -0,0 +1,53 @@
+//
+// Created by silas on 5/24/21.
+//
+
+#include "../Muxer.h"
+
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libavcodec/packet.h>
+}
+
+#include <QtCore>
+
+#ifndef LIBAVQT_MUXER_P_H
+#define LIBAVQT_MUXER_P_H
+
+namespace AVQt {
+    class MuxerPrivate {
+    public:
+        MuxerPrivate(const MuxerPrivate &) = delete;
+
+        void operator=(const MuxerPrivate &) = delete;
+
+    private:
+        explicit MuxerPrivate(Muxer *q) : q_ptr(q) {};
+
+        Muxer *q_ptr;
+
+        QIODevice *m_outputDevice{nullptr};
+
+        QMutex m_initMutex{};
+        static constexpr size_t IOBUF_SIZE{4 * 1024};  // 4 KB
+        uint8_t *m_pIOBuffer{nullptr};
+        AVIOContext *m_pIOContext{nullptr};
+        AVFormatContext *m_pFormatContext{nullptr};
+        QMap<IPacketSource *, QList<AVStream *>> m_sourceStreamMap{};
+
+        QMutex m_inputQueueMutex{};
+        QQueue<QPair<AVPacket *, AVStream *>> m_inputQueue{};
+
+        std::atomic_bool m_running{false};
+        std::atomic_bool m_paused{false};
+        std::atomic_bool m_headerWritten{false};
+
+        friend class Muxer;
+
+        static int64_t seekIO(void *opaque, int64_t offset, int whence);
+
+        static int writeToIO(void *opaque, uint8_t *buf, int buf_size);
+    };
+}
+
+#endif //LIBAVQT_MUXER_P_H
\ No newline at end of file
diff --git a/AVQt/output/private/OpenALAudioOutput_p.h b/AVQt/output/private/OpenALAudioOutput_p.h
index 04b678b8fdd56cff826e5571793fa7cbf9480a8b..c9330cc3f612f87cec1604f446b2f19db0c5cd70 100644
--- a/AVQt/output/private/OpenALAudioOutput_p.h
+++ b/AVQt/output/private/OpenALAudioOutput_p.h
@@ -22,43 +22,49 @@ namespace AVQt {
     class OpenALAudioOutput;
 
     class OpenALAudioOutputPrivate {
+    public:
+        OpenALAudioOutputPrivate(const OpenALAudioOutputPrivate &) = delete;
+
+        void operator=(const OpenALAudioOutputPrivate &) = delete;
+
+    private:
         explicit OpenALAudioOutputPrivate(OpenALAudioOutput *q) : q_ptr(q) {};
 
-        [[maybe_unused]] OpenALAudioOutput *q_ptr;
+        OpenALAudioOutput *q_ptr;
 
-        QMutex m_inputQueueMutex;
-        QQueue<QPair<AVFrame *, int64_t>> m_inputQueue;
+        QMutex m_inputQueueMutex{};
+        QQueue<QPair<AVFrame *, int64_t>> m_inputQueue{};
 //        AVFrame *m_partialFrame {nullptr};
 //        size_t m_partialFrameOffset {0};
-        QMutex m_outputQueueMutex;
-        QQueue<QPair<AVFrame *, int64_t>> m_outputQueue;
-        std::atomic_bool m_outputSliceDurationChanged  {false};
-        int64_t m_duration = 0, m_clockInterval = 0, m_sampleRate {0};
-
-        std::atomic<RenderClock *> m_clock {nullptr};
-
-        QMutex m_swrContextMutex;
-        SwrContext *m_pSwrContext {nullptr};
-
-        int m_ALBufferCount = 5;
-        std::atomic_size_t m_playingBuffers {0};
-        QVector<ALuint> m_ALBuffers;
-        QRecursiveMutex m_ALBufferQueueMutex;
-        QQueue<ALuint> m_ALBufferQueue;
-        QRecursiveMutex m_ALBufferSampleMapMutex;
-        QMap<ALuint, int64_t> m_ALBufferSampleMap;
-        int64_t m_queuedSamples {0};
-        ALCdevice *m_ALCDevice {nullptr};
-        ALCcontext *m_ALCContext {nullptr};
-
-        ALuint m_ALSource {0};
+        QMutex m_outputQueueMutex{};
+        QQueue<QPair<AVFrame *, int64_t>> m_outputQueue{};
+        std::atomic_bool m_outputSliceDurationChanged{false};
+        int64_t m_duration{0}, m_clockInterval{0}, m_sampleRate{0};
+
+        std::atomic<RenderClock *> m_clock{nullptr};
+
+        QMutex m_swrContextMutex{};
+        SwrContext *m_pSwrContext{nullptr};
+
+        int m_ALBufferCount{5};
+        std::atomic_int64_t m_playingBuffers{0};
+        QVector<ALuint> m_ALBuffers{};
+        QRecursiveMutex m_ALBufferQueueMutex{};
+        QQueue<ALuint> m_ALBufferQueue{};
+        QRecursiveMutex m_ALBufferSampleMapMutex{};
+        QMap<ALuint, int64_t> m_ALBufferSampleMap{};
+        int64_t m_queuedSamples{0};
+        ALCdevice *m_ALCDevice{nullptr};
+        ALCcontext *m_ALCContext{nullptr};
+
+        ALuint m_ALSource{0};
         // Threading stuff
-        std::atomic_bool m_running  {false};
-        std::atomic_bool m_paused  {false};
+        std::atomic_bool m_running{false};
+        std::atomic_bool m_paused{false};
 
-        std::atomic_bool m_wasPaused  {false};
-        std::atomic_int64_t m_lastUpdate {0};
-        std::atomic_size_t m_audioFrame {0};
+        std::atomic_bool m_wasPaused{false};
+        std::atomic_int64_t m_lastUpdate{0};
+        std::atomic_size_t m_audioFrame{0};
 
         friend class OpenALAudioOutput;
     };
diff --git a/AVQt/output/private/OpenGLRenderer_p.h b/AVQt/output/private/OpenGLRenderer_p.h
index c5a00e6385b256621adcef570ba54c42575366ab..5092f6e284c40b8a3d33d5d49fef90e9298a8d6a 100644
--- a/AVQt/output/private/OpenGLRenderer_p.h
+++ b/AVQt/output/private/OpenGLRenderer_p.h
@@ -24,6 +24,12 @@ namespace AVQt {
      * \internal
      */
     class OpenGLRendererPrivate {
+    public:
+        OpenGLRendererPrivate(const OpenGLRendererPrivate &) = delete;
+
+        void operator=(const OpenGLRendererPrivate &) = delete;
+
+    private:
         explicit OpenGLRendererPrivate(OpenGLRenderer *q) : q_ptr(q) {};
 
         static GLint
@@ -32,30 +38,31 @@ namespace AVQt {
 
         static inline void transformPoint(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]);
 
+        static QTime timeFromMillis(int64_t ts);
 
-        OpenGLRenderer *q_ptr {nullptr};
+        OpenGLRenderer *q_ptr{nullptr};
 
-        QMutex m_renderQueueMutex;
-        QQueue<QPair<AVFrame *, int64_t>> m_renderQueue;
+        QMutex m_renderQueueMutex{};
+        QQueue<QPair<AVFrame *, int64_t>> m_renderQueue{};
 
-        RenderClock *m_clock {nullptr};
-        int64_t m_currentFrameTimeout = 1;
-        QTime m_duration;
-        QTime m_position;
-        std::atomic_bool m_updateRequired {true}, m_paused {false}, m_running {false}, m_firstFrame {true};
-        std::atomic<qint64> m_updateTimestamp {0};
-        std::chrono::time_point<std::chrono::high_resolution_clock> m_lastFrame;
+        RenderClock *m_clock{nullptr};
+        int64_t m_currentFrameTimeout{1};
+        QTime m_duration{};
+        QTime m_position{};
+        std::atomic_bool m_updateRequired{true}, m_paused{false}, m_running{false}, m_firstFrame{true};
+        std::atomic<qint64> m_updateTimestamp{0};
+        std::chrono::time_point<std::chrono::high_resolution_clock> m_lastFrame{};
 
-        QMutex m_currentFrameMutex;
-        AVFrame *m_currentFrame {nullptr};
+        QMutex m_currentFrameMutex{};
+        AVFrame *m_currentFrame{nullptr};
 
-        QOpenGLVertexArrayObject m_vao;
-        QOpenGLBuffer m_vbo, m_ibo;
-        QOpenGLShaderProgram *m_program {nullptr};
-        QOpenGLTexture *m_yTexture {nullptr}, *m_uTexture {nullptr}, *m_vTexture {nullptr};
+        QOpenGLVertexArrayObject m_vao{};
+        QOpenGLBuffer m_vbo{}, m_ibo{};
+        QOpenGLShaderProgram *m_program{nullptr};
+        QOpenGLTexture *m_yTexture{nullptr}, *m_uTexture{nullptr}, *m_vTexture{nullptr};
 
-        static constexpr uint PROGRAM_VERTEX_ATTRIBUTE {0};
-        static constexpr uint PROGRAM_TEXCOORD_ATTRIBUTE {1};
+        static constexpr uint PROGRAM_VERTEX_ATTRIBUTE{0};
+        static constexpr uint PROGRAM_TEXCOORD_ATTRIBUTE{1};
 
         friend class OpenGLRenderer;
     };
diff --git a/AVQt/output/private/RenderClock_p.h b/AVQt/output/private/RenderClock_p.h
index de66bdc9fcb5f6225787723e8556e4dea51de646..71ff96a97a5d9006b64bd2b44718e3b50b7158ed 100644
--- a/AVQt/output/private/RenderClock_p.h
+++ b/AVQt/output/private/RenderClock_p.h
@@ -9,15 +9,21 @@
 
 namespace AVQt {
     class RenderClockPrivate {
+    public:
+        RenderClockPrivate(const RenderClockPrivate &) = delete;
+
+        void operator=(const RenderClockPrivate &) = delete;
+
+    private:
         explicit RenderClockPrivate(RenderClock *q) : q_ptr(q) {};
         RenderClock *q_ptr;
 
-        QTimer *m_timer {nullptr};
-        std::atomic_int64_t m_interval {1};
-        std::atomic_bool m_active  {false};
-        std::atomic_bool m_paused  {false};
-        QElapsedTimer *m_elapsedTime {nullptr};
-        qint64 m_lastPauseTimestamp {0};
+        QTimer *m_timer{nullptr};
+        std::atomic_int m_interval{1};
+        std::atomic_bool m_active{false};
+        std::atomic_bool m_paused{false};
+        QElapsedTimer *m_elapsedTime{nullptr};
+        qint64 m_lastPauseTimestamp{0};
 
         friend class RenderClock;
     };