zaps166 / QMPlay2

QMPlay2 is a video and audio player which can play most formats and codecs.
GNU Lesser General Public License v3.0
853 stars 177 forks source link

VTB failure on OS X 10.9 #610

Closed RJVB closed 1 year ago

RJVB commented 1 year ago

As mentioned in my previous ticket, I have a long-standing fails-to-work issue with VTB in QMPlay2 on my Mac (2011 MPB 8.1 running OS X 10.9.5). This hardware acceleration does work in VLC as far as I can tell, so a priori it's not that my OS is too old (VTB was introduced in 10.8 btw).

I've been trying to trace the origin of the problem but get stuck somewhere on what appears to be a C++ problem...

In FFDecVTP::open():

av_hwdevice_ctx_create(&m_hwDeviceBufferRef, AV_HWDEVICE_TYPE_VIDEOTOOLBOX, nullptr, nullptr, 0)

does not fail. The subsequent operation

vtbOpenGL = make_shared<VTBOpenGL>(m_hwDeviceBufferRef);

also appears to succeed (I get a VTBOpenGL instance with its own, non-null copy of m_hwDeviceBufferRef).

Things go wrong in OpenGLWriter::setHWDecContext(): the dynamic cast from the HWDecContext instance to a OpenGLHWInterop fails. With some trace output:

bool OpenGLWriter::setHWDecContext(const shared_ptr<HWDecContext> &hwDecContext)
{
    auto hwInterop = dynamic_pointer_cast<OpenGLHWInterop>(hwDecContext);
    auto hwInterop2 = dynamic_cast<OpenGLHWInterop*>(hwDecContext.get());
    qWarning() << Q_FUNC_INFO << "hwDecContext" << hwDecContext.get()
        << "hwInterop" << hwInterop.get()
        << "hwInterop2" << (void*)hwInterop2;
    if (hwDecContext && !hwInterop)
        return false;

I get virtual bool OpenGLWriter::setHWDecContext(const shared_ptr<HWDecContext> &) hwDecContext 0x11e4061c8 hwInterop 0x0 hwInterop2 0x0

As far as I can tell this makes little sense: VTBOpenGL inherits OpenGLHWInterop inherits HWDecContext so unless something fishy is going on with the shared_ptr implementation a VTBOpenGL instance passed as a hwDecContext pointer should be dynamic-castable to a OpenGLHWInterop pointer.

Any idea how to figure out what goes wrong and why, here?

How crucial is the use of shared_ptr?

RJVB commented 1 year ago

Probably not surprisingly the dynamic casting does work with any issue in FFDecVTP::open():

bool FFDecVTB::open(StreamInfo &streamInfo)
{
// ...
#ifdef USE_OPENGL
    if (QMPlay2Core.renderer() == QMPlay2CoreClass::Renderer::OpenGL && !vtbOpenGL)
    {
        auto vOGL = new VTBOpenGL(m_hwDeviceBufferRef);
        vtbOpenGL = shared_ptr<VTBOpenGL>(vOGL); //make_shared<VTBOpenGL>(m_hwDeviceBufferRef);
        auto hDC = dynamic_cast<HWDecContext*>(vOGL);
        auto hDCptr = dynamic_pointer_cast<HWDecContext>(vtbOpenGL);
        auto hDC2 = shared_ptr<HWDecContext>(vtbOpenGL);
        auto oGHWI = dynamic_cast<OpenGLHWInterop*>(vOGL);
        auto oGHWIptr = dynamic_pointer_cast<OpenGLHWInterop>(vtbOpenGL);
        auto oGHWIptr2 = dynamic_pointer_cast<OpenGLHWInterop>(hDC2);
        qWarning() << "vOGL" << vOGL << "vtbOpenGL" << vtbOpenGL.get();
        qWarning() << "hDC" << hDC << "hDCptr" << hDCptr.get();
        qWarning() << "oGHWI" << oGHWI << "oGHWIptr" << oGHWIptr.get() << "oGHWIptr2" << oGHWIptr2.get();

prints

[26 May 2023 18:52:05.843] vOGL 0x10d253150 vtbOpenGL 0x10d253150
[26 May 2023 18:52:05.844] hDC 0x10d253150 hDCptr 0x10d253150
[26 May 2023 18:52:05.845] oGHWI 0x10d253150 oGHWIptr 0x10d253150 oGHWIptr2 0x10d253150
[26 May 2023 18:52:05.846] virtual bool OpenGLWriter::setHWDecContext(const shared_ptr<HWDecContext> &) hwDecContext 0x10d253150 hwInterop 0x0 hwInterop2 0x0
zaps166 commented 1 year ago

dynamic_cast might not work across libraries e.g. if symbols are hidden and are not exported or RTTI is disabled. VTBOpenGL is in different library than OpenGLWriter and HWDecContext. What did you modify in QMPlay2? First try to remove -fvisibility=hidden -fvisibility-inlines-hidden from CMake and recompile.

RJVB commented 1 year ago

You probably right and I do make mods. I double-checked though and none of my modifications have anything to do with the way C++ is built. IOW I don't disable RTTI and I don't mess with your visibility settings.

I can exclude shared_ptr now, though - I added a few methods to pass the VTBOpenGL* directly into OpenGLWriter and do the shared_ptr business there. But the dynamic cast already failed before that conversion. This means I can probably also exclude the possibility that this is a libc++ issue.

RJVB commented 1 year ago

I've now added

string(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "-fvisibility-inlines-hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

to src/modules/FFmpeg/CMakeLists.txt and that doesn't make a difference... should I do the same for libqmplay2?

RJVB commented 1 year ago

Well, apparently I should. Now it works...

zaps166 commented 1 year ago

I told you to remove existing -fvisibility=hidden -fvisibility-inlines-hidden, not replace in FFmpeg :sweat_smile:

So what should be done to properly make it working? Could you check which class or classes requires __attribute__((visibility("default"))) to make it work with default CMake settings?

RJVB commented 1 year ago

Replacing with an empty string is removing, no? I know what you told me, but I figured we'd both be more interested in not setting more classes to default visibility that necessary ... and it's indeed enough not to hide then in libFFmpeg and libQMplay2. In fact, I didn't even test if libFFmpeg needs to export everything...

I'll check the attribute thing. Probably only needs to be set for the 3 involved classes at most, no? (Good little "chore" for when my mother in law is there this weekend ;) )

Just so I understand this a bit better: is it libFFmpeg that needs to be able to access normally hidden things from the 2 classes in libQMplay2, the other way round, or both? I would have guessed that the dynamic cast failed only because libFFmpeg didn't export all the required symbols, but apparently I was wrong.

zaps166 commented 1 year ago

Replacing with an empty string is removing, no?

Yes, but in entire software, not in a single library.


I don't understand why it works on Linux, new macOS and Windows :smile:


I'll check the attribute thing.

:+1:

zaps166 commented 1 year ago

Try to add to HWDecContext and OpenGLHWInterop. If still not, try also for VTBOpenGL.

RJVB commented 1 year ago

I don't understand why it works on Linux, new macOS and Windows :smile:

So maybe something related to the C++ runtime (libc++, libstdc++ etc) after all? Your assumption re: visibility made sense though, the runtime can't use information that wasn't emitted by the compiler so indeed, why...

I never understand why anything works on MSWin ;)

zaps166 commented 1 year ago

I never understand why anything works on MSWin ;)

:rofl: Especially with symbols in DLLs - sometimes I don't know what's going on there and trying until it links :sweat_smile:


The two classes in libqmplay2 are header-only, maybe your compiler needs them to have visible attribute anyway... When you'll be able to check it, I'm curious :smile: Tried on macOS 10.13 and no issue there.

RJVB commented 1 year ago

Do you happen to know what clang version is used on 10.13? I'm using clang 9.0 which should be new enough (clang 8 definitely is on Linux).

I do build the compiler chain without RTTI but that shouldn't have any impact on code generated by the compiler.

RJVB commented 1 year ago

Try to add to HWDecContext and OpenGLHWInterop. If still not, try also for VTBOpenGL.

No luck. Besides, HWDecContext already has QMPLAY2SHAREDLIB_EXPORT which is supposed to do the same thing I think.

zaps166 commented 1 year ago

Do you happen to know what clang version is used on 10.13? I'm using clang 9.0 which should be new enough (clang 8 definitely is on Linux).

Apple has their own clang versioning... Some numbers are similar, but it's not the same :angry: It's 10.0.0.10001145 (Xcode 10.1) on my macOS VM.

HWDecContext already has QMPLAY2SHAREDLIB_EXPORT

Where :astonished: ?

RJVB commented 1 year ago

Do you happen to know what clang version is used on 10.13? I'm using clang 9.0 which should be new enough (clang 8 definitely is on Linux).

Apple has their own clang versioning... Some numbers are similar, but it's not the same 😠 It's 10.0.0.10001145 (Xcode 10.1) on my macOS VM.

HWDecContext already has QMPLAY2SHAREDLIB_EXPORT

Where 😲 ?

Sorry, I may need new glasses :-/

zaps166 commented 1 year ago

Sorry, I may need new glasses :-/

Try to change visibility of this again. Otherwise I don't have any idea... Maybe add CMake option to not hide symbols optionally.

Apple has their own clang versioning... Some numbers are similar, but it's not the same :angry: It's 10.0.0.10001145 (Xcode 10.1) on my macOS VM.

The "angry" emoji is for Apple for their stupid versioning, not for you :smile:

which is supposed to do the same thing I think.

Yes, except Windows, because it's more complicated there (dllexport/dllimport - one is specified when you compile library, another when you include it in another library... So complicated :smile: ).

RJVB commented 1 year ago

Tried again, this time really with VTBOpenGL, OpenGLHWInterop and HWDecContext. It's clearly not enough, but yet

> nm --demangle /Applications/MacPorts/Qt5/QMPlay2.app/Contents/MacOS/modules/libFFmpeg.dylib | fgrep VTBOpenGL | fgrep typeinfo
0000000000022610 s typeinfo for VTBOpenGL
0000000000022580 s typeinfo for std::__1::__shared_ptr_emplace<VTBOpenGL, std::__1::allocator<VTBOpenGL> >
000000000001f3bf s typeinfo name for VTBOpenGL
000000000001f368 s typeinfo name for std::__1::__shared_ptr_emplace<VTBOpenGL, std::__1::allocator<VTBOpenGL> >

> nm --demangle /opt/local/lib/libqmplay2.dylib | egrep 'HWDecContext|OpenGLHWInterop' | fgrep typeinfo
0000000000056890 s typeinfo for HWDecContext
00000000000568a0 s typeinfo for OpenGLHWInterop
0000000000056a10 s typeinfo for std::__1::__function::__func<OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1, std::__1::allocator<OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1>, void (unsigned int)>
0000000000056a28 s typeinfo for OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1
000000000004c787 s typeinfo name for HWDecContext
000000000004c775 s typeinfo name for OpenGLHWInterop
000000000004c8b8 s typeinfo name for std::__1::__function::__func<OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1, std::__1::allocator<OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1>, void (unsigned int)>
000000000004c86c s typeinfo name for OpenGLCommon::initialize(std::__1::shared_ptr<OpenGLHWInterop> const&)::$_1
RJVB commented 1 year ago

Grrr, building against libc++ 9.0.1 (and its headers) also doesn't help :(

zaps166 commented 1 year ago

What will happen if you remove -fvisibility=hidden or -fvisibility-inlines-hidden (keep one of them and try)?

RJVB commented 1 year ago

Maybe add CMake option to not hide symbols optionally.

Do you really prefer to not use hidden visibility (export control) at all, instead of only disabling it for the 2 libraries where it's needed to get VideoToolBox acceleration to work?

zaps166 commented 1 year ago

Do you really prefer to not use hidden visibility (export control) at all, instead of only disabling it for the 2 libraries where it's needed to get VideoToolBox acceleration to work

It's a workaround for your compiler. It works elsewhere. Hiding saves some kilobytes only.

zaps166 commented 1 year ago

There are also some calls to dynamic_cast, who knows if it works with hidden symbols to you :grin: Two of them I can replace for qobject_cast, but two others I can't.

RJVB commented 1 year ago

Have you been able to test down to 10.10 (should work given that you require Qt 5.10)?

As said before, this can't really be a problem with my compiler. I use clang 9, but clang 8 on Linux where I do get VAAPI hardware acceleration. I have clang 11 installed too so could try with that to see if I'm wrong...

Either way, you don't have to add hacks for me; I can just apply those myself for my own builds! ;)

BTW, removing just -fvisibility=hidden is enough (just for the 2 libraries, but curiously I need to force a rebuild of the entire tree if I change this compiler option).

Theoretically hidden visibility also (or mostly) speeds up launching the application because the loader has less to do.

zaps166 commented 1 year ago

Have you been able to test down to 10.10 (should work given that you require Qt 5.10)?

I don't have VM with 10.10. Too much things to install everything to build QMPlay2 :sweat_smile:

As said before, this can't really be a problem with my compiler. I use clang 9, but clang 8 on Linux where I do get VAAPI hardware acceleration. I have clang 11 installed too so could try with that to see if I'm wrong...

Maybe some global config you have? Btw. you can use static_pointer_cast instead. dynamic_pointer_cast it's just a guard. Can you try with hidden visibility? If VTB will work, try to do a screenshot in QMPlay2 (Atl+S) - there's another dynamic_pointer_cast for this with HW accell :smile:

RJVB commented 1 year ago

Maybe some global config you have?

Of the toolchain? Maybe, but what ...

Btw. you can use static_pointer_cast instead. dynamic_pointer_cast it's just a guard.

In OpenGLWriter::setHWDecContext()?

zaps166 commented 1 year ago

In OpenGLWriter::setHWDecContext()?

Yes

Of the toolchain? Maybe, but what ...

Idk :smile:

RJVB commented 1 year ago

Well I be ... static_pointer_cast does the trick too...

And Alt+S gives me "Cannot create screenshot" so I guess the fix has to be applied elsewhere too?

zaps166 commented 1 year ago

It's here: void VideoThr::screenshot(Frame videoFrame), but if you use Vulkan, it'll crash with static_pointer_cast (you don't use Vulkan on macOS).

RJVB commented 1 year ago

hmmm, Vulkan cannot be used at all on Mac (not even on newer ones with the Metal framework)?

zaps166 commented 1 year ago

https://github.com/KhronosGroup/MoltenVK

RJVB commented 1 year ago

Yeah, that (uses the Metal framework underneath).

So the question is, do we use a compile-time conditional or a runtime one, to decide wether to use static_pointer_cast or dynamic_pointer_cast?

zaps166 commented 1 year ago

It works fine to me for compute shaders, but not tried it in QMPlay2 yet.

zaps166 commented 1 year ago

So the question is, do we use a compile-time conditional or a runtime one, to decide wether to use static_pointer_cast or dynamic_pointer_cast?

If dynamic_pointer_cast fails, use static_pointer_cast and crash :grinning:

I don't know what do you mean, if old mac - use static cast?

zaps166 commented 1 year ago

For curiosity - can you check if const bool self = dynamic_cast<MediaBrowser *>(QMPlay2Ext); and if (dynamic_cast<YouTube *>(QMPlay2Ext)) are working?

zaps166 commented 1 year ago

If you have problems with visibility-hidden - better to disable for entire software. Who knows what else will not work or will work differently than expected?

RJVB commented 1 year ago

I don't know what do you mean, if old mac - use static cast?

For curiosity - can you check if const bool self = dynamic_cast<MediaBrowser >(QMPlay2Ext); and if (dynamic_cast<YouTube >(QMPlay2Ext)) are working?

Where should I do that?

zaps166 commented 1 year ago

Where should I do that?

Find occurrences (grep on entire source) and put qDebug and compare with and without visibility. Two places in code. It's on playlist context menu -> Extensions. Can't tell exactly, on phone now.

RJVB commented 1 year ago

For curiosity - can you check if const bool self = dynamic_cast<MediaBrowser *>(QMPlay2Ext); and if (dynamic_cast<YouTube *>(QMPlay2Ext)) are working?

I haven't yet gotten the MediaBrowser trace to output anything but the YouTube dyncast clearly doesn't work with hidden visibility.

I'm going to check if CMAKE_CXX_VISIBILITY_PRESET has any interest.

RJVB commented 1 year ago

I haven't yet gotten the MediaBrowser trace to output anything but the YouTube dyncast clearly doesn't work with hidden visibility.

Correction, apparently the result can be NULL and is so most of the time, so I completely missed the fact that I did get 2 successful dyncasts with hidden visibility too.

The CMAKE_CXX_VISIBILITY_PRESET variable does do what it promises to do, btw. So I now have:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1429fdebe650cfdabb41cff2a543a9383c109019..f543b9eb7344299944df1d61323fcc9d87ac6360 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -307,6 +307,9 @@ if(USE_GIT_VERSION)
 endif()
 add_feature_info("Git version" QMPLAY2_GIT_HEAD "Append Git HEAD to QMPlay2 version")

+option(USE_HIDDEN_VISIBILITY "Use selective export control in shared libraries" ON)
+add_feature_info(VISIBILITY USE_HIDDEN_VISIBILITY "Use selective export control in shared libraries")
+
 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") # GCC or Clang
     option(USE_LINK_TIME_OPTIMIZATION "Enable link time optimization for release builds" OFF)
     add_feature_info("Link Time Optimization" USE_LINK_TIME_OPTIMIZATION "Enable link time optimization for release builds")
@@ -329,9 +332,19 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"
     endif()

     # Hide symbols, and also make sure that debugging symbols are disabled
-    set(CMAKE_CXX_FLAGS_RELEASE    "${RELEASE_DEBUG_FLAG} -fvisibility=hidden -fvisibility-inlines-hidden ${CMAKE_CXX_FLAGS_RELEASE}")
-    set(CMAKE_CXX_FLAGS_MINSIZEREL "${RELEASE_DEBUG_FLAG} -fvisibility=hidden -fvisibility-inlines-hidden ${CMAKE_CXX_FLAGS_MINSIZEREL}")
+    if(USE_HIDDEN_VISIBILITY)
+        set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+    else()
+        # be sure to reset these so code can be rebuilt without the option
+        set(CMAKE_CXX_VISIBILITY_PRESET default)
+    endif()
+    # this one can always be enabled:
+    set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+    set(CMAKE_CXX_FLAGS            "${CMAKE_CXX_FLAGS}")
+    set(CMAKE_CXX_FLAGS_RELEASE    "${RELEASE_DEBUG_FLAG} ${CMAKE_CXX_FLAGS_RELEASE}")
+    set(CMAKE_CXX_FLAGS_MINSIZEREL "${RELEASE_DEBUG_FLAG} ${CMAKE_CXX_FLAGS_MINSIZEREL}")
     if(NOT USE_VULKAN)
+        set(CMAKE_CXX_FLAGS            "-fno-exceptions ${CMAKE_CXX_FLAGS}")
         set(CMAKE_CXX_FLAGS_RELEASE    "-fno-exceptions ${CMAKE_CXX_FLAGS_RELEASE}")
         set(CMAKE_CXX_FLAGS_MINSIZEREL "-fno-exceptions ${CMAKE_CXX_FLAGS_MINSIZEREL}")
     endif()
@@ -351,8 +364,9 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"
     endif()

     if(USE_LINK_TIME_OPTIMIZATION)
+        set(CMAKE_CXX_FLAGS            "-flto ${CMAKE_CXX_FLAGS}")
         set(CMAKE_CXX_FLAGS_RELEASE    "-flto ${CMAKE_CXX_FLAGS_RELEASE}")
-        set(CMAKE_CXX_FLAGS_MINSIZEREL "-flto ${CMAKE_CXX_FLAGS_RELEASE}")
+        set(CMAKE_CXX_FLAGS_MINSIZEREL "-flto ${CMAKE_CXX_FLAGS_MINSIZEREL}")
     endif()

     if(CMAKE_MODULE_LINKER_FLAGS)

(That's my full mod of the relevant bit of the CMake file; I use a custom CMAKE_BUILD_TYPE so I (and the project) have complete control over the flags that get passed to the compiler.)

RJVB commented 1 year ago

Did you test playback of VP9 videos with VideoToolBox acceleration? These videos cause a "trace/bpt" trap after printing Failed to initialize decoder for 1280x714 @ 0

I notice that at least with my Linux,FFmpeg,Mesa combination these same videos are played with regular Vulkan, not Vulkan/VAAPI.

RJVB commented 1 year ago

For that VP9 issue:

diff --git a/src/modules/FFmpeg/FFDecVTB.cpp b/src/modules/FFmpeg/FFDecVTB.cpp
index 74838792da90ec42b95d4facaf67364ab6fccbc5..1f48643c78757516602c4f4b23b015112fde05eb 100644
--- a/src/modules/FFmpeg/FFDecVTB.cpp
+++ b/src/modules/FFmpeg/FFDecVTB.cpp
@@ -77,3 +77,12 @@ bool FFDecVTB::open(StreamInfo &streamInfo)
         return false;
-
+    if (streamInfo.params->codec_id == AV_CODEC_ID_VP9)
+    {
+#if __has_builtin(__builtin_available)
+        if (! __builtin_available(macOS 10.15, *))
+#endif
+        {
+            qWarning() << "VP9 not supported by VTB";
+            return false;
+        }
+    }
     const AVPixelFormat pix_fmt = streamInfo.pixelFormat();
zaps166 commented 1 year ago

Correction, apparently the result can be NULL and is so most of the time, so I completely missed the fact that I did get 2 successful dyncasts with hidden visibility too.

Nice, so some dynamic casts works with hidden symbols on your system!


Did you test playback of VP9 videos with VideoToolBox acceleration?

Yes, it worked without problems, also yuv420p10!

These videos cause a "trace/bpt" trap after printing Failed to initialize decoder for 1280x714 @ 0

Strange, FFmpeg bug?

I notice that at least with my Linux,FFmpeg,Mesa combination these same videos are played with regular Vulkan, not Vulkan/VAAPI.

I don't think your hardware supports VP9. Check vainfo tool.

RJVB commented 1 year ago

These videos cause a "trace/bpt" trap after printing Failed to initialize decoder for 1280x714 @ 0

Strange, FFmpeg bug?

No idea, or QMPlay2 assumes that VTB always supports VP9 decoding. Which it doesn't. I haven't really been able to pinpoint exactly when that support was added and what hardware is required. I've copied a patch that makes a hopefully reasonably safe assumption about when support should be available and falls back to CPU decoding otherwise.

FWIW I notice that even on my lowly Linux N3150 system CPU decoding is actually faster than using the GPU on the same chip. For 720p videos, that is.

I don't think your hardware supports VP9. Check vainfo tool.

I'll need to update vainfo (after figuring out where the source hides nowadays). libva and the intel-vaapi-driver are among the things I've been keeping up-to-date better than the system itself ^^ From what I've been able to see there should be some hardware support for VP9 in an N3150 but it's quite possible that I'm just getting lost in the pretty names.

On a related note: I saw ffmpeg can use OpenCL for hw acceleration. Not of much (or any, in fact) use on my systems but have you considered exposing the option in QMPlay2?

zaps166 commented 1 year ago

On a related note: I saw ffmpeg can use OpenCL for hw acceleration. Not of much (or any, in fact) use on my systems but have you considered exposing the option in QMPlay2?

I guess FFmpeg uses it for filters, not for decoding video. GPU isn't decoding video itself, it has separate chip for this which supports only some codecs. Anyway OpenCL is a horrible idea. Vulkan compute shaders can be better.

FWIW I notice that even on my lowly Linux N3150 system CPU decoding is actually faster than using the GPU on the same chip. For 720p videos, that is.

It can happen. My Ryzen 7950X is decoding faster than Radeon RX 6900XT :sweat_smile: E.g. Ryzen can smoothly decode 8k 60 FPS VP9 video, Radeon can't :rofl: Moreover when I put everything to powersave mode, watt meter shows less wattage when I decode simple videos on CPU than on GPU. It depends on hardware which decoder is better (CPU or GPU).

some hardware support for VP9 in an N3150

VP8 only

QMPlay2 assumes that VTB always supports VP9 decoding

QMPlay2 can check it additionally, but FFmpeg must do it without a crash. Are you sure your FFmpeg compilation is up-to-date and correct?

zaps166 commented 1 year ago

It depends on hardware which decoder is better (CPU or GPU).

Some videos can't decode in parallel on CPU (idk why), in this case hardware decoder is the only option (e.g. HEVC 4k 60FPS videos from mobile phones).

RJVB commented 1 year ago

QMPlay2 can check it additionally, but FFmpeg must do it without a crash. Are you sure your FFmpeg compilation is up-to-date and correct?

The crash isn't in FFmpeg itself. When I ask FFmpeg to decode a VP9 video with VTB accel it tells me it can't. I'm using FFmpeg 4.4.4, haven't upgraded to v6 yet.

There are already a few checks for unsupported content in FFDecVTB; I suppose you didn't put them there for nothing.

RJVB commented 1 year ago

Some videos can't decode in parallel on CPU (idk why), in this case hardware decoder is the only option (e.g. HEVC 4k 60FPS videos from mobile phones).

Well, for playback decoding all that matters anyway is if you can do it at the video's framerate. I'm glad we got VTB to work for me because that old i7 runs hot very easily and the fans can get quite noisy when that happens.

zaps166 commented 1 year ago

The crash isn't in FFmpeg itself. When I ask FFmpeg to decode a VP9 video with VTB accel it tells me it can't. I'm using FFmpeg 4.4.4, haven't upgraded to v6 yet.

What "trace/bpt" trap means?

RJVB commented 1 year ago

What "trace/bpt" trap means?

I suppose it corresponds to "SIGTRAP" but the only thing I know about that one is that it is a "trace trap" which isn't reset when caught...

zaps166 commented 1 year ago

I'll keep it as is, I can't easily test macOS VTB especially with older hardware. Your system is obsolete and very custom, it might cause some issues, too :smile: