mirror of
https://github.com/wang-bin/QtAV.git
synced 2026-10-28 02:56:45 +08:00
buffer: play audio when video buffer is ready. fix cover display
music with cover has a video stream contains only 1 frame. Then audio buffer should be the primary buffer. TODO: - dynamic change buffer value when playing - change primary buffer if previous primary buffer stream is disabled bug: broken backward seeking rtsp://184.72.239.149/vod/ mp4:BigBuckBunny_115k.mov
This commit is contained in:
+12
-2
@@ -20,6 +20,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "AVDemuxThread.h"
|
||||
#include <limits>
|
||||
#include "QtAV/AVClock.h"
|
||||
#include "QtAV/AVDemuxer.h"
|
||||
#include "QtAV/AVDecoder.h"
|
||||
@@ -399,7 +400,9 @@ void AVDemuxThread::run()
|
||||
qDebug("get av queue a/v thread = %p %p", audio_thread, video_thread);
|
||||
PacketBuffer *aqueue = audio_thread ? audio_thread->packetQueue() : 0;
|
||||
PacketBuffer *vqueue = video_thread ? video_thread->packetQueue() : 0;
|
||||
m_buffer = vqueue ? vqueue : aqueue;
|
||||
// aqueue as a primary buffer: music with/without cover
|
||||
m_buffer = !vqueue || (aqueue && demuxer->hasAttacedPicture()) ? aqueue : vqueue;
|
||||
const int buf2 = aqueue->bufferValue(); // TODO: may be changed by user
|
||||
if (aqueue) {
|
||||
aqueue->clear();
|
||||
aqueue->setBlocking(true);
|
||||
@@ -464,9 +467,16 @@ void AVDemuxThread::run()
|
||||
aqueue->clear();
|
||||
continue;
|
||||
}
|
||||
if (m_buffer != aqueue) {
|
||||
if (m_buffer->isBuffering()) {
|
||||
aqueue->setBufferValue(std::numeric_limits<int>::max());
|
||||
} else {
|
||||
aqueue->setBufferValue(buf2);
|
||||
}
|
||||
}
|
||||
// always block full if no vqueue because empty callback may set false
|
||||
// attached picture is cover for song, 1 frame
|
||||
aqueue->blockFull(!video_thread || !video_thread->isRunning() || !vqueue || (vqueue->isEnough() || demuxer->hasAttacedPicture()));
|
||||
aqueue->blockFull(!video_thread || !video_thread->isRunning() || !vqueue || demuxer->hasAttacedPicture());
|
||||
aqueue->put(pkt); //affect video_thread
|
||||
}
|
||||
} else if (index == demuxer->videoStream()) {
|
||||
|
||||
@@ -404,8 +404,10 @@ bool AVPlayer::Private::setupAudioThread(AVPlayer *player)
|
||||
}
|
||||
athread->setDecoder(adec);
|
||||
player->setAudioOutput(ao);
|
||||
const qreal fps = qMax<qreal>(24.0, statistics.video.frame_rate);
|
||||
int bv = 0.6*fps;
|
||||
// if has video, then audio buffer should not block the video buffer (bufferValue == 1, modified in AVDemuxThread)
|
||||
// TODO: buf if video stream is only a cover picture, audio buffer should be the primary buffer and BufferTime is preferred(call setBufferMode/Value)
|
||||
int bv = statistics.audio.frame_rate > 0 && statistics.audio.frame_rate < 60 ?
|
||||
statistics.audio.frame_rate : 1;
|
||||
if (buffer_mode == BufferTime)
|
||||
bv = 600; //ms
|
||||
else if (buffer_mode == BufferBytes)
|
||||
@@ -484,6 +486,9 @@ bool AVPlayer::Private::setupVideoThread(AVPlayer *player)
|
||||
bv = 600; //ms
|
||||
else if (buffer_mode == BufferBytes)
|
||||
bv = 1024;
|
||||
// no block for music with cover
|
||||
if (demuxer.hasAttacedPicture() || (statistics.video.frames > 0 && statistics.video.frames < bv))
|
||||
bv = qMax<int>(1, statistics.video.frames);
|
||||
vthread->packetQueue()->setBufferMode(buffer_mode);
|
||||
vthread->packetQueue()->setBufferValue(buffer_value < 0 ? bv : buffer_value);
|
||||
initVideoStatistics(demuxer.videoStream());
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
void blockFull(bool block);
|
||||
//TODO:setMinBlock,MaxBlock
|
||||
inline void clear();
|
||||
// TODO: checkEmpty, Enough, Full?
|
||||
inline bool isEmpty() const;
|
||||
inline bool isEnough() const; //size > thres
|
||||
inline bool isFull() const; //size >= cap
|
||||
|
||||
Reference in New Issue
Block a user