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() \
