Hello community,

here is the log from the commit of package QMPlay2 for openSUSE:Factory checked 
in at 2019-12-05 17:34:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/QMPlay2 (Old)
 and      /work/SRC/openSUSE:Factory/.QMPlay2.new.4691 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "QMPlay2"

Thu Dec  5 17:34:11 2019 rev:41 rq:754262 version:19.12.04

Changes:
--------
--- /work/SRC/openSUSE:Factory/QMPlay2/QMPlay2.changes  2019-11-28 
10:16:25.615638569 +0100
+++ /work/SRC/openSUSE:Factory/.QMPlay2.new.4691/QMPlay2.changes        
2019-12-05 17:34:43.117444954 +0100
@@ -1,0 +2,9 @@
+Wed Dec  4 19:05:57 UTC 2019 - Simon Vogl <[email protected]>
+
+- Update to version 19.12.04
+   * Fix reading of titles for some M3U playlists,
+   * fix possible corrupted DXVA2 video playback,
+   * refactor HWAccelInterface class,
+   * minor fixes.
+
+-------------------------------------------------------------------
@@ -5 +13,0 @@
-

Old:
----
  QMPlay2-src-19.11.26.tar.xz

New:
----
  QMPlay2-src-19.12.04.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ QMPlay2.spec ++++++
--- /var/tmp/diff_new_pack.R2lZS2/_old  2019-12-05 17:34:43.809444856 +0100
+++ /var/tmp/diff_new_pack.R2lZS2/_new  2019-12-05 17:34:43.813444855 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           QMPlay2
-Version:        19.11.26
+Version:        19.12.04
 Release:        0
 Summary:        A Qt based media player, streamer and downloader
 License:        LGPL-3.0-or-later

++++++ QMPlay2-src-19.11.26.tar.xz -> QMPlay2-src-19.12.04.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/ChangeLog 
new/QMPlay2-src-19.12.04/ChangeLog
--- old/QMPlay2-src-19.11.26/ChangeLog  2019-11-26 19:54:37.000000000 +0100
+++ new/QMPlay2-src-19.12.04/ChangeLog  2019-12-04 00:31:04.000000000 +0100
@@ -1,3 +1,9 @@
+Changes in QMPlay2 build 19.12.04:
+    - fix reading of titles for some M3U playlists,
+    - fix possible corrupted DXVA2 video playback,
+    - refactor HWAccelInterface class,
+    - minor fixes,
+
 Changes in QMPlay2 build 19.11.26:
     - move OpenGL mode check boxes from visualizations and OpenGL2 settings 
into general settings,
     - improve (again) bypassing compositor on Windows platform and OpenGL,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/README.md 
new/QMPlay2-src-19.12.04/README.md
--- old/QMPlay2-src-19.11.26/README.md  2019-11-22 23:50:05.000000000 +0100
+++ new/QMPlay2-src-19.12.04/README.md  2019-12-02 20:42:00.000000000 +0100
@@ -79,10 +79,11 @@
 
 ### Hardware acceleration important information:
 - CUVID, DXVA2, VDPAU and VA-API uses OpenGL2 video output, so OpenGL features 
are available, but CPU filters won't work.
-- DXVA2 requires "WGL_NV_DX_interop" extension. Known issues: possible 
stuttering on NVIDIA GPUs, deinterlacing might not work on AMD GPUs.
-- VDPAU, VA-API and CUVID has its own deinterlacing filters. Their settings 
are available in "Settings->Video filters".
+- DXVA2 requires "WGL_NV_DX_interop" extension.
+- VDPAU, VA-API, CUVID and DXVA2 have its own deinterlacing filters. Their 
settings are available in "Settings->Video filters".
 - H.264 lossless movies (CRF 0 or QP 0) might not be properly decoded via 
VDPAU and VA-API.
 - VideoToolBox doesn't support OpenGL high quality video scaling yet.
+- high quality video downscaling doesn't work on DXVA2 and VDPAU.
 - VideoToolBox doesn't support deinterlacing.
 
 ### VA-API information:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/de.ts 
new/QMPlay2-src-19.12.04/lang/de.ts
--- old/QMPlay2-src-19.11.26/lang/de.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/de.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1937,10 +1937,6 @@
         <translation>Kann Texturen nicht initialisieren für</translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>Fehler</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation>Textur-Map-Fehler</translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/es.ts 
new/QMPlay2-src-19.12.04/lang/es.ts
--- old/QMPlay2-src-19.11.26/lang/es.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/es.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1938,10 +1938,6 @@
         <translation>No se pueden iniciar texturas para</translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>error</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation type="unfinished"></translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/fr.ts 
new/QMPlay2-src-19.12.04/lang/fr.ts
--- old/QMPlay2-src-19.11.26/lang/fr.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/fr.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1935,10 +1935,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>error</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation type="unfinished"></translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/hu.ts 
new/QMPlay2-src-19.12.04/lang/hu.ts
--- old/QMPlay2-src-19.11.26/lang/hu.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/hu.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1938,10 +1938,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>hiba</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation type="unfinished"></translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/pl.ts 
new/QMPlay2-src-19.12.04/lang/pl.ts
--- old/QMPlay2-src-19.11.26/lang/pl.ts 2019-11-23 00:47:48.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/pl.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1938,10 +1938,6 @@
         <translation>Nie udało się zainicjalizować tekstur dla</translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>błąd</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation>błąd mapowania tekstury</translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/ru.ts 
new/QMPlay2-src-19.12.04/lang/ru.ts
--- old/QMPlay2-src-19.11.26/lang/ru.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/ru.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1935,10 +1935,6 @@
         <translation>Не удается инициализировать текстуры для</translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>ошибка</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation type="unfinished"></translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/uk.ts 
new/QMPlay2-src-19.12.04/lang/uk.ts
--- old/QMPlay2-src-19.11.26/lang/uk.ts 2019-11-23 17:56:25.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/uk.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1938,10 +1938,6 @@
         <translation>Неможливо ініціалізувати текстури для</translation>
     </message>
     <message>
-        <source>error</source>
-        <translation>помилка</translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation>помилка відображення текстури</translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/lang/zh.ts 
new/QMPlay2-src-19.12.04/lang/zh.ts
--- old/QMPlay2-src-19.11.26/lang/zh.ts 2019-11-23 00:46:40.000000000 +0100
+++ new/QMPlay2-src-19.12.04/lang/zh.ts 2019-12-02 20:42:33.000000000 +0100
@@ -1935,10 +1935,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>error</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>texture map error</source>
         <translation type="unfinished"></translation>
     </message>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/CUVID/CMakeLists.txt 
new/QMPlay2-src-19.12.04/src/modules/CUVID/CMakeLists.txt
--- old/QMPlay2-src-19.11.26/src/modules/CUVID/CMakeLists.txt   2018-02-08 
17:21:48.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/CUVID/CMakeLists.txt   2019-12-02 
20:42:00.000000000 +0100
@@ -44,4 +44,8 @@
     libqmplay2
 )
 
+if(WIN32)
+    target_link_libraries(${PROJECT_NAME} opengl32)
+endif()
+
 install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${MODULES_INSTALL_PATH})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/modules/CUVID/CuvidDec.cpp 
