Skip to content

Commit

Permalink
use frame pts for ao and fix pts update
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Feb 6, 2016
1 parent b24cb56 commit ead419a
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 11 deletions.
11 changes: 5 additions & 6 deletions src/AudioThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 294,7 @@ void AudioThread::run()
}
// reduce here to ensure to decode the rest data in the next loop
if (!pkt.isEOF())
pkt.data = QByteArray::fromRawData(pkt.data.constData() pkt.data.size() - dec->undecodedSize(), dec->undecodedSize());
pkt.skip(pkt.data.size() - dec->undecodedSize());
#if USE_AUDIO_FRAME
AudioFrame frame(dec->frame());
if (!frame)
Expand Down Expand Up @@ -341,14 341,10 @@ void AudioThread::run()
const int chunk = qMin(decodedSize, has_ao ? ao->bufferSize() : 1024*4);//int(max_len*byte_rate));
//AudioFormat.bytesForDuration
const qreal chunk_delay = (qreal)chunk/(qreal)byte_rate;
pts = chunk_delay;
pkt.pts = chunk_delay; // packet not fully decoded, use new pts in the next decoding
pkt.dts = chunk_delay;
if (has_ao && ao->isOpen()) {
QByteArray decodedChunk = QByteArray::fromRawData(decoded.constData() decodedPos, chunk);
//qDebug("ao.timestamp: %.3f, pts: %.3f, pktpts: %.3f", ao->timestamp(), pts, pkt.pts);

ao->play(decodedChunk, pkt.pts); //FIXME: why frame.timestamp() is wrong? i.e. Packet.asAVPacket()->pts is wrong in decoder
ao->play(decodedChunk, pts);
if (!is_external_clock && ao->timestamp() > 0) {//TODO: clear ao buffer
// const qreal da = qAbs(pts - ao->timestamp());
// if (da > 1.0) { // what if frame duration is long?
Expand All @@ -368,6 364,9 @@ void AudioThread::run()
}
decodedPos = chunk;
decodedSize -= chunk;
pts = chunk_delay;
pkt.pts = chunk_delay; // packet not fully decoded, use new pts in the next decoding
pkt.dts = chunk_delay;
}
if (has_ao)
emit frameDelivered();
Expand Down
32 changes: 29 additions & 3 deletions src/Packet.cpp
Original file line number Diff line number Diff line change
@@ -1,6 1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand All @@ -24,7 24,7 @@
#include "utils/Logger.h"

//ffmpeg2.1 libav10
#define AVPACKET_REF AV_MODULE_CHECK(LIBAVCODEC, 55, 34, 1 ,39, 101)
#define AVPACKET_REF AV_MODULE_CHECK(LIBAVCODEC, 55, 34, 1, 39, 101)

namespace QtAV {
namespace {
Expand Down Expand Up @@ -114,7 114,6 @@ bool Packet::fromAVPacket(Packet* pkt, const AVPacket *avpkt, double time_base)
pkt->pts = qMax<qreal>(0, pkt->pts);
pkt->dts = qMax<qreal>(0, pkt->dts);


// subtitle always has a key frame? convergence_duration may be 0
if (avpkt->convergence_duration > 0 // mpv demux_lavf only check this
&& pkt->hasKeyFrame
Expand Down Expand Up @@ -239,4 238,31 @@ const AVPacket *Packet::asAVPacket() const
}
return p;
}

void Packet::skip(int bytes)
{
if (!d.constData()) { //not constructed from AVPacket
d = QSharedDataPointer<PacketPrivate>(new PacketPrivate());
}
d->initialized = false;
data = QByteArray::fromRawData(data.constData() bytes, data.size() - bytes);
if (position >= 0)
position = bytes;
// TODO: if duration is valid, compute pts/dts and no manually update outside?
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const Packet &pkt)
{
dbg.nospace() << "QtAV::Packet.data " << hex << (qptrdiff)pkt.data.constData() << " " << dec << pkt.data.size();
dbg.nospace() << ", dts: " << pkt.dts;
dbg.nospace() << ", pts: " << pkt.pts;
dbg.nospace() << ", duration: " << pkt.duration;
dbg.nospace() << ", position: " << pkt.position;
dbg.nospace() << ", hasKeyFrame: " << pkt.hasKeyFrame;
dbg.nospace() << ", isCorrupt: " << pkt.isCorrupt;
dbg.nospace() << ", eof: " << pkt.isEOF();
return dbg.space();
}
#endif //QT_NO_DEBUG_STREAM
} //namespace QtAV
11 changes: 10 additions & 1 deletion src/QtAV/Packet.h
Original file line number Diff line number Diff line change
@@ -1,6 1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -55,6 55,12 @@ class Q_AV_EXPORT Packet
* Packet takes the owner ship. time unit is always ms even constructed from AVPacket.
*/
const AVPacket* asAVPacket() const;
/*!
* \brief skip
* Skip bytes of packet data. User has to update pts, dts etc to new values.
* Useful for asAVPakcet(). When asAVPakcet() is called, AVPacket->pts/dts will be updated to new values.
*/
void skip(int bytes);

bool hasKeyFrame;
bool isCorrupt;
Expand All @@ -75,6 81,9 @@ bool Packet::isValid() const
return !isCorrupt && !data.isEmpty() && pts >= 0 && duration >= 0; //!data.isEmpty()?
}

#ifndef QT_NO_DEBUG_STREAM
Q_AV_EXPORT QDebug operator<<(QDebug debug, const Packet &pkt);
#endif
} //namespace QtAV
Q_DECLARE_METATYPE(QtAV::Packet)
#endif // QAV_PACKET_H
2 changes: 1 addition & 1 deletion src/VideoThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 526,7 @@ void VideoThread::run()
}
// reduce here to ensure to decode the rest data in the next loop
if (!pkt.isEOF())
pkt.data = QByteArray::fromRawData(pkt.data.constData() pkt.data.size() - dec->undecodedSize(), dec->undecodedSize());
pkt.skip(pkt.data.size() - dec->undecodedSize());
VideoFrame frame = dec->frame();
if (!frame.isValid()) {
qWarning("invalid video frame from decoder. undecoded data size: %d", pkt.data.size());
Expand Down

0 comments on commit ead419a

Please sign in to comment.