Details
-
Bug
-
Resolution: Incomplete
-
P2: Important
-
None
-
6.2.0
-
None
Description
To reproduce the bug:
QMediaPlayer *player = new QMediaPlayer; QUrl source = QUrl::fromLocalFile( "file:///home/anon/Production/Internet.mp4" ); player->setSource(source); QVideoWidget *videoWidget = new QVideoWidget; QAudioOutput *audioOutput = new QAudioOutput; player->setVideoOutput(videoWidget); player->setAudioOutput(audioOutput); videoWidget->show(); player->play(); forever { ct_Delay( 3, player->position() ); // This is just a timer delay for 3 seconds player->setPosition( player->position() + 6000 ); }
Backstory:
I had developed a basic video player for my Qt application and it was working great for over a year. Around half a year ago, either due to an update to gstreamer or switching to Qt6, it started freezing, segfaulting, hanging after exactly 5 skips.
Tracing a crash never led to anything solid so I just left it, and there were no obvious GStreamer regressions that I could find in my search. It persisted for months so I took another stab at trying to "workaround" the bug and my ugly solution here more or less did the trick:
void QVideoWidgetPlayer::setPosition( const int n ) { // Yes this is a retarded function // If the audio not reset, gstreamer freezes after about 5 skips m_Mutex.lock(); bool isPlaying = m_MediaPlayer.playbackState() == 1; if ( isPlaying ) { m_MediaPlayer.pause(); } QAudioOutput *ao = m_MediaPlayer.audioOutput(); // For deleting m_MediaPlayer.setAudioOutput(nullptr); // The video positioning almost never tracks to the proper portion, so I have to call the function multiple times for ( int i = 0; m_MediaPlayer.position() != n && i < 5; i++ ) { m_MediaPlayer.setPosition(n); ct_Delay( 0.1, m_MediaPlayer.position() ); if ( m_MediaPlayer.position() > n - 5000 ) { break; } // close enough } m_MediaPlayer.setAudioOutput( m_AudioOutput ); // I have an object pre-created to reduce initialization speed m_AudioOutput = new QAudioOutput; if ( ao != nullptr ) { delete ao; } ao = nullptr; ct_Delay( 0.1, m_MediaPlayer.position() ); if ( isPlaying ) { m_MediaPlayer.pause(); ct_Delay( 0.1, m_MediaPlayer.position() ); m_MediaPlayer.play(); } m_Mutex.unlock(); }
^ The positioning is increbly slow and annoying to deal with whenever the audio is involved. I am tempted to at this point to just run the audio and video as seperate processes. However, at least it does not freeze anymore.
If no audio ouptut is set, the video tracking handles very well and this function is not needed.