mirror of
https://github.com/wang-bin/QtAV.git
synced 2026-10-29 03:26:39 +08:00
Limit buffered packets size when demuxing. Result in less memory usage
TODO: configurable threshold
This commit is contained in:
@@ -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....");
|
||||
}
|
||||
|
||||
@@ -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
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user