Skip to content

Commit

Permalink
buffer: play audio when video buffer is ready. fix cover display
Browse files Browse the repository at this point in the history
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
  • Loading branch information
wang-bin committed Mar 24, 2015
1 parent 8c59182 commit 20bf0d6
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
14 changes: 12 additions & 2 deletions src/AVDemuxThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 20,7 @@
******************************************************************************/

#include "AVDemuxThread.h"
#include <limits>
#include "QtAV/AVClock.h"
#include "QtAV/AVDemuxer.h"
#include "QtAV/AVDecoder.h"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()) {
Expand Down
9 changes: 7 additions & 2 deletions src/AVPlayerPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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());
Expand Down
1 change: 1 addition & 0 deletions src/utils/BlockingQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 53,7 @@ class BlockingQueue
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
Expand Down

0 comments on commit 20bf0d6

Please sign in to comment.