fix: keep the displayed frame during frame stepping
This commit is contained in:
@@ -21,8 +21,8 @@ public:
|
||||
// Atomic target gain; callback slews to it within 240 frames (5 ms).
|
||||
void set_volume(float normalized0to1) noexcept;
|
||||
float volume() const noexcept;
|
||||
// Called with audio stopped. Clears audio and video from the old timeline.
|
||||
void reset();
|
||||
// Called with audio stopped. Clears audio; optionally keeps the displayed frame.
|
||||
void reset(bool clear_video = true);
|
||||
std::size_t write(const float *samples, std::size_t frames, double pts);
|
||||
std::size_t queued() const;
|
||||
// Latency-aware presented position; NaN until an audio callback has run.
|
||||
|
||||
@@ -269,9 +269,9 @@ struct Player {
|
||||
check(avcodec_open2(track.codec, decoder, nullptr), "Opening decoder");
|
||||
}
|
||||
|
||||
void resetTimeline(double target) {
|
||||
void resetTimeline(double target, bool clearVideo = true) {
|
||||
output.pause();
|
||||
output.reset();
|
||||
output.reset(clearVideo);
|
||||
for (auto &track : tracks) {
|
||||
if (!track.codec) continue;
|
||||
avcodec_flush_buffers(track.codec);
|
||||
@@ -425,7 +425,8 @@ struct Player {
|
||||
output.pause();
|
||||
check(av_seek_frame(format, tracks[1].index, timestamp, AVSEEK_FLAG_BACKWARD),
|
||||
"Seeking video keyframe");
|
||||
resetTimeline(target);
|
||||
// Decoder preroll must not blank the last presented frame between steps.
|
||||
resetTimeline(target, false);
|
||||
status = PLAYER_PAUSED;
|
||||
}
|
||||
|
||||
|
||||
@@ -395,13 +395,15 @@ void Output::set_volume(float normalized0to1) noexcept {
|
||||
float Output::volume() const noexcept {
|
||||
return impl->targetGain.load(std::memory_order_relaxed);
|
||||
}
|
||||
void Output::reset() {
|
||||
void Output::reset(bool clear_video) {
|
||||
impl->read.store(0); impl->written.store(0);
|
||||
impl->origin = 0;
|
||||
impl->anchorPTS.store(NAN); impl->frozen.store(NAN); impl->endPTS.store(0);
|
||||
std::lock_guard lock(impl->video->mutex);
|
||||
av_frame_unref(impl->video->frame);
|
||||
++impl->video->version;
|
||||
if (clear_video) {
|
||||
std::lock_guard lock(impl->video->mutex);
|
||||
av_frame_unref(impl->video->frame);
|
||||
++impl->video->version;
|
||||
}
|
||||
}
|
||||
size_t Output::write(const float *samples, size_t frames, double pts) {
|
||||
uint64_t w = impl->written.load(std::memory_order_relaxed);
|
||||
|
||||
Reference in New Issue
Block a user