new/QMPlay2-src-19.12.04/src/modules/CUVID/CuvidDec.cpp
--- old/QMPlay2-src-19.11.26/src/modules/CUVID/CuvidDec.cpp     2019-11-14 
19:06:28.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/CUVID/CuvidDec.cpp     2019-12-02 
20:42:00.000000000 +0100
@@ -25,13 +25,25 @@
 
 #include <QLibrary>
 #include <QMutex>
+#include <QDebug>
+
+#include <GL/gl.h>
 
 #ifdef Q_OS_WIN
     #include <windows.h>
 #endif
 
-#ifndef GL_TEXTURE_2D
-    #define GL_TEXTURE_2D 0x0DE1
+#ifndef GL_R8
+    #define GL_R8 0x8229
+#endif
+#ifndef GL_RG8
+    #define GL_RG8 0x822B
+#endif
+#ifndef GL_RED
+    #define GL_RED 0x1903
+#endif
+#ifndef GL_RG
+    #define GL_RG 0x8227
 #endif
 
 static QMutex g_cudaMutex(QMutex::Recursive);
@@ -230,16 +242,9 @@
 class CuvidHWAccel : public HWAccelInterface
 {
 public:
-    CuvidHWAccel(CUcontext cuCtx) :
-        m_canDestroyCuda(false),
-        m_codedHeight(0),
-        m_lastId(0),
-        m_tff(false),
-        m_cuCtx(cuCtx),
-        m_cuvidDec(nullptr)
-    {
-        memset(m_res, 0, sizeof m_res);
-    }
+    CuvidHWAccel(CUcontext cuCtx)
+        : m_cuCtx(cuCtx)
+    {}
     ~CuvidHWAccel() final
     {
         if (m_canDestroyCuda)
@@ -259,33 +264,47 @@
         return NV12;
     }
 
-    bool lock() override
+    bool init(const int *widths, const int *heights, const SetTextureParamsFn 
&setTextureParamsFn) override
     {
-        g_cudaMutex.lock();
-        if (cu::ctxPushCurrent(m_cuCtx) == CUDA_SUCCESS)
+        cu::ContextGuard cuCtxGuard(m_cuCtx);
+
+        bool mustRegister = false;
+        for (int p = 0; p < 2; ++p)
+        {
+            if (m_widths[p] != widths[p] || m_heights[p] != heights[p])
+            {
+                clear();
+                for (int p = 0; p < 2; ++p)
+                {
+                    m_widths[p] = widths[p];
+                    m_heights[p] = heights[p];
+
+                    glGenTextures(1, &m_textures[p]);
+                    glBindTexture(GL_TEXTURE_2D, m_textures[p]);
+                    glTexImage2D(GL_TEXTURE_2D, 0, (p == 0) ? GL_R8 : GL_RG8, 
widths[p], heights[p], 0, (p == 0) ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, nullptr);
+                }
+                mustRegister = true;
+                break;
+            }
+        }
+
+        for (int p = 0; p < 2; ++p)
+            setTextureParamsFn(m_textures[p]);
+
+        if (!mustRegister)
             return true;
-        g_cudaMutex.unlock();
-        return false;
-    }
-    void unlock() override
-    {
-        CUcontext cuCtx;
-        cu::ctxPopCurrent(&cuCtx);
-        g_cudaMutex.unlock();
-    }
 
-    bool init(quint32 *textures) override
-    {
         for (int p = 0; p < 2; ++p)
         {
-            if (cu::graphicsGLRegisterImage(&m_res[p], textures[p], 
GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD) != CUDA_SUCCESS)
+            if (cu::graphicsGLRegisterImage(&m_res[p], m_textures[p], 
GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD) != CUDA_SUCCESS)
                 return false;
         }
+
         return true;
     }
-    void clear(bool contextChange) override
+    void clear() override
     {
-        Q_UNUSED(contextChange)
+        cu::ContextGuard cuCtxGuard(m_cuCtx);
         for (int p = 0; p < 2; ++p)
         {
             if (m_res[p])
@@ -293,11 +312,20 @@
                 cu::graphicsUnregisterResource(m_res[p]);
                 m_res[p] = nullptr;
             }
+            if (m_textures[p])
+            {
+                glDeleteTextures(1, &m_textures[p]);
+                m_textures[p] = 0;
+            }
+            m_widths[p] = 0;
+            m_heights[p] = 0;
         }
     }
 
     MapResult mapFrame(const VideoFrame &videoFrame, Field field) override
     {
+        cu::ContextGuard cuCtxGuard(m_cuCtx);
+
         if (!m_cuvidDec || !m_validSurfaces.contains(videoFrame.surfaceId))
             return MapNotReady;
 
@@ -367,6 +395,10 @@
 
         return MapError;
     }
+    quint32 getTexture(int plane) override
+    {
+        return m_textures[plane];
+    }
 
     bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32) override
     {
@@ -439,17 +471,22 @@
     }
 
 private:
-    bool m_canDestroyCuda;
+    bool m_canDestroyCuda = false;
+
+    int m_codedHeight = 0;
+
+    quint32 m_textures[2] = {};
 
-    int m_codedHeight;
+    int m_widths[2] = {};
+    int m_heights[2] = {};
 
-    quintptr m_lastId;
-    bool m_tff;
+    quintptr m_lastId = 0;
+    bool m_tff = false;
 
-    CUcontext m_cuCtx;
-    CUvideodecoder m_cuvidDec;
+    const CUcontext m_cuCtx;
+    CUvideodecoder m_cuvidDec = nullptr;
 
-    CUgraphicsResource m_res[2];
+    CUgraphicsResource m_res[2] = {};
 
     QSet<quintptr> m_validSurfaces;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/Extensions/Downloader.cpp 
new/QMPlay2-src-19.12.04/src/modules/Extensions/Downloader.cpp
--- old/QMPlay2-src-19.11.26/src/modules/Extensions/Downloader.cpp      
2019-08-23 23:31:17.000000000 +0200
+++ new/QMPlay2-src-19.12.04/src/modules/Extensions/Downloader.cpp      
2019-12-02 20:42:00.000000000 +0100
@@ -528,6 +528,11 @@
             downloadLW->resize(downloadLW->size() + QSize(0, 1));
             downloadLW->resize(downloadLW->size() - QSize(0, 1));
 
+            if (!downloadLW->currentItem())
+                downloadLW->setCurrentItem(item);
+            else
+                downloadLW->scrollToItem(item, 
QAbstractItemView::EnsureVisible);
+
             break;
         case NAME:
             downloadItemW->setName(name);
@@ -1156,7 +1161,6 @@
         action->property("param").toString(),
         action->property("preset").toString()
     );
-    downloadLW->setCurrentItem(downloadLW->invisibleRootItem()->child(0));
 }
 void Downloader::itemDoubleClicked(QTreeWidgetItem *item)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/FFmpeg/CMakeLists.txt 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/CMakeLists.txt
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/CMakeLists.txt  2019-11-22 
23:37:13.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/CMakeLists.txt  2019-12-02 
20:42:00.000000000 +0100
@@ -119,4 +119,8 @@
     libqmplay2
 )
 
+if(WIN32 AND USE_FFMPEG_DXVA2)
+    target_link_libraries(${PROJECT_NAME} opengl32)
+endif()
+
 install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${MODULES_INSTALL_PATH})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecDXVA2.cpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecDXVA2.cpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecDXVA2.cpp  2019-11-22 
19:08:53.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecDXVA2.cpp  2019-12-02 
20:42:00.000000000 +0100
@@ -81,13 +81,14 @@
     {
         if (m_dontReleaseRenderTarget)
         {
-            for (auto &&renderTarget : asConst(m_renderTargets))
-                renderTarget->Release();
+            for (int i = 0; i < s_numRenderTargets; ++i)
+            {
+                for (auto &&renderTarget : 
asConst(m_renderTargets[i].surfaces))
+                    renderTarget->Release();
+            }
         }
         if (m_videoProcessor)
             m_videoProcessor->Release();
-        if (m_videoProcessorService)
-            m_videoProcessorService->Release();
         av_buffer_unref(&m_hwDeviceBufferRef);
     }
 
@@ -101,14 +102,24 @@
         return RGB32;
     }
 
-    bool init(quint32 *textures) override
+    bool init(const int *widths, const int *heights, const SetTextureParamsFn 
&setTextureParamsFn) override
     {
-        if (m_glHandleD3D)
+        if (m_width != widths[0] || m_height != heights[0])
         {
-            m_textures = textures;
-            return true;
+            clearTextures();
+
+            m_width = widths[0];
+            m_height = heights[0];
+
+            glGenTextures(2, m_textures);
         }
 
+        for (int i = 0; i < 2; ++i)
+            setTextureParamsFn(m_textures[i]);
+
+        if (m_glHandleD3D)
+            return ensureRenderTargets();
+
         auto context = QOpenGLContext::currentContext();
         if (!context)
         {
@@ -152,37 +163,26 @@
             return false;
         }
 
-        m_textures = textures;
+        if (!ensureRenderTargets())
+            return false;
+
         return true;
     }
-    void clear(bool contextChange) override
+    void clear() override
     {
-        releaseRenderTarget();
-        if (m_glHandleD3D && contextChange)
+        clearTextures();
+        if (m_glHandleD3D)
         {
             wglDXCloseDeviceNV(m_glHandleD3D);
             m_glHandleD3D = nullptr;
         }
-        m_textures = nullptr;
     }
 
     MapResult mapFrame(const VideoFrame &videoFrame, Field field) override
     {
         Q_UNUSED(field)
 
-        if (!unlockRenderTarget())
-            return MapError;
-
-        const int width = videoFrame.size.width;
-        const int height = videoFrame.size.height;
-        if (m_width != width || m_height != height)
-        {
-            releaseRenderTarget();
-            m_width = width;
-            m_height = height;
-        }
-
-        if (!ensureRenderTarget())
+        if (!unlockRenderTargets())
             return MapError;
 
         const RECT rect = {
@@ -233,15 +233,22 @@
             : DXVA2_NominalRange_16_235
         ;
 
-        if (FAILED(m_videoProcessor->VideoProcessBlt(m_renderTarget, 
&m_bltParams, &m_videoSample, 1, nullptr)))
+        if 
(FAILED(m_videoProcessor->VideoProcessBlt(m_renderTargets[m_renderTargetIdx].surface,
 &m_bltParams, &m_videoSample, 1, nullptr)))
             return MapError;
 
-        if (!wglDXLockObjectsNV(m_glHandleD3D, 1, &m_glHandleSurface))
+        m_renderTargetIdx = (m_renderTargetIdx + 1) % s_numRenderTargets;
+
+        if (!wglDXLockObjectsNV(m_glHandleD3D, 1, 
&m_renderTargets[m_renderTargetIdx].glSurface))
             return MapError;
 
-        m_surfaceLocked = true;
+        m_renderTargets[m_renderTargetIdx].locked = true;
         return MapOk;
     }
+    quint32 getTexture(int plane) override
+    {
+        Q_UNUSED(plane)
+        return m_textures[m_renderTargetIdx];
+    }
 
     bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32) override
     {
@@ -375,19 +382,23 @@
         if (!d3dDev9)
             return false;
 
-        if (FAILED(DXVA2CreateVideoService(d3dDev9.get(), 
IID_IDirectXVideoProcessorService, (void **)&m_videoProcessorService)))
+        IDirectXVideoProcessorService *videoProcessorService = nullptr;
+        if (FAILED(DXVA2CreateVideoService(d3dDev9.get(), 
IID_IDirectXVideoProcessorService, (void **)&videoProcessorService)))
         {
             QMPlay2Core.logError("DXVA2 :: Unable to create video processor 
service");
             return false;
         }
 
         DXVA2_VideoDesc videoDesc = {};
-        if 
(FAILED(m_videoProcessorService->CreateVideoProcessor(QMPlay2_DXVA2_VideoProcProgressiveDevice,
 &videoDesc, D3DFMT_X8R8G8B8, 0, &m_videoProcessor)))
+        if 
(FAILED(videoProcessorService->CreateVideoProcessor(QMPlay2_DXVA2_VideoProcProgressiveDevice,
 &videoDesc, D3DFMT_X8R8G8B8, 0, &m_videoProcessor)))
         {
             QMPlay2Core.logError("DXVA2 :: Unable to create video processor");
+            videoProcessorService->Release();
             return false;
         }
 
+        videoProcessorService->Release();
+
         return true;
     }
 
@@ -413,93 +424,94 @@
         });
     }
 
-    bool ensureRenderTarget()
+    bool ensureRenderTargets()
     {
-        if (m_renderTarget)
-            return true;
+        for (int i = 0; i < s_numRenderTargets; ++i)
+        {
+            auto &surface = m_renderTargets[i].surface;
+            if (surface)
+                continue;
 
-        Q_ASSERT(!m_glHandleSurface);
+            auto &glSurface = m_renderTargets[i].glSurface;
+            Q_ASSERT(!glSurface);
 
-        const auto size = qMakePair(m_width, m_height);
+            const auto size = qMakePair(m_width, m_height);
+            auto &surfaces = m_renderTargets[i].surfaces;
 
-        if (m_dontReleaseRenderTarget)
-            m_renderTarget = m_renderTargets.value(size);
-        if (!m_renderTarget)
-        {
-            HANDLE sharedHandle = nullptr;
+            if (m_dontReleaseRenderTarget)
+                surface = surfaces.value(size);
+            if (!surface)
+            {
+                HANDLE sharedHandle = nullptr;
 
-#if 1
-            auto d3dDev9 = getD3dDevice9();
-            if (!d3dDev9)
-                return false;
+                auto d3dDev9 = getD3dDevice9();
+                if (!d3dDev9)
+                    return false;
+
+                HRESULT hr = d3dDev9->CreateRenderTarget(
+                    m_width,
+                    m_height,
+                    D3DFMT_X8R8G8B8,
+                    D3DMULTISAMPLE_NONE,
+                    0,
+                    false,
+                    &surface,
+                    &sharedHandle
+                );
+                if (FAILED(hr))
+                    return false;
 
-            HRESULT hr = d3dDev9->CreateRenderTarget(
-                m_width,
-                m_height,
-                D3DFMT_X8R8G8B8,
-                D3DMULTISAMPLE_NONE,
-                0,
-                false,
-                &m_renderTarget,
-                &sharedHandle
-            );
-#else
-            HRESULT hr = m_videoProcessorService->CreateSurface(
-                m_width,
-                m_height,
-                0,
-                D3DFMT_X8R8G8B8,
-                D3DPOOL_DEFAULT,
-                0,
-                DXVA2_VideoProcessorRenderTarget,
-                &m_renderTarget,
-                &sharedHandle
-            );
-#endif
-            if (FAILED(hr))
-                return false;
+                if (m_dontReleaseRenderTarget)
+                    surfaces[size] = surface;
 
-            if (m_dontReleaseRenderTarget)
-                m_renderTargets[size] = m_renderTarget;
+                if (!wglDXSetResourceShareHandleNV(surface, sharedHandle))
+                    return false;
+            }
 
-            if (!wglDXSetResourceShareHandleNV(m_renderTarget, sharedHandle))
+            glSurface = wglDXRegisterObjectNV(m_glHandleD3D, surface, 
m_textures[i], GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV);
+            if (!glSurface)
                 return false;
         }
 
-        m_glHandleSurface = wglDXRegisterObjectNV(m_glHandleD3D, 
m_renderTarget, m_textures[0], GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV);
-        if (!m_glHandleSurface)
-            return false;
-
         return true;
     }
-    bool unlockRenderTarget()
+    bool unlockRenderTargets()
     {
-        if (!m_surfaceLocked)
-            return true;
-
-        Q_ASSERT(m_glHandleSurface);
-        if (wglDXUnlockObjectsNV(m_glHandleD3D, 1, &m_glHandleSurface))
+        bool ok = true;
+        for (int i = 0; i < s_numRenderTargets; ++i)
         {
-            m_surfaceLocked = false;
-            return true;
-        }
+            if (!m_renderTargets[i].locked)
+                continue;
 
-        return false;
+            Q_ASSERT(m_renderTargets[i].glSurface);
+            if (wglDXUnlockObjectsNV(m_glHandleD3D, 1, 
&m_renderTargets[i].glSurface))
+                m_renderTargets[i].locked = false;
+            else
+                ok = false;
+        }
+        return ok;
     }
