QGraphicsVideoItem::nativeSize() is wrong after "waiting for meta data"
-
using recommended method of waiting for meta data for an mp4 file (specifically waiting for mediaStatusChanged -> QMediaPlayer::BufferedMedia, so we can get the dimensions, and also for durationChanged so we can get the duration) causes subsequent "nativeSize()" to be incorrect.
in fact, after awaiting said meta data, if we then wait for nativeSizeChanged(), the size reported is incorrect. a symptom is that the aspect ratio for the media is forevermore reported as 4:3 when the actual ratio is 16:9, so when resizing the view 1: it's the wrong resolution and 2: it has letterbox black bands.
the following looks fine when too tall (cuz aspect ratio favors this orientation):
the following shows terrible letterboxing on top and bottom when too wide, because size is reported as 640x480, even though vid is actually 1280x720):
skipping the "waitForMeta()" call avoids the above mentioned problems.
see the minimal example code. problem occurs on mac, DOES NOT occur on windows using the same code:
https://karaoke.kjams.com/downloads/QVideoScene.zip
run the example, and resize the window to be either too tall or too wide, you'll see the video resizing CORRECTLY, because the native size reported at handleNativeSizeChanged() is correct (a 16:9 aspect ratio, and the right size)
but now uncomment line 200, waitForMeta() which is a technique found if you google the shit out of "how do i get dimensions / duration meta data for a video" and then you'll see that handleNativeSizeChanged() gets the wrong size and a 4:3 aspect ratio.
and the symptom, when you run the app is that the video is lower rez (try substituting a 1920x1080 vid for "test_good.mp4" to see more clearly the problem), and much worse: it has an aspect ratio of 4:3, so always appears letterboxed no matter how you resize the window. looks fine if the window is too tall, but horrible if it is too wide.
i think this is a bug in AVPlayerLayer::setupVideoOutput() where it is trying to get the native size and it gets the wrong size, so it forevermore reports the wrong size
-
the solution is, when waiting for meta, is do not use a
QVideoWidget
as the "buffer" which awaits the size changed message, instead, use aQGraphicsVideoItem
and get itsvideoSurface()
, and await thesurfaceFormatChanged
callback. then it all works as expected.