Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on terminate when switching sources and calling play #501

Closed
wants to merge 1 commit into from

Conversation

yunag
Copy link

@yunag yunag commented Dec 5, 2024

Hi, valbok. I experienced some crashes when switching network sources and calling play. This crash might happen after multiple attempts.

Here is small demo:

#include <QApplication>
#include <QtAVPlayer/qavaudiooutput.h>
#include <QtAVPlayer/qavplayer.h>

#include <QComboBox>
#include <QLoggingCategory>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>

using namespace std::chrono_literals;

int main(int argc, char *argv[]) {
  QLoggingCategory::setFilterRules("qt.QtAVPlayer.debug=true");

  QApplication app(argc, argv);

  QAVPlayer p;

  QComboBox *combo = new QComboBox;
  combo->setMaximumWidth(300);

  combo->addItem("https://s7-webradio.rockantenne.de/alternative/stream/mp3");
  combo->addItem("http://79.120.77.11:8000/punkru");
  combo->addItem("https://live.hunter.fm/rock_high");

  QWidget window;

  QPushButton *playButton = new QPushButton("Play");
  QPushButton *stopButton = new QPushButton("Stop");

  QVBoxLayout layout(&window);
  layout.addWidget(combo);
  layout.addWidget(playButton);
  layout.addWidget(stopButton);

  QAVAudioOutput *audioOutput = nullptr;

  QObject::connect(combo, &QComboBox::currentIndexChanged, &p, [&]() {
    p.stop();

    if (audioOutput) {
      audioOutput->stop();
      audioOutput->deleteLater();
    }

    audioOutput = new QAVAudioOutput(&p);
    audioOutput->setVolume(0.5);

    p.setSource(combo->currentText());
    p.play();

    // audioOutput.setBufferSize(128 * 1024);
    QObject::connect(
        &p, &QAVPlayer::audioFrame, audioOutput,
        [audioOutput](const QAVAudioFrame &frame) { audioOutput->play(frame); },
        Qt::DirectConnection);
  });

  QObject::connect(playButton, &QPushButton::clicked, &p, [&]() { p.play(); });
  QObject::connect(stopButton, &QPushButton::clicked, &p, [&]() { p.stop(); });

  window.show();

  return app.exec();
}

Reproduce:

  1. Switch source and call play()
  2. Repeat first step multiple times

Possible reason:
Functions executing in wrong order. We waiting for futures when we already deallocated some resources that futures might depend on.

If I'm wrong please correct me.

Reproduce:
1. Switch source and call play()
2. Repeat first step

Possible reason:
Functions executing in wrong order. We waiting for futures when we already
deallocated some resources that futures might depend on.
videoPlayFuture.waitForFinished();
audioPlayFuture.waitForFinished();
demuxer.abort(false);

videoFrameRate = 0.0;
videoQueue.clear();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as I remember, first we clear queues and after we wait that threads finished to consume all frames.

@valbok
Copy link
Owner

valbok commented Dec 5, 2024

thanks, got this BT:

QAVPacket::duration (this=0x7fffddbfeef0) at ../../src/QtAVPlayer/qavpacket.cpp:76
76	    auto tb = d->stream.stream()->time_base;
(gdb) bt
#0  QAVPacket::duration() const (this=0x7fffddbfeef0) at ../../src/QtAVPlayer/qavpacket.cpp:76
#1  0x0000555555570dc5 in QAVPacketQueue<QAVFrame>::dequeue() (this=0x5555558b7648) at ../../src/QtAVPlayer/qavpacketqueue_p.h:241
#2  0x000055555556e100 in QAVPacketQueue<QAVFrame>::frontFrame(QAVFrame&) (this=0x5555558b7648, frame=...) at ../../src/QtAVPlayer/qavpacketqueue_p.h:161
#3  0x00005555555636ee in QAVPlayerPrivate::doPlayStep(bool&, double, QAVQueueClock&, QAVPacketQueue<QAVFrame>&, bool&, std::function<void (QAVFrame const&)> const&)
    (this=0x5555558b74d0, master=@0x7fffddbff02d: false, refPts=-1, clock=..., queue=..., sync=@0x7fffddbff02e: true, cb=...) at ../../src/QtAVPlayer/qavplayer.cpp:707
#4  0x0000555555563f42 in QAVPlayerPrivate::doPlayAudio() (this=0x5555558b74d0) at ../../src/QtAVPlayer/qavplayer.cpp:793
#5  0x00005555555766a8 in QtConcurrent::VoidStoredMemberFunctionPointerCall0<void, QAVPlayerPrivate>::runFunctor() (this=0x7fffb825a8c0) at /usr/include/x86_64-linux-gnu/qt5/QtConcurrent/qtconcurrentstoredfunctioncall.h:205
#6  0x000055555556b835 in QtConcurrent::RunFunctionTask<void>::run() (this=0x7fffb825a8c0) at /usr/include/x86_64-linux-gnu/qt5/QtConcurrent/qtconcurrentrunbase.h:136
#7  0x00007ffff46cff92 in  () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#8  0x00007ffff46ccca1 in  () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#9  0x00007ffff3e94ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#10 0x00007ffff3f26850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

@yunag
Copy link
Author

yunag commented Dec 5, 2024

Oh I also got this backtrace and then tried to add some null checks after each crash and it not helped me a lot. Then other type of issues occurred. I thought it was easy peasy but now i realize it's not

@valbok
Copy link
Owner

valbok commented Dec 5, 2024

could you check #503 ?

@yunag
Copy link
Author

yunag commented Dec 5, 2024

I confirm. Everything is working now!

@yunag yunag closed this Dec 5, 2024
@valbok
Copy link
Owner

valbok commented Dec 5, 2024

I confirm. Everything is working now!

thanks, just need to understand why tests failed, maybe would require another fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants