Skip to content

Commit

Permalink
support change buffer value when playing
Browse files Browse the repository at this point in the history
bug: set to a lower value may block the playback when buffering
  • Loading branch information
wang-bin committed Apr 17, 2015
1 parent 4c15e89 commit b52f8d9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/AVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,10 @@ BufferMode AVPlayer::bufferMode() const

void AVPlayer::setBufferValue(int value)
{
if (d->buffer_value == value)
return;
d->buffer_value = value;
d->updateBufferValue();
}

int AVPlayer::bufferValue() const
Expand Down
47 changes: 30 additions & 17 deletions src/AVPlayerPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ bool AVPlayer::Private::setupAudioThread(AVPlayer *player)
}
AVCodecContext *avctx = demuxer.audioCodecContext();
if (!avctx) {
// TODO: close ao?
// TODO: close ao? //TODO: check pulseaudio perapp control if closed
return false;
}
qDebug("has audio");
Expand Down Expand Up @@ -371,16 +371,7 @@ bool AVPlayer::Private::setupAudioThread(AVPlayer *player)
}
athread->setDecoder(adec);
setAVOutput(ao, ao, athread);
// 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)
bv = 1024;
athread->packetQueue()->setBufferMode(buffer_mode);
athread->packetQueue()->setBufferValue(buffer_value < 0 ? bv : buffer_value);
updateBufferValue(athread->packetQueue());
initAudioStatistics(demuxer.audioStream());
return true;
}
Expand Down Expand Up @@ -447,19 +438,41 @@ bool AVPlayer::Private::setupVideoThread(AVPlayer *player)
vthread->setBrightness(brightness);
vthread->setContrast(contrast);
vthread->setSaturation(saturation);
updateBufferValue(vthread->packetQueue());
initVideoStatistics(demuxer.videoStream());
return true;
}

// TODO: set to a lower value when buffering
void AVPlayer::Private::updateBufferValue(PacketBuffer* buf)
{
const bool video = vthread && buf == vthread->packetQueue();
const qreal fps = qMax<qreal>(24.0, statistics.video.frame_rate);
int bv = 0.6*fps;
if (!video) {
// if has video, then audio buffer should not block the video buffer (bufferValue == 1, modified in AVDemuxThread)
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)
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());
return true;
if (video) {
if (demuxer.hasAttacedPicture() || (statistics.video.frames > 0 && statistics.video.frames < bv))
bv = qMax<int>(1, statistics.video.frames);
}
buf->setBufferMode(buffer_mode);
buf->setBufferValue(buffer_value < 0 ? bv : buffer_value);
}

void AVPlayer::Private::updateBufferValue()
{
if (athread)
updateBufferValue(athread->packetQueue());
if (vthread)
updateBufferValue(vthread->packetQueue());
}

} //namespace QtAV
5 changes: 3 additions & 2 deletions src/AVPlayerPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class AVPlayer::Private

bool setupAudioThread(AVPlayer *player);
bool setupVideoThread(AVPlayer *player);

// TODO: what if buffer mode changed during playback?
void updateBufferValue(PacketBuffer *buf);
void updateBufferValue();
//TODO: addAVOutput()
template<class Out>
void setAVOutput(Out *&pOut, Out *pNew, AVThread *thread) {
Expand Down Expand Up @@ -95,7 +97,6 @@ class AVPlayer::Private
}
}


bool auto_load;
bool async_load;
// can be QString, QIODevice*
Expand Down

0 comments on commit b52f8d9

Please sign in to comment.