Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-103494

QAudioOutput causes hanging, freezing, thread blocking, if not removed and replaced during media positioning/playing/pausing.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • P2: Important
    • None
    • 6.2.0
    • Multimedia
    • None
    • Linux/X11

    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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            kill.animals Kill Animals
            kill.animals Kill Animals
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes