Skip to content

Commit

Permalink
fix some crash issues and can not play issues since b971c51
Browse files Browse the repository at this point in the history
TODO:
the code now is ugly! need to rewrite. e.g. how to manage the threads,
decoders and outputs etc. avthread**? managed by avthread? demux thread?
BUG:
1. sometimes no stopped signal
2. sometimes multiple stopped signal
  • Loading branch information
wang-bin committed Jun 3, 2013
1 parent c442e4c commit 09cb16b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 43 deletions.
18 changes: 14 additions & 4 deletions src/AVDemuxThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,14 @@ void AVDemuxThread::stop()
end = true;
//this will not affect the pause state if we pause the output
//TODO: why remove blockFull(false) can not play another file?
//avthread can stop. do not clear queue, make sure all data are played
if (audio_thread) {
audio_thread->setDemuxEnded(true);
audio_thread->packetQueue()->clear();
audio_thread->packetQueue()->blockFull(false); //??
}
if (video_thread) {
video_thread->setDemuxEnded(true);
video_thread->packetQueue()->clear();
video_thread->packetQueue()->blockFull(false); //?
}
pause(false);
Expand Down Expand Up @@ -325,7 +326,14 @@ void AVDemuxThread::run()
//connect to stop is ok too
if (pkt.isEnd()) {
qDebug("read end packet %d A:%d V:%d", index, audio_stream, video_stream);
stop();
end = true;
//avthread can stop. do not clear queue, make sure all data are played
if (audio_thread) {
audio_thread->setDemuxEnded(true);
}
if (video_thread) {
video_thread->setDemuxEnded(true);
}
}
/*1 is empty but another is enough, then do not block to
ensure the empty one can put packets immediatly.
Expand Down Expand Up @@ -359,8 +367,10 @@ void AVDemuxThread::run()
}
}
//flush. seeking will be omitted when stopped
aqueue->put(Packet());
vqueue->put(Packet());
if (aqueue)
aqueue->put(Packet());
if (vqueue)
vqueue->put(Packet());
qDebug("Demux thread stops running....");
}

Expand Down
77 changes: 38 additions & 39 deletions src/AVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ VideoRenderer *AVPlayer::renderer()

AudioOutput* AVPlayer::setAudioOutput(AudioOutput* ao)
{

//Fill code here
Q_UNUSED(ao);
}

AudioOutput* AVPlayer::audio()
Expand Down Expand Up @@ -358,22 +359,20 @@ bool AVPlayer::load()
audio_thread->setDecoder(audio_dec);
audio_thread->setOutput(_audio);
audio_thread->setStatistics(&mStatistics);
}
qDebug("demux thread setAudioThread");
demuxer_thread->setAudioThread(audio_thread);}
} else {
//releaseAudioResource()
if (audio_thread) {
audio_thread->terminate();
delete audio_thread;
audio_thread = 0;
}
qDebug("demux thread setAudioThread");
//set 0 before delete because demux thread will use the address
//TODO: use avthread** ?
demuxer_thread->setAudioThread(0);
audio_thread = 0; //deleted in demux thread. TODO: better code and logic
if (audio_dec) {
delete audio_dec;
audio_dec = 0;
}
//DO NOT delete AVOutput. it is setted by user
}
qDebug("demux thread setAudioThread");
demuxer_thread->setAudioThread(audio_thread);
if (vCodecCtx) {
if (!video_dec) {
video_dec = new VideoDecoder();
Expand All @@ -384,21 +383,18 @@ bool AVPlayer::load()
video_thread->setClock(clock);
video_thread->setDecoder(video_dec);
video_thread->setVideoCapture(video_capture);
demuxer_thread->setVideoThread(video_thread);
}
setRenderer(_renderer);
} else {
if (video_thread) {
video_thread->terminate();
delete video_thread;
video_thread = 0;
}
if (video_dec) {
demuxer_thread->setVideoThread(0);
video_thread = 0;//deleted in demux thread. TODO: better code and logic
if (video_dec) { //TODO: should the decoder managed by avthread?
delete video_dec;
video_dec = 0;
}
//DO NOT delete AVOutput. it is setted by user
}
demuxer_thread->setVideoThread(video_thread);
//TODO: init statistics
return loaded;
}
Expand Down Expand Up @@ -460,13 +456,32 @@ void AVPlayer::stop()
{
if (!isPlaying())
return;
qDebug("AVPlayer::stop");
if (video_thread)
disconnect(video_thread, SIGNAL(finished()), this, SIGNAL(stopped()));
if (audio_thread)
disconnect(audio_thread, SIGNAL(finished()), this, SIGNAL(stopped()));
qDebug("AVPlayer::stop");
//blockSignals(true); //TODO: move emit stopped() before it. or connect avthread.finished() to tryEmitStop() {if (!called_by_stop) emit}
//TODO: stop demux thread after avthread is better? it will stop avthread internally actually

if (audio_thread) {
disconnect(audio_thread, SIGNAL(finished()), this, SIGNAL(stopped()));
if (audio_thread->isRunning()) {
qDebug("stop a");
audio_thread->stop();
if (!audio_thread->wait(1000)) {
qWarning("Timeout waiting for audio thread stopped. Terminate it.");
audio_thread->terminate();
}
}
}
if (video_thread) {
disconnect(video_thread, SIGNAL(finished()), this, SIGNAL(stopped()));
if (video_thread->isRunning()) {
qDebug("stopv");
video_thread->stop();
if (!video_thread->wait(1000)) {
qWarning("Timeout waiting for video thread stopped. Terminate it.");
video_thread->terminate(); ///if time out
}
}
}
//stop demux thread after avthread is better. otherwise demux thread may be terminated when waiting for avthread ?
if (demuxer_thread->isRunning()) {
qDebug("stop d");
demuxer_thread->stop();
Expand All @@ -476,22 +491,6 @@ void AVPlayer::stop()
demuxer_thread->terminate(); //Terminate() causes the wait condition destroyed without waking up
}
}
if (audio_thread && audio_thread->isRunning()) {
qDebug("stop a");
audio_thread->stop();
if (!audio_thread->wait(1000)) {
qWarning("Timeout waiting for audio thread stopped. Terminate it.");
audio_thread->terminate();
}
}
if (video_thread && video_thread->isRunning()) {
qDebug("stopv");
video_thread->stop();
if (!video_thread->wait(1000)) {
qWarning("Timeout waiting for video thread stopped. Terminate it.");
video_thread->terminate(); ///if time out
}
}
//TODO: why AVThread not trigger the signal?
qDebug("demux thread, avthreads stopped...");
emit stopped();
Expand Down

0 comments on commit 09cb16b

Please sign in to comment.