mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
avplayer: report loop boundaries when decoded output is delivered
This commit is contained in:
+23
-3
@@ -552,6 +552,7 @@ private:
|
|||||||
struct ReadyFrame {
|
struct ReadyFrame {
|
||||||
std::unique_ptr<GuestBuffer> buffer;
|
std::unique_ptr<GuestBuffer> buffer;
|
||||||
AvPlayerFrameInfoEx info {};
|
AvPlayerFrameInfoEx info {};
|
||||||
|
uint64_t timestamp_offset = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileStreamer {
|
class FileStreamer {
|
||||||
@@ -933,6 +934,7 @@ public:
|
|||||||
}
|
}
|
||||||
current_video = std::move(*frame);
|
current_video = std::move(*frame);
|
||||||
*out = current_video->info;
|
*out = current_video->info;
|
||||||
|
RecordLoopBoundary(*current_video);
|
||||||
if (deliver_seek_frame) {
|
if (deliver_seek_frame) {
|
||||||
seek_video_frame_pending = false;
|
seek_video_frame_pending = false;
|
||||||
}
|
}
|
||||||
@@ -963,11 +965,25 @@ public:
|
|||||||
std::memcpy(out->details.audio.language_code,
|
std::memcpy(out->details.audio.language_code,
|
||||||
current_audio->info.details.audio.language_code, 4);
|
current_audio->info.details.audio.language_code, 4);
|
||||||
last_audio_ts = out->time_stamp;
|
last_audio_ts = out->time_stamp;
|
||||||
|
RecordLoopBoundary(*current_audio);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::optional<int32_t> TakeWarning() { return warnings.TryPop(); }
|
std::optional<int32_t> TakeWarning() {
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
if (pending_loop_warnings == 0) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
--pending_loop_warnings;
|
||||||
|
return AVPLAYER_WARNING_LOOPING_BACK;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void RecordLoopBoundary(const ReadyFrame& frame) {
|
||||||
|
if (frame.timestamp_offset > last_output_loop_offset) {
|
||||||
|
last_output_loop_offset = frame.timestamp_offset;
|
||||||
|
++pending_loop_warnings;
|
||||||
|
}
|
||||||
|
}
|
||||||
void Close() {
|
void Close() {
|
||||||
Stop();
|
Stop();
|
||||||
if (fmt != nullptr) {
|
if (fmt != nullptr) {
|
||||||
@@ -1014,6 +1030,8 @@ private:
|
|||||||
audio_done = true;
|
audio_done = true;
|
||||||
seek_video_frame_pending = false;
|
seek_video_frame_pending = false;
|
||||||
last_audio_ts = 0;
|
last_audio_ts = 0;
|
||||||
|
last_output_loop_offset = 0;
|
||||||
|
pending_loop_warnings = 0;
|
||||||
current_video = std::move(delivered_video);
|
current_video = std::move(delivered_video);
|
||||||
current_audio = std::move(delivered_audio);
|
current_audio = std::move(delivered_audio);
|
||||||
retired_video = std::move(in_flight_video);
|
retired_video = std::move(in_flight_video);
|
||||||
@@ -1220,7 +1238,6 @@ private:
|
|||||||
if (avformat_seek_file(fmt, stream, INT64_MIN, 0, INT64_MAX, 0) < 0) {
|
if (avformat_seek_file(fmt, stream, INT64_MIN, 0, INT64_MAX, 0) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
warnings.Push(AVPLAYER_WARNING_LOOPING_BACK);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result != AVERROR_EOF && !worker_stop) {
|
if (result != AVERROR_EOF && !worker_stop) {
|
||||||
@@ -1340,6 +1357,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ready.info.time_stamp += timestamp_offset;
|
ready.info.time_stamp += timestamp_offset;
|
||||||
|
ready.timestamp_offset = timestamp_offset;
|
||||||
frames.Push(std::move(ready));
|
frames.Push(std::move(ready));
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1621,6 @@ private:
|
|||||||
std::optional<ReadyFrame> current_video;
|
std::optional<ReadyFrame> current_video;
|
||||||
std::optional<ReadyFrame> current_audio;
|
std::optional<ReadyFrame> current_audio;
|
||||||
std::deque<std::unique_ptr<GuestBuffer>> retired_video;
|
std::deque<std::unique_ptr<GuestBuffer>> retired_video;
|
||||||
WorkQueue<int32_t> warnings;
|
|
||||||
LibKernel::Pthread demux_thread = nullptr;
|
LibKernel::Pthread demux_thread = nullptr;
|
||||||
LibKernel::Pthread video_thread = nullptr;
|
LibKernel::Pthread video_thread = nullptr;
|
||||||
LibKernel::Pthread audio_thread = nullptr;
|
LibKernel::Pthread audio_thread = nullptr;
|
||||||
@@ -1623,6 +1640,8 @@ private:
|
|||||||
uint32_t sync_mode = 0;
|
uint32_t sync_mode = 0;
|
||||||
uint64_t start_time_ms = 0;
|
uint64_t start_time_ms = 0;
|
||||||
uint64_t last_audio_ts = 0;
|
uint64_t last_audio_ts = 0;
|
||||||
|
uint64_t last_output_loop_offset = 0;
|
||||||
|
uint32_t pending_loop_warnings = 0;
|
||||||
std::chrono::steady_clock::time_point clock_start {};
|
std::chrono::steady_clock::time_point clock_start {};
|
||||||
std::chrono::steady_clock::time_point pause_time {};
|
std::chrono::steady_clock::time_point pause_time {};
|
||||||
std::chrono::steady_clock::duration paused_extra {};
|
std::chrono::steady_clock::duration paused_extra {};
|
||||||
@@ -1951,6 +1970,7 @@ Bool KYTY_SYSV_ABI AvPlayerGetVideoData(AvPlayerInternal* h, AvPlayerFrameInfo*
|
|||||||
video_info->details.video.height = ex.details.video.height;
|
video_info->details.video.height = ex.details.video.height;
|
||||||
video_info->details.video.aspect_ratio = ex.details.video.aspect_ratio;
|
video_info->details.video.aspect_ratio = ex.details.video.aspect_ratio;
|
||||||
std::memcpy(video_info->details.video.language_code, ex.details.video.language_code, 4);
|
std::memcpy(video_info->details.video.language_code, ex.details.video.language_code, 4);
|
||||||
|
pump_warnings(h);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Bool KYTY_SYSV_ABI AvPlayerGetVideoDataEx(AvPlayerInternal* h, AvPlayerFrameInfoEx* video_info) {
|
Bool KYTY_SYSV_ABI AvPlayerGetVideoDataEx(AvPlayerInternal* h, AvPlayerFrameInfoEx* video_info) {
|
||||||
|
|||||||
Reference in New Issue
Block a user