Fix AvPlayer end-of-file handling

This commit is contained in:
nmzik
2026-09-20 14:40:29 +04:00
parent 6b79b7a003
commit fa51da4d76
+5 -23
View File
@@ -829,12 +829,15 @@ 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();
if (state == State::Playing) {
was_playing_video = video_id.has_value();
stop_event = event;
}
state = State::Stopped;
}
StopWorkers();
@@ -842,7 +845,6 @@ public:
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<int32_t> 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;
@@ -1207,11 +1204,9 @@ private:
return false;
}
state = State::Playing;
stop_event_sent = false;
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,12 +1340,8 @@ private:
break;
}
}
{
std::lock_guard lock(mutex);
done = true;
}
completion_changed.notify_all();
}
bool DecodePacket(AVCodecContext* codec, AVPacket* packet, uint64_t timestamp_offset,
WorkQueue<std::unique_ptr<GuestBuffer>>& buffers,
WorkQueue<ReadyFrame>& frames, PrepareFrame prepare, const char* kind) {
@@ -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;