Skip to content

Commit

Permalink
add AVPlayer.bufferSpeed
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Dec 31, 2015
1 parent 81a6272 commit 575e0db
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 10 deletions.
23 changes: 17 additions & 6 deletions examples/player/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void MainWindow::setupUi()
{
QVBoxLayout *mainLayout = new QVBoxLayout();
mainLayout->setSpacing(0);
mainLayout->setMargin(0);
mainLayout->setContentsMargins(QMargins());
setLayout(mainLayout);

mpPlayerLayout = new QVBoxLayout();
Expand All @@ -225,18 +225,18 @@ void MainWindow::setupUi()
mpTimeSlider->setMinimum(0);
mpCurrent = new QLabel(mpControl);
mpCurrent->setToolTip(tr("Current time"));
mpCurrent->setMargin(2);
mpCurrent->setContentsMargins(QMargins(2, 2, 2, 2));
mpCurrent->setText(QString::fromLatin1("00:00:00"));
mpEnd = new QLabel(mpControl);
mpEnd->setToolTip(tr("Duration"));
mpEnd->setMargin(2);
mpEnd->setContentsMargins(QMargins(2, 2, 2, 2));
mpEnd->setText(QString::fromLatin1("00:00:00"));
mpTitle = new QLabel(mpControl);
mpTitle->setToolTip(tr("Render engine"));
mpTitle->setText(QString::fromLatin1("QPainter"));
mpTitle->setIndent(8);
mpSpeed = new QLabel(QString::fromLatin1("1.00"));
mpSpeed->setMargin(1);
mpSpeed->setContentsMargins(QMargins(1, 1, 1, 1));
mpSpeed->setToolTip(tr("Speed. Ctrl+Up/Down"));

mpPlayPauseBtn = new QToolButton(mpControl);
Expand Down Expand Up @@ -509,7 +509,7 @@ void MainWindow::setupUi()

QHBoxLayout *controlLayout = new QHBoxLayout();
controlLayout->setSpacing(0);
controlLayout->setMargin(1);
controlLayout->setContentsMargins(QMargins(1, 1, 1, 1));
mpControl->setLayout(controlLayout);
controlLayout->addWidget(mpCurrent);
controlLayout->addWidget(mpTitle);
Expand Down Expand Up @@ -940,6 +940,7 @@ void MainWindow::onPositionChange(qint64 pos)
if (mpPlayer->isSeekable())
mpTimeSlider->setValue(pos);
mpCurrent->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss")));
//setWindowTitle(QString::number(mpPlayer->statistics().video_only.currentDisplayFPS(), 'f', 2).append(" ").append(mTitle));
}

void MainWindow::repeatAChanged(const QTime& t)
Expand Down Expand Up @@ -1323,7 +1324,17 @@ void MainWindow::onMediaStatusChanged()

void MainWindow::onBufferProgress(qreal percent)
{
setWindowTitle(QString::fromLatin1("Buffering... %1% ").arg(percent*100.0, 0, 'f', 1) + mTitle);
const qreal bs = mpPlayer->bufferSpeed();
QString s;
if (bs > 1024*1024*1024)
s = QString("%1G/s").arg(bs/1024.0/1024.0/1024.0, 5, 'f', 1);
else if (bs > 1024*1024)
s = QString("%1M/s").arg(bs/1024.0/1024.0, 5, 'f', 1);
else if (bs > 1024)
s = QString("%1K/s").arg(bs/1024.0, 5, 'f', 1);
else
s = QString("%1B/s").arg(bs, 5, 'f', 1);
setWindowTitle(QString::fromLatin1("Buffering... %1% @%2 ").arg(percent*100.0, 5, 'f', 1).arg(s) + mTitle);
}

void MainWindow::onVideoEQEngineChanged()
Expand Down
6 changes: 6 additions & 0 deletions src/AVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,12 @@ qreal AVPlayer::bufferProgress() const
return buf ? buf->bufferProgress() : 0;
}

qreal AVPlayer::bufferSpeed() const
{
const PacketBuffer* buf = d->read_thread->buffer();
return buf ? buf->bufferSpeedInBytes() : 0;
}

qint64 AVPlayer::buffered() const
{
const PacketBuffer* buf = d->read_thread->buffer();
Expand Down
41 changes: 39 additions & 2 deletions src/PacketBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@
******************************************************************************/

#include "PacketBuffer.h"
#include <QtCore/QDateTime>

namespace QtAV {

static const int kAvgSize = 16;
PacketBuffer::PacketBuffer()
: m_mode(BufferTime)
, m_buffering(true) // in buffering state at the beginning
, m_max(1.5)
, m_buffer(0)
, m_value0(0)
, m_value1(0)
, m_history(kAvgSize)
{
}

Expand Down Expand Up @@ -97,6 +99,16 @@ qreal PacketBuffer::bufferProgress() const
return qMax<qreal>(qMin<qreal>(p, 1.0), 0.0);
}

qreal PacketBuffer::bufferSpeed() const
{
return calc_speed(false);
}

qreal PacketBuffer::bufferSpeedInBytes() const
{
return calc_speed(true);
}

bool PacketBuffer::checkEnough() const
{
return buffered() >= bufferValue();
Expand All @@ -119,12 +131,22 @@ void PacketBuffer::onPut(const Packet &p)
} else {
m_value1++;
}
// TODO: compute buffer speed (and auto set the best bufferValue)
if (!m_buffering)
return;
if (checkEnough()) {
m_buffering = false;
}
if (!m_buffering) { //buffering=>buffered
m_history = ring<BufferInfo>(kAvgSize);
return;
}
BufferInfo bi;
bi.bytes = p.data.size();
if (!m_history.empty())
bi.bytes += m_history.back().bytes;
bi.v = m_value1;
bi.t = QDateTime::currentMSecsSinceEpoch();
m_history.push_back(bi);
}

void PacketBuffer::onTake(const Packet &p)
Expand All @@ -149,4 +171,19 @@ void PacketBuffer::onTake(const Packet &p)
}
}

qreal PacketBuffer::calc_speed(bool use_bytes) const
{
if (m_history.empty())
return 0;
const qreal dt = (double)QDateTime::currentMSecsSinceEpoch()/1000.0 - m_history.front().t/1000.0;
// dt should be always > 0 because history stores absolute time
if (qFuzzyIsNull(dt))
return 0;
const qint64 delta = use_bytes ? m_history.back().bytes - m_history.front().bytes : m_history.back().v - m_history.front().v;
if (delta < 0) {
qWarning("PacketBuffer internal error. delta(bytes %d): %lld", use_bytes, delta);
return 0;
}
return (qreal)delta/dt;
}
} //namespace QtAV
16 changes: 15 additions & 1 deletion src/PacketBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QtAV/Packet.h>
#include "QtAV/CommonTypes.h"
#include "utils/BlockingQueue.h"
#include "utils/ring.h"

namespace QtAV {

Expand Down Expand Up @@ -70,8 +71,13 @@ class PacketBuffer : public BlockingQueue<Packet, QQueue>
* \return Percent of buffered time, bytes or packets.
*/
qreal bufferProgress() const;
/*!
* \brief bufferSpeed
* Depending on BufferMode, the result is delta_pts/s, packets/s or bytes/s
* \return
*/
qreal bufferSpeed() const;

qreal bufferSpeedInBytes() const;
protected:
bool checkEnough() const Q_DECL_OVERRIDE;
bool checkFull() const Q_DECL_OVERRIDE;
Expand All @@ -85,12 +91,20 @@ class PacketBuffer : public BlockingQueue<Packet, QQueue>
using PQ::threshold;

private:
qreal calc_speed(bool use_bytes) const;

BufferMode m_mode;
bool m_buffering;
qreal m_max;
// bytes or count
qint64 m_buffer;
qint64 m_value0, m_value1;
typedef struct {
qint64 v; //pts, total packes or total bytes
qint64 bytes; //total bytes
qint64 t;
} BufferInfo;
ring<BufferInfo> m_history;
};

} //namespace QtAV
Expand Down
12 changes: 11 additions & 1 deletion src/QtAV/AVPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ class Q_AV_EXPORT AVPlayer : public QObject
explicit AVPlayer(QObject *parent = 0);
~AVPlayer();

//NOT const. This is the only way to access the clock.
/*!
* \brief masterClock
* setClockType() should call when playback started.
* \return
*/
AVClock* masterClock();
// If path is different from previous one, the stream to play will be reset to default.
/*!
Expand Down Expand Up @@ -449,6 +453,12 @@ public slots:
* Playback can start or resume only when the buffer is entirely filled.
*/
qreal bufferProgress() const;
/*!
* \brief bufferSpeed
* Bytes/s
* \return 0 if not buffering. >= 0 if buffering
*/
qreal bufferSpeed() const;
/*!
* \brief buffered
* Current buffered value in msecs, bytes or packet count depending on bufferMode()
Expand Down

0 comments on commit 575e0db

Please sign in to comment.