Limit buffered packets size when demuxing. Result in less memory usage

TODO: configurable threshold
This commit is contained in:
wang-bin
2012-11-03 11:21:05 +08:00
parent 755ba40624
commit 9a2c018fe8
7 changed files with 57 additions and 2 deletions
+17
View File
@@ -23,6 +23,8 @@
namespace QtAV {
const int kPktBufferSize = 512;
AVDemuxThread::AVDemuxThread(QObject *parent) :
QThread(parent),end(false),demuxer(0),audio_thread(0),video_thread(0)
{
@@ -48,6 +50,7 @@ void AVDemuxThread::setAudioThread(AVThread *thread)
audio_thread = 0;
}
audio_thread = thread;
audio_thread->setDemuxThread(this);
}
void AVDemuxThread::setVideoThread(AVThread *thread)
@@ -58,6 +61,12 @@ void AVDemuxThread::setVideoThread(AVThread *thread)
video_thread = 0;
}
video_thread = thread;
video_thread->setDemuxThread(this);
}
void AVDemuxThread::readMoreFrames()
{
buffer_cond.wakeAll();
}
void AVDemuxThread::stop()
@@ -81,7 +90,13 @@ void AVDemuxThread::run()
int index = 0;
Packet pkt;
while (!end) {
buffer_mutex.lock();
if (audio_thread->packetQueue()->size() > kPktBufferSize
&& video_thread->packetQueue()->size() > kPktBufferSize) {
buffer_cond.wait(&buffer_mutex);
}
if (!demuxer->readFrame()) {
buffer_mutex.unlock();
continue;
}
index = demuxer->stream();
@@ -93,8 +108,10 @@ void AVDemuxThread::run()
video_thread->packetQueue()->enqueue(pkt);
video_thread->wakeAll(); //need it?
} else { //subtitle
buffer_mutex.unlock();
continue;
}
buffer_mutex.unlock();
}
qDebug("Demux thread stops running....");
}
+10
View File
@@ -46,6 +46,16 @@ void AVThread::wakeAll()
d_ptr->condition.wakeAll();
}
void AVThread::setDemuxThread(AVDemuxThread *thread)
{
d_ptr->demux_thread = thread;
}
AVDemuxThread* AVThread::demuxThread() const
{
return d_ptr->demux_thread;
}
void AVThread::setClock(AVClock *clock)
{
d_ptr->clock = clock;
+7 -1
View File
@@ -22,6 +22,7 @@
#include <QtAV/Packet.h>
#include <QtAV/AudioOutput.h>
#include <QtAV/AVClock.h>
#include <QtAV/AVDemuxThread.h>
#include <QtCore/QCoreApplication>
#ifdef __cplusplus
@@ -35,6 +36,8 @@ extern "C"
namespace QtAV {
const int kAPktBufferMin = 256;
class AudioThreadPrivate : public AVThreadPrivate
{
public:
@@ -52,7 +55,7 @@ void AudioThread::run()
if (!d_ptr->dec || !d_ptr->writer)
return;
Q_ASSERT(d_ptr->clock != 0);
Q_ASSERT(d_ptr->demux_thread != 0);
int sample_rate = d_ptr->dec->codecContext()->sample_rate;
int channels = d_ptr->dec->codecContext()->channels;
int csf = channels * sample_rate * sizeof(float);
@@ -68,6 +71,9 @@ void AudioThread::run()
break;
}
Packet pkt = d_ptr->packets.dequeue();
if (d_ptr->packets.size() < kAPktBufferMin) {
d_ptr->demux_thread->readMoreFrames();
}
d_ptr->clock->updateValue(pkt.pts);
if (d_ptr->dec->decode(pkt.data)) {
QByteArray decoded(d_ptr->dec->data());
+5
View File
@@ -19,7 +19,9 @@
#ifndef QAV_DEMUXTHREAD_H
#define QAV_DEMUXTHREAD_H
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include <QtCore/QWaitCondition>
#include <QtAV/QtAV_Global.h>
namespace QtAV {
@@ -35,6 +37,7 @@ public:
void setDemuxer(AVDemuxer *dmx);
void setAudioThread(AVThread *thread);
void setVideoThread(AVThread *thread);
void readMoreFrames(); //called by AVThread to demux more
public slots:
void stop();
@@ -47,6 +50,8 @@ private:
AVDemuxer *demuxer;
AVThread *audio_thread, *video_thread;
int audio_stream, video_stream;
QMutex buffer_mutex;
QWaitCondition buffer_cond;
};
} //namespace QtAV
+8
View File
@@ -24,10 +24,12 @@
#include <QtAV/Packet.h>
namespace QtAV {
class AVDecoder;
class AVThreadPrivate;
class AVOutput;
class AVClock;
class AVDemuxThread;
class Q_EXPORT AVThread : public QThread
{
Q_OBJECT
@@ -50,6 +52,12 @@ public:
void setOutput(AVOutput *out);
AVOutput* output() const;
private:
friend class AVDemuxThread;
//notify demux thread to read more packets. call it internally when demux thread sets the avthread
void setDemuxThread(AVDemuxThread *thread);
AVDemuxThread* demuxThread() const;
protected:
AVThread(AVThreadPrivate& d, QObject *parent = 0);
+4 -1
View File
@@ -33,10 +33,12 @@ namespace QtAV {
class AVDecoder;
class Packet;
class AVClock;
class AVDemuxThread;
class AVThreadPrivate
{
public:
AVThreadPrivate():stop(false),clock(0),dec(0),writer(0) {}
AVThreadPrivate():stop(false),clock(0),dec(0),writer(0),demux_thread(0){
}
virtual ~AVThreadPrivate() {
/*if (dec) {
delete dec;
@@ -63,6 +65,7 @@ public:
AVOutput *writer;
QMutex mutex;
QWaitCondition condition;
AVDemuxThread *demux_thread; //notify it to read more packets
};
} //namespace QtAV
+6
View File
@@ -20,9 +20,11 @@
#include <private/AVThread_p.h>
#include <QtAV/Packet.h>
#include <QtAV/AVClock.h>
#include <QtAV/AVDemuxThread.h>
namespace QtAV {
const int kVPktBufferMin = 256;
const double kSyncThreshold = 0.005; // 5 ms
class VideoThreadPrivate : public AVThreadPrivate
@@ -49,6 +51,7 @@ void VideoThread::run()
if (!d_ptr->dec || !d_ptr->writer)
return;
Q_ASSERT(d_ptr->clock != 0);
Q_ASSERT(d_ptr->demux_thread != 0);
Q_D(VideoThread);
while (!d_ptr->stop) {
@@ -61,6 +64,9 @@ void VideoThread::run()
break;
}
Packet pkt = d_ptr->packets.dequeue();
if (d_ptr->packets.size() < kVPktBufferMin) {
d_ptr->demux_thread->readMoreFrames();
}
//Compare to the clock
if (pkt.pts <= 0) {
d_ptr->mutex.unlock();