Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt6 porting guidance: QMediaPlayer



  • Quesion 1:
    in qt5 i could call the equivalent of:

    mediaPlayerP->setVideoOutput(const QList<QVideoSink *> &sinks)
    

    this is no longer available, unless enough of us complain, i guess. well here i am.

    my media player app can output to 3 different scenes in 3 different windows. with qt6 it can no longer do that.

    i thought i might be able to derive QVideoSink, and just make a CMultiplexVideoSink out of it, which is an accepted trick to get a QCameraDevice to be capable of sending its output to multiple destinations, but you can't derive from QVideoSink because there are no virtual methods :(

    so that method won't work for media player (also won't work for camera, see my other post on that).

    how am i supposed to do this now?

    Quesion 2:
    if one has a requirement to have a video's dimensions and duration BEFORE playing the video (eg: to create a buffer, resize a window, or to set up a timeline GUI that shows the proper end time), an acceptable method in the past was to "preroll" the video by starting to play it with no visible or audible interface, start it (secretly) playing, spin an event loop waiting for the messages QAbstractVideoSurface::surfaceFormatChanged and QMediaPlayer::durationChanged, and when received, store the data, tear it all down, and THEN present the interface and start playing the video.

    but... there is no surfaceFormatChanged signal in QVideoSink.

    querying metadata still doesn't provide the frame size (dimensions / resolution) either.

    Quesion 3:
    similar to above, when constructing a QGraphicsScene with a QVideoGraphicsItem that was mapped from a QImage (not from a video), then, at the first presentation, one could ask the surface if it were active, and if not, one would have to call surfaceP->start() (do we need to do this any more?) then one would spin a bit on an event loop waiting for handleNativeSizeChanged, so the graphicsItem could know the proper dimensions, so it would not first present with wrong dimensions..

    like this:

    void				CG_Overlay::present(
    	QtAbstractVideoSurface	*surfaceP,
    	const QVideoFrame&	frame)
    {
    	#if _QT6_
    	{
    		QSize		vidSize(surfaceP->videoSize());
    
    		CF_ASSERT(!vidSize.isEmpty());
    	}
    	#else
    	if (!surfaceP->isActive()) {
    		bool			startedB(surfaceP->start(surfaceFormat(frame)));
    		CTimerSince		timer;
    
    		CF_ASSERT(startedB);
    
    		//	wait for dimensions to get got
    		//	so the first presentation has
    		//	correct aspect ratio
    		setHasDimensions(false);
    
    		while (!hasDimensions() && !QtFireTimersUntilExpire(timer)) {}
    	}
    	#endif
    
    	//	if you can't get the CDG image to appear for
    	//	presentation, see comment in CPixels::hqx_blit()
    	#if _QT6_
    		surfaceP->newVideoFrame(frame);
    	#else
    		surfaceP->present(frame);
    	#endif
    }
    

    in the above, QtAbstractVideoSurface is a QVideoSink, and the first assert always fires (vidSize is in fact empty)

    in qt6 there isn't a way to do this :(

    what am i missing?

    -dave


Log in to reply