From fa51da4d76f04e57e9bb3674631c0f1139132d28 Mon Sep 17 00:00:00 2001 From: nmzik Date: Sun, 20 Sep 2026 14:40:29 +0400 Subject: [PATCH] Fix AvPlayer end-of-file handling --- src/libs/avPlayer.cpp | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/libs/avPlayer.cpp b/src/libs/avPlayer.cpp index 005a6f628..f7fa88f28 100644 --- a/src/libs/avPlayer.cpp +++ b/src/libs/avPlayer.cpp @@ -829,20 +829,22 @@ public: } int Stop() { bool was_playing_video = false; - AvPlayerEventReplacement stop_event; + AvPlayerEventReplacement stop_event {}; { std::scoped_lock lifecycle_lock(lifecycle_mutex); { std::lock_guard lock(mutex); - was_playing_video = state == State::Playing && video_id.has_value(); - state = State::Stopped; + if (state == State::Playing) { + was_playing_video = video_id.has_value(); + stop_event = event; + } + state = State::Stopped; } StopWorkers(); { std::lock_guard lock(mutex); ResetNoLock(); } - stop_event = TakeStopEvent(); } if (was_playing_video) { ::printf("AvPlayer video stopped\n"); @@ -960,7 +962,6 @@ public: current_video = std::move(*frame); *out = current_video->info; RecordLoopBoundary(*current_video); - completion_changed.notify_all(); if (deliver_seek_frame) { seek_video_frame_pending = false; } @@ -993,7 +994,6 @@ public: current_audio->info.details.audio.language_code, 4); last_audio_ts = out->time_stamp; RecordLoopBoundary(*current_audio); - completion_changed.notify_all(); return true; } std::optional TakeWarning() { @@ -1012,9 +1012,6 @@ private: return demux_eof && video_done && audio_done && video_frames.Empty() && audio_frames.Empty(); } - AvPlayerEventReplacement TakeStopEvent() { - return stop_event_sent.exchange(true) ? AvPlayerEventReplacement {} : event; - } void RecordLoopBoundary(const ReadyFrame& frame) { if (frame.timestamp_offset > last_output_loop_offset) { last_output_loop_offset = frame.timestamp_offset; @@ -1206,12 +1203,10 @@ private: StopWorkers(); return false; } - state = State::Playing; - stop_event_sent = false; + state = State::Playing; return true; } void NotifyWorkers() { - completion_changed.notify_all(); video_packets.Notify(); audio_packets.Notify(); video_buffers.Notify(); @@ -1298,13 +1293,6 @@ private: demux_eof = true; video_packets.Notify(); audio_packets.Notify(); - std::unique_lock lock(mutex); - completion_changed.wait(lock, [&] { return worker_stop || DrainedNoLock(); }); - if (!worker_stop) { - const auto stop_event = TakeStopEvent(); - lock.unlock(); - emit_event(stop_event, AVPLAYER_EVENT_STATE_STOP); - } } void VideoDecoder() { Decoder(video_packets, video_ctx, video_buffers, video_frames, video_done, @@ -1352,11 +1340,7 @@ private: break; } } - { - std::lock_guard lock(mutex); - done = true; - } - completion_changed.notify_all(); + done = true; } bool DecodePacket(AVCodecContext* codec, AVPacket* packet, uint64_t timestamp_offset, WorkQueue>& buffers, @@ -1681,8 +1665,6 @@ private: std::atomic_bool demux_eof {true}; std::atomic_bool video_done {true}; std::atomic_bool audio_done {true}; - std::atomic_bool stop_event_sent {true}; - std::condition_variable completion_changed; std::mutex lifecycle_mutex; mutable std::mutex mutex; State state = State::Ready;