-    void releaseRenderTarget()
+
+    void clearTextures()
     {
-        unlockRenderTarget();
-        if (m_glHandleSurface)
+        unlockRenderTargets();
+        for (int i = 0; i < s_numRenderTargets; ++i)
         {
-            wglDXUnregisterObjectNV(m_glHandleD3D, m_glHandleSurface);
-            m_glHandleSurface = nullptr;
-        }
-        if (m_renderTarget)
-        {
-            if (!m_dontReleaseRenderTarget)
-                m_renderTarget->Release();
-            m_renderTarget = nullptr;
+            if (m_renderTargets[i].glSurface)
+            {
+                wglDXUnregisterObjectNV(m_glHandleD3D, 
m_renderTargets[i].glSurface);
+                m_renderTargets[i].glSurface = nullptr;
+            }
+            if (m_renderTargets[i].surface)
+            {
+                if (!m_dontReleaseRenderTarget)
+                    m_renderTargets[i].surface->Release();
+                m_renderTargets[i].surface = nullptr;
+            }
         }
+
+        glDeleteTextures(2, m_textures);
+        memset(m_textures, 0, sizeof(m_textures));
         m_width = m_height = 0;
     }
 
@@ -515,21 +527,24 @@
     PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV = nullptr;
     PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV = nullptr;
 
-    IDirectXVideoProcessorService *m_videoProcessorService = nullptr;
     IDirectXVideoProcessor *m_videoProcessor = nullptr;
     DXVA2_VideoSample m_videoSample = {};
     DXVA2_VideoProcessBltParams m_bltParams = {};
 
-    QHash<QPair<int, int>, IDirect3DSurface9 *> m_renderTargets;
     bool m_dontReleaseRenderTarget = false;
 
-    quint32 *m_textures = nullptr;
-
     HANDLE m_glHandleD3D = nullptr;
 
-    IDirect3DSurface9 *m_renderTarget = nullptr;
-    HANDLE m_glHandleSurface = nullptr;
-    bool m_surfaceLocked = false;
+    static constexpr int s_numRenderTargets = 2;
+    struct RenderTarget
+    {
+        QHash<QPair<int, int>, IDirect3DSurface9 *> surfaces;
+        IDirect3DSurface9 *surface = nullptr;
+        HANDLE glSurface = nullptr;
+        bool locked = false;
+    } m_renderTargets[s_numRenderTargets];
+    quint32 m_textures[2] = {};
+    int m_renderTargetIdx = 0;
     int m_width = 0;
     int m_height = 0;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVAAPI.cpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVAAPI.cpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVAAPI.cpp  2019-11-22 
23:37:13.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVAAPI.cpp  2019-12-02 
20:42:00.000000000 +0100
@@ -48,8 +48,6 @@
 #   include <EGL/egl.h>
 #   include <EGL/eglext.h>
 
-#   include <GL/gl.h>
-
 #   ifndef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT
 #       define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
 #   endif
@@ -58,12 +56,15 @@
 #   endif
 #endif
 
+#include <GL/gl.h>
+
 class VAAPIOpenGL : public HWAccelInterface
 {
 public:
     VAAPIOpenGL(const std::shared_ptr<VAAPI> &vaapi)
         : m_vaapi(vaapi)
         , m_isEGL(m_vaapi->m_fd > -1)
+        , m_numPlanes(m_isEGL ? 2 : 1)
     {}
     ~VAAPIOpenGL() final
     {}
@@ -85,17 +86,33 @@
         return m_isEGL ? false : true;
     }
 
-    bool canInitializeTextures() const override
+    bool init(const int *widths, const int *heights, const SetTextureParamsFn 
&setTextureParamsFn) override
     {
-        return true;
-    }
+        for (int p = 0; p < m_numPlanes; ++p)
+        {
+            if (m_widths[p] != widths[p] || m_heights[p] != heights[p])
+            {
+                clearTextures();
+                for (int p = 0; p < m_numPlanes; ++p)
+                {
+                    m_widths[p] = widths[p];
+                    m_heights[p] = heights[p];
+                }
+                glGenTextures(m_numPlanes, m_textures);
+                break;
+            }
+        }
+
+        for (int p = 0; p < m_numPlanes; ++p)
+            setTextureParamsFn(m_textures[p]);
 
-    bool init(quint32 *textures) override
-    {
         if (!m_isEGL)
-            return (vaCreateSurfaceGLX(m_vaapi->VADisp, GL_TEXTURE_2D, 
*textures, &m_glSurface) == VA_STATUS_SUCCESS);
+            return (vaCreateSurfaceGLX(m_vaapi->VADisp, GL_TEXTURE_2D, 
m_textures[0], &m_glSurface) == VA_STATUS_SUCCESS);
 
 #ifdef VAAPI_HAS_ESH
+        if (m_eglDpy != EGL_NO_DISPLAY && eglCreateImageKHR && 
eglDestroyImageKHR && glEGLImageTargetTexture2DOES)
+            return true;
+
         const auto context = QOpenGLContext::currentContext();
         if (!context)
         {
@@ -135,17 +152,13 @@
 
         m_hasDmaBufImportModifiers = 
extensions.contains("EGL_EXT_image_dma_buf_import_modifiers");
 
-        m_textures = textures;
-
         return true;
 #else
         return false;
 #endif
     }
-    void clear(bool contextChange) override
+    void clear() override
     {
-        Q_UNUSED(contextChange)
-
 #ifdef VAAPI_HAS_ESH
         if (m_isEGL)
         {
@@ -156,15 +169,9 @@
             glEGLImageTargetTexture2DOES = nullptr;
 
             m_hasDmaBufImportModifiers = false;
-
-            m_textures = nullptr;
         }
 #endif
-        if (m_glSurface)
-        {
-            vaDestroySurfaceGLX(m_vaapi->VADisp, m_glSurface);
-            m_glSurface = nullptr;
-        }
+        clearTextures();
     }
 
     MapResult mapFrame(const VideoFrame &videoFrame, Field field) override
@@ -257,6 +264,10 @@
         return MapError;
 #endif
     }
+    quint32 getTexture(int plane) override
+    {
+        return m_textures[plane];
+    }
 
     bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32) override
     {
@@ -265,6 +276,9 @@
 
     void getVideAdjustmentCap(VideoAdjustment &videoAdjustmentCap) override
     {
+        if (m_isEGL)
+            return;
+
         videoAdjustmentCap.brightness = false;
         videoAdjustmentCap.contrast = false;
         videoAdjustmentCap.saturation = true;
@@ -285,8 +299,29 @@
     }
 
 private:
+    void clearTextures()
+    {
+        if (m_glSurface)
+        {
+            vaDestroySurfaceGLX(m_vaapi->VADisp, m_glSurface);
+            m_glSurface = nullptr;
+        }
+
+        glDeleteTextures(m_numPlanes, m_textures);
+        memset(m_textures, 0, sizeof(m_textures));
+        memset(m_widths, 0, sizeof(m_widths));
+        memset(m_heights, 0, sizeof(m_heights));
+    }
+
+private:
     const std::shared_ptr<VAAPI> m_vaapi;
     const bool m_isEGL;
+    const int m_numPlanes;
+
+    quint32 m_textures[2] = {};
+
+    int m_widths[2] = {};
+    int m_heights[2] = {};
 
     // GLX
     void *m_glSurface = nullptr;
@@ -300,8 +335,6 @@
     PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = nullptr;
 
     bool m_hasDmaBufImportModifiers = false;
-
-    quint32 *m_textures = nullptr;
 #endif
 };
 
@@ -476,7 +509,7 @@
     codec_ctx->get_format = vaapiGetFormat;
     codec_ctx->thread_count = 1;
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 18, 100)
-    codec_ctx->extra_hw_frames = 3;
+    codec_ctx->extra_hw_frames = 4;
 #endif
     if (!openCodec(codec))
         return false;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVDPAU.cpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVDPAU.cpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVDPAU.cpp  2019-11-22 
23:37:13.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVDPAU.cpp  2019-12-02 
20:42:00.000000000 +0100
@@ -53,19 +53,24 @@
     {
         return RGB32;
     }
-    bool isCopy() const override
-    {
-        return true;
-    }
 
-    bool init(quint32 *textures) override
+    bool init(const int *widths, const int *heights, const SetTextureParamsFn 
&setTextureParamsFn) override
     {
-        if (m_isInitialized)
+        if (m_width != widths[0] || m_height != heights[0])
         {
-            m_textures = textures;
-            return true;
+            clearTextures();
+
+            m_width = widths[0];
+            m_height = heights[0];
+
+            glGenTextures(1, &m_texture);
         }
 
+        setTextureParamsFn(m_texture);
+
+        if (m_isInitialized)
+            return true;
+
         const auto context = QOpenGLContext::currentContext();
         if (!context)
         {
@@ -100,29 +105,26 @@
         }
 
         m_isInitialized = true;
-
-        m_textures = textures;
         return true;
     }
-    void clear(bool contextChange) override
+    void clear() override
     {
-        maybeUnmapOutputSurface();
-        maybeUnregisterOutputSurface();
-        if (m_isInitialized && contextChange)
-        {
-            VDPAUFiniNV();
+        clearTextures();
 
-            VDPAUInitNV = nullptr;
-            VDPAUFiniNV = nullptr;
-            VDPAURegisterOutputSurfaceNV = nullptr;
-            VDPAUUnregisterSurfaceNV = nullptr;
-            VDPAUSurfaceAccessNV = nullptr;
-            VDPAUMapSurfacesNV = nullptr;
-            VDPAUUnmapSurfacesNV = nullptr;
+        if (!m_isInitialized)
+            return;
 
-            m_isInitialized = false;
-        }
-        m_textures = nullptr;
+        VDPAUFiniNV();
+
+        VDPAUInitNV = nullptr;
+        VDPAUFiniNV = nullptr;
+        VDPAURegisterOutputSurfaceNV = nullptr;
+        VDPAUUnregisterSurfaceNV = nullptr;
+        VDPAUSurfaceAccessNV = nullptr;
+        VDPAUMapSurfacesNV = nullptr;
+        VDPAUUnmapSurfacesNV = nullptr;
+
+        m_isInitialized = false;
     }
 
     MapResult mapFrame(const VideoFrame &videoFrame, Field field) override
@@ -151,7 +153,7 @@
         {
             maybeUnregisterOutputSurface();
 
-            m_glSurface = VDPAURegisterOutputSurfaceNV(id, GL_TEXTURE_2D, 1, 
m_textures);
+            m_glSurface = VDPAURegisterOutputSurfaceNV(id, GL_TEXTURE_2D, 1, 
&m_texture);
             if (!m_glSurface)
                 return MapError;
 
@@ -166,6 +168,11 @@
         m_isSurfaceMapped = true;
         return MapOk;
     }
+    quint32 getTexture(int plane) override
+    {
+        Q_UNUSED(plane)
+        return m_texture;
+    }
 
     bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32) override
     {
@@ -212,12 +219,28 @@
     }
 
 private:
+    void clearTextures()
+    {
+        maybeUnmapOutputSurface();
+        maybeUnregisterOutputSurface();
+        if (m_texture)
+        {
+            glDeleteTextures(1, &m_texture);
+            m_texture = 0;
+        }
+        m_width = m_height = 0;
+    }
+
+private:
     using GLvdpauSurfaceNV = GLintptr;
 
     std::shared_ptr<VDPAU> m_vdpau;
 
     bool m_isInitialized = false;
-    uint32_t *m_textures = nullptr;
+    uint32_t m_texture = 0;
+
+    int m_width = 0;
+    int m_height = 0;
 
     VdpOutputSurface m_registeredOutputSurface = VDP_INVALID_HANDLE;
     GLvdpauSurfaceNV m_glSurface = 0;
@@ -386,7 +409,7 @@
     codec_ctx->get_format = vdpauGetFormat;
     codec_ctx->thread_count = 1;
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 18, 100)
-    codec_ctx->extra_hw_frames = 3;
+    codec_ctx->extra_hw_frames = 4;
 #endif
     if (!openCodec(codec))
         return false;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVTB.cpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVTB.cpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/FFDecVTB.cpp    2019-11-22 
19:07:05.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/FFDecVTB.cpp    2019-12-02 
20:42:00.000000000 +0100
@@ -82,20 +82,32 @@
         return false;
     }
 
-    bool canInitializeTextures() const override
+    bool init(const int *widths, const int *heights, const SetTextureParamsFn 
&setTextureParamsFn) override
     {
-        return false;
-    }
-
-    bool init(quint32 *textures) override
-    {
-        m_glTextures = textures;
+        for (int p = 0; p < 2; ++p)
+        {
+            if (m_widths[p] != widths[p] || m_heights[p] != heights[p])
+            {
+                clear();
+                for (int p = 0; p < 2; ++p)
+                {
+                    m_widths[p] = widths[p];
+                    m_heights[p] = heights[p];
+                }
+                glGenTextures(2, m_textures);
+                break;
+            }
+        }
+        for (int p = 0; p < 2; ++p)
+            setTextureParamsFn(m_textures[p]);
         return true;
     }
-    void clear(bool contextChange) override
+    void clear() override
     {
-        Q_UNUSED(contextChange)
-        m_glTextures = nullptr;
+        glDeleteTextures(2, m_textures);
+        memset(m_textures, 0, sizeof(m_textures));
+        memset(m_widths, 0, sizeof(m_widths));
+        memset(m_heights, 0, sizeof(m_heights));
     }
 
     MapResult mapFrame(const VideoFrame &videoFrame, Field field) override
@@ -111,16 +123,20 @@
         if (pixelFormat != kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
             return MapError;
 
-        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_glTextures[0]);
+        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_textures[0]);
         if (CGLTexImageIOSurface2D(glCtx, GL_TEXTURE_RECTANGLE_ARB, GL_R8, 
videoFrame.size.getWidth(0), videoFrame.size.getHeight(0), GL_RED, 
GL_UNSIGNED_BYTE, surface, 0) != kCGLNoError)
             return MapError;
 
-        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_glTextures[1]);
+        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_textures[1]);
         if (CGLTexImageIOSurface2D(glCtx, GL_TEXTURE_RECTANGLE_ARB, GL_RG8, 
videoFrame.size.getWidth(1), videoFrame.size.getHeight(1), GL_RG, 
GL_UNSIGNED_BYTE, surface, 1) != kCGLNoError)
             return MapError;
 
         return MapOk;
     }
+    quint32 getTexture(int plane) override
+    {
+        return m_textures[plane];
+    }
 
     bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32) override
     {
@@ -152,7 +168,10 @@
     AVBufferRef *m_hwDeviceBufferRef = nullptr;
 
 private:
-    quint32 *m_glTextures = nullptr;
+    quint32 m_textures[2] = {};
+
+    int m_widths[2] = {};
+    int m_heights[2] = {};
 };
 
 /**/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/modules/FFmpeg/VDPAU.cpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/VDPAU.cpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/VDPAU.cpp       2019-11-13 
18:56:21.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/VDPAU.cpp       2019-12-02 
20:42:00.000000000 +0100
@@ -127,6 +127,7 @@
 
 void VDPAU::clearBufferedFrames()
 {
+    QMutexLocker locker(&m_framesMutex);
     m_bufferedFrames.clear();
 }
 
@@ -268,6 +269,8 @@
     }
     else
     {
+        QMutexLocker locker(&m_framesMutex);
+
         if (m_bufferedFrames.empty() || m_bufferedFrames[0].surfaceId != 
videoFrame.surfaceId)
         {
             while (m_bufferedFrames.size() >= numVideoFrames)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/modules/FFmpeg/VDPAU.hpp 
new/QMPlay2-src-19.12.04/src/modules/FFmpeg/VDPAU.hpp
--- old/QMPlay2-src-19.11.26/src/modules/FFmpeg/VDPAU.hpp       2019-11-13 
18:54:48.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/FFmpeg/VDPAU.hpp       2019-12-02 
20:42:00.000000000 +0100
@@ -21,6 +21,7 @@
 #include <VideoFrame.hpp>
 
 #include <QCoreApplication>
+#include <QMutex>
 
 #include <deque>
 
@@ -87,6 +88,7 @@
     bool m_mustSetCSCMatrix = false;
     bool m_mustApplyVideoMixerFeatures = false;
 
+    QMutex m_framesMutex;
     std::deque<VideoFrame> m_bufferedFrames;
 
     VdpGetProcAddress *vdp_get_proc_address = nullptr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/OpenGL2/CMakeLists.txt 
new/QMPlay2-src-19.12.04/src/modules/OpenGL2/CMakeLists.txt
--- old/QMPlay2-src-19.11.26/src/modules/OpenGL2/CMakeLists.txt 2019-11-03 
19:43:35.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/OpenGL2/CMakeLists.txt 2019-12-02 
20:42:00.000000000 +0100
@@ -26,7 +26,6 @@
 
 if(NOT WIN32)
     if(Qt5Gui_OPENGL_IMPLEMENTATION STREQUAL GLESv2)
-        set(QT_USES_OPENGLES ON)
         add_definitions(-DOPENGL_ES2)
     elseif(Qt5Gui_OPENGL_IMPLEMENTATION STREQUAL GLES)
         message(SEND_ERROR "OpenGL|ES 1.0 is not supported!")
@@ -49,11 +48,7 @@
     find_package(OpenGL REQUIRED)
     target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES})
 elseif(WIN32)
-    if(QT_USES_OPENGLES)
-        target_link_libraries(${PROJECT_NAME} GLESv2)
-    else()
-        target_link_libraries(${PROJECT_NAME} opengl32)
-    endif()
+    target_link_libraries(${PROJECT_NAME} opengl32)
 endif()
 
 install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${MODULES_INSTALL_PATH})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/OpenGL2/OpenGL2Common.cpp 
new/QMPlay2-src-19.12.04/src/modules/OpenGL2/OpenGL2Common.cpp
--- old/QMPlay2-src-19.11.26/src/modules/OpenGL2/OpenGL2Common.cpp      
2019-11-14 21:16:25.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/OpenGL2/OpenGL2Common.cpp      
2019-12-02 20:42:00.000000000 +0100
@@ -52,18 +52,6 @@
 #ifndef GL_PIXEL_UNPACK_BUFFER
     #define GL_PIXEL_UNPACK_BUFFER 0x88EC
 #endif
-#ifndef GL_R8
-    #define GL_R8 0x8229
-#endif
-#ifndef GL_RG8
-    #define GL_RG8 0x822B
-#endif
-#ifndef GL_RED
-    #define GL_RED 0x1903
-#endif
-#ifndef GL_RG
-    #define GL_RG 0x8227
-#endif
 #ifndef GL_TEXTURE_RECTANGLE_ARB
     #define GL_TEXTURE_RECTANGLE_ARB 0x84F5
 #endif
@@ -276,6 +264,16 @@
     }
 }
 
+void OpenGL2Common::setTextureParameters(GLenum target, quint32 texture, GLint 
param)
+{
+    glBindTexture(target, texture);
+    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, param);
+    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, param);
+    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glBindTexture(target, 0);
+}
+
 void OpenGL2Common::initializeGL()
 {
     if (!initGLProc())
@@ -377,21 +375,17 @@
     glDisable(GL_DITHER);
 
     /* Prepare textures */
-    glGenTextures(numPlanes + 1, textures);
-    for (int i = 0; i < numPlanes + 1; ++i)
+    const int texturesToGen = hwAccellnterface ? 0 : numPlanes;
+    glGenTextures(texturesToGen + 1, textures);
+    for (int i = 0; i < texturesToGen + 1; ++i)
     {
         const quint32 tmpTarget = (i == 0) ? GL_TEXTURE_2D : target;
-        qint32 tmpParam  = (i == 0) ? GL_NEAREST : GL_LINEAR;
-        glBindTexture(tmpTarget, textures[i]);
-        glTexParameteri(tmpTarget, GL_TEXTURE_MIN_FILTER, tmpParam);
-        glTexParameteri(tmpTarget, GL_TEXTURE_MAG_FILTER, tmpParam);
-        glTexParameteri(tmpTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(tmpTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        setTextureParameters(tmpTarget, textures[i], (i == 0) ? GL_NEAREST : 
GL_LINEAR);
     }
 
     if (hasPbo)
     {
-        glGenBuffers(1 + (hwAccellnterface ? 0 : numPlanes), pbo);
+        glGenBuffers(1 + texturesToGen, pbo);
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     }
 
@@ -415,7 +409,7 @@
 
     bool resetDone = false;
 
-    if (!frameIsEmpty && hwAccellPossibleLock())
+    if (!frameIsEmpty)
     {
         const GLsizei widths[3] = {
             videoFrame.size.width,
@@ -432,39 +426,15 @@
         {
             if (hwAccellnterface)
             {
-                /* Release HWAccell resources */
-                hwAccellnterface->clear(false);
-
-                if (hwAccellnterface->canInitializeTextures())
-                {
-                    if (numPlanes == 2)
-                    {
-                        //NV12
-                        for (int p = 0; p < 2; ++p)
-                        {
-                            glBindTexture(target, textures[p + 1]);
-                            glTexImage2D(target, 0, !p ? GL_R8 : GL_RG8, 
widths[p], heights[p], 0, !p ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, nullptr);
-                        }
-                    }
-                    else if (numPlanes == 1)
-                    {
-                        //RGB32
-                        glBindTexture(target, textures[1]);
-                        glTexImage2D(target, 0, GL_RGBA, widths[0], 
heights[0], 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
-                    }
-                }
-
                 m_textureSize = QSize(widths[0], heights[0]);
 
-                if (hqScaling)
-                {
-                    // Must be set before "HWAccelInterface::init()" and must 
have "m_textureSize"
-                    maybeSetMipmaps(widget()->devicePixelRatioF());
-                }
-
-                /* Prepare textures, register GL textures */
+                /* Initialize hw accell and prepare GL textures */
                 const bool hasHwAccelError = hwAccelError;
-                hwAccelError = !hwAccellnterface->init(&textures[1]);
+                hwAccelError = !hwAccellnterface->init(widths, heights, 
[this](quint32 texture) {
+                    setTextureParameters(target, texture, GL_LINEAR);
+                    if (hqScaling)
+                        maybeSetMipmaps(widget()->devicePixelRatioF(), 
texture);
+                });
                 if (hwAccelError && !hasHwAccelError)
                     QMPlay2Core.logError("OpenGL 2 :: " + tr("Can't init 
textures for") + " " + hwAccellnterface->name());
 
@@ -525,13 +495,12 @@
                     hwAccelError = true;
                 }
             }
-            hwAccellnterface->unlock();
             if (!imageReady && !hasImage)
                 return;
             for (int p = 0; p < numPlanes; ++p)
             {
                 glActiveTexture(GL_TEXTURE0 + p);
-                glBindTexture(target, textures[p + 1]);
+                glBindTexture(target, hwAccellnterface->getTexture(p));
                 if (m_useMipmaps && imageReady)
                     glGenerateMipmap(target);
             }
@@ -773,15 +742,13 @@
 
 void OpenGL2Common::contextAboutToBeDestroyed()
 {
-    if (hwAccellnterface && hwAccellnterface->lock())
-    {
-        hwAccellnterface->clear(true);
-        hwAccellnterface->unlock();
-    }
+    if (hwAccellnterface)
+        hwAccellnterface->clear();
     deleteSphereVbo();
+    const int texturesToDel = hwAccellnterface ? 0 : numPlanes;
     if (hasPbo)
-        glDeleteBuffers(1 + (hwAccellnterface ? 0 : numPlanes), pbo);
-    glDeleteTextures(numPlanes + 1, textures);
+        glDeleteBuffers(1 + texturesToDel, pbo);
+    glDeleteTextures(texturesToDel + 1, textures);
 }
 
 void OpenGL2Common::testGLInternal()
@@ -847,47 +814,25 @@
 
         if (isOK)
         {
-            quint32 textures[numPlanes];
-            memset(textures, 0, sizeof textures);
-            glGenTextures(numPlanes, textures);
-            if (hwAccellnterface->canInitializeTextures())
-            {
-                for (int p = 0; p < numPlanes; ++p)
-                {
-                    glBindTexture(target, textures[p]);
-                    if (numPlanes == 2)
-                        glTexImage2D(target, 0, !p ? GL_R8 : GL_RG8, 1, 1, 0, 
!p ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, nullptr);
-                    else if (numPlanes == 1)
-                        glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, 
GL_UNSIGNED_BYTE, nullptr);
-                }
-            }
-
-            if (!hwAccellnterface->lock())
+            const QVector<int> sizes(numPlanes * 2, 1);
+            if (!hwAccellnterface->init(&sizes[0], &sizes[numPlanes], 
[](quint32){}))
                 isOK = false;
-            else
+            if (numPlanes == 1) //For RGB32 format, HWAccel should be able to 
adjust the video
             {
-                if (!hwAccellnterface->init(textures))
-                    isOK = false;
-                if (numPlanes == 1) //For RGB32 format, HWAccel should be able 
to adjust the video
-                {
-                    VideoAdjustment videoAdjustmentCap;
-                    hwAccellnterface->getVideAdjustmentCap(videoAdjustmentCap);
-                    if (videoAdjustmentCap.brightness)
-                        videoAdjustmentKeys += "Brightness";
-                    if (videoAdjustmentCap.contrast)
-                        videoAdjustmentKeys += "Contrast";
-                    if (videoAdjustmentCap.saturation)
-                        videoAdjustmentKeys += "Saturation";
-                    if (videoAdjustmentCap.hue)
-                        videoAdjustmentKeys += "Hue";
-                    if (videoAdjustmentCap.sharpness)
-                        videoAdjustmentKeys += "Sharpness";
-                }
-                hwAccellnterface->clear(true);
-                hwAccellnterface->unlock();
+                VideoAdjustment videoAdjustmentCap;
+                hwAccellnterface->getVideAdjustmentCap(videoAdjustmentCap);
+                if (videoAdjustmentCap.brightness)
+                    videoAdjustmentKeys += "Brightness";
+                if (videoAdjustmentCap.contrast)
+                    videoAdjustmentKeys += "Contrast";
+                if (videoAdjustmentCap.saturation)
+                    videoAdjustmentKeys += "Saturation";
+                if (videoAdjustmentCap.hue)
+                    videoAdjustmentKeys += "Hue";
+                if (videoAdjustmentCap.sharpness)
+                    videoAdjustmentKeys += "Sharpness";
             }
-
-            glDeleteTextures(numPlanes, textures);
+            hwAccellnterface->clear();
         }
     }
 
@@ -984,10 +929,10 @@
     }
 }
 
-void OpenGL2Common::maybeSetMipmaps(qreal dpr)
+void OpenGL2Common::maybeSetMipmaps(qreal dpr, quint32 texture)
 {
     const bool lastUseMipmaps = m_useMipmaps;
-    m_useMipmaps = (W * dpr < m_textureSize.width() || H * dpr < 
m_textureSize.height());
+    m_useMipmaps = (W * dpr < m_textureSize.width() / 2.0 || H * dpr < 
m_textureSize.height() / 2.0);
 #ifndef OPENGL_ES2
     if (m_useMipmaps && !glGenerateMipmap)
     {
@@ -995,15 +940,17 @@
         m_useMipmaps = false;
     }
 #endif
-    if (m_useMipmaps != lastUseMipmaps)
+    if (texture || m_useMipmaps != lastUseMipmaps)
     {
-        for (int p = 0; p < numPlanes; ++p)
+        const int n = texture ? 1 : numPlanes;
+        for (int p = 0; p < n; ++p)
         {
-            glBindTexture(target, textures[p + 1]);
+            glBindTexture(target, texture ? texture : (hwAccellnterface ? 
hwAccellnterface->getTexture(p) : textures[p + 1]));
             glTexParameteri(target, GL_TEXTURE_MIN_FILTER, m_useMipmaps ? 
GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
             if (m_useMipmaps)
                 glGenerateMipmap(target);
         }
+        glBindTexture(target, 0);
     }
 }
 
@@ -1012,17 +959,6 @@
     return verticesIdx >= 4 && !sphericalView;
 }
 
-inline bool OpenGL2Common::hwAccellPossibleLock()
-{
-    if (hwAccellnterface && !hwAccellnterface->lock())
-    {
-        QMPlay2Core.logError("OpenGL 2 :: " + hwAccellnterface->name() + " " + 
tr("error"));
-        hwAccelError = true;
-        return false;
-    }
-    return true;
-}
-
 QByteArray OpenGL2Common::readShader(const QString &fileName, bool pure)
 {
     QResource res(fileName);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/modules/OpenGL2/OpenGL2Common.hpp 
new/QMPlay2-src-19.12.04/src/modules/OpenGL2/OpenGL2Common.hpp
--- old/QMPlay2-src-19.11.26/src/modules/OpenGL2/OpenGL2Common.hpp      
2019-11-22 23:37:13.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/modules/OpenGL2/OpenGL2Common.hpp      
2019-12-02 20:42:00.000000000 +0100
@@ -92,6 +92,8 @@
 
     void setSpherical(bool spherical);
 protected:
+    static void setTextureParameters(GLenum target, quint32 texture, GLint 
param);
+
     void initializeGL();
     void paintGL();
 
@@ -119,12 +121,10 @@
 
     void dispatchEvent(QEvent *e, QObject *p);
 private:
-    void maybeSetMipmaps(qreal dpr);
+    void maybeSetMipmaps(qreal dpr, quint32 texture = 0);
 
     inline bool isRotate90() const;
 
-    inline bool hwAccellPossibleLock();
-
     QByteArray readShader(const QString &fileName, bool pure = false);
 
     void mousePress(QMouseEvent *e);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/modules/Playlists/M3U.cpp 
new/QMPlay2-src-19.12.04/src/modules/Playlists/M3U.cpp
--- old/QMPlay2-src-19.11.26/src/modules/Playlists/M3U.cpp      2019-08-23 
23:31:17.000000000 +0200
+++ new/QMPlay2-src-19.12.04/src/modules/Playlists/M3U.cpp      2019-12-02 
20:42:00.000000000 +0100
@@ -47,21 +47,18 @@
             extinf[1] = line.right(line.length() - idx - 1);
             hasExtinf = true;
         }
-        else
+        else if (!line.startsWith("#"))
         {
-            if (!line.startsWith("#"))
+            Entry entry;
+            if (!hasExtinf)
+                entry.name = Functions::fileName(line, false);
+            else
             {
-                Entry entry;
-                if (!hasExtinf)
-                    entry.name = Functions::fileName(line, false);
-                else
-                {
-                    entry.length = extinf[0].toInt();
-                    entry.name = extinf[1].replace('\001', '\n');
-                }
-                entry.url = Functions::Url(line, playlistPath);
-                list += entry;
+                entry.length = extinf[0].toInt();
+                entry.name = extinf[1].replace('\001', '\n');
             }
+            entry.url = Functions::Url(line, playlistPath);
+            list += entry;
             hasExtinf = false;
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/qmplay2/Version.cpp 
new/QMPlay2-src-19.12.04/src/qmplay2/Version.cpp
--- old/QMPlay2-src-19.11.26/src/qmplay2/Version.cpp    2019-11-26 
19:55:17.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/qmplay2/Version.cpp    2019-12-04 
00:32:27.000000000 +0100
@@ -25,7 +25,7 @@
 #ifndef QMPlay2GitHEAD
     #define QMPlay2GitHEAD
 #endif
-#define QMPlay2Version "19.11.26" QMPlay2GitHEAD
+#define QMPlay2Version "19.12.04" QMPlay2GitHEAD
 
 QByteArray Version::get()
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/QMPlay2-src-19.11.26/src/qmplay2/headers/HWAccelInterface.hpp 
new/QMPlay2-src-19.12.04/src/qmplay2/headers/HWAccelInterface.hpp
--- old/QMPlay2-src-19.11.26/src/qmplay2/headers/HWAccelInterface.hpp   
2019-11-13 18:54:48.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/qmplay2/headers/HWAccelInterface.hpp   
2019-12-02 20:42:00.000000000 +0100
@@ -22,6 +22,8 @@
 
 #include <QString>
 
+#include <functional>
+
 class VideoFrame;
 class ImgScaler;
 
@@ -46,6 +48,9 @@
         MapError,
     };
 
+    using SetTextureParamsFn = std::function<void(quint32 texture)>;
+
+public:
     virtual ~HWAccelInterface() = default;
 
     virtual QString name() const = 0;
@@ -60,22 +65,11 @@
         return true;
     }
 
-    virtual bool lock()
-    {
-        return true;
-    }
-    virtual void unlock()
-    {}
-
-    virtual bool canInitializeTextures() const
-    {
-        return true;
-    }
-
-    virtual bool init(quint32 *textures) = 0;
-    virtual void clear(bool contextChange) = 0;
+    virtual bool init(const int *widths, const int *heights, const 
SetTextureParamsFn &setTextureParamsFn) = 0;
+    virtual void clear() = 0;
 
     virtual MapResult mapFrame(const VideoFrame &videoFrame, Field field) = 0;
+    virtual quint32 getTexture(int plane) = 0;
 
     virtual bool getImage(const VideoFrame &videoFrame, void *dest, ImgScaler 
*nv12ToRGB32 = nullptr) = 0;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/QMPlay2-src-19.11.26/src/qmplay2/headers/Module.hpp 
new/QMPlay2-src-19.12.04/src/qmplay2/headers/Module.hpp
--- old/QMPlay2-src-19.11.26/src/qmplay2/headers/Module.hpp     2019-11-22 
23:37:13.000000000 +0100
+++ new/QMPlay2-src-19.12.04/src/qmplay2/headers/Module.hpp     2019-12-02 
20:42:00.000000000 +0100
@@ -135,7 +135,7 @@
 
 /**/
 
-#define QMPLAY2_MODULES_API_VERSION 11
+#define QMPLAY2_MODULES_API_VERSION 12
 
 #define QMPLAY2_EXPORT_MODULE(ModuleClass) \
     extern "C" Q_DECL_EXPORT quint32 getQMPlay2ModuleAPIVersion() \


Reply via email to