avplayer: report loop boundaries when decoded output is delivered
This commit is contained in:
parent
f3c82a317a
commit
b67cb81359
|
|
@ -552,6 +552,7 @@ private:
|
|||
struct ReadyFrame {
|
||||
std::unique_ptr<GuestBuffer> buffer;
|
||||
AvPlayerFrameInfoEx info {};
|
||||
uint64_t timestamp_offset = 0;
|
||||
};
|
||||
|
||||
class FileStreamer {
|
||||
|
|
@ -933,6 +934,7 @@ public:
|
|||
}
|
||||
current_video = std::move(*frame);
|
||||
*out = current_video->info;
|
||||
RecordLoopBoundary(*current_video);
|
||||
if (deliver_seek_frame) {
|
||||
seek_video_frame_pending = false;
|
||||
}
|
||||
|
|
@ -963,11 +965,25 @@ public:
|
|||
std::memcpy(out->details.audio.language_code,
|
||||
current_audio->info.details.audio.language_code, 4);
|
||||
last_audio_ts = out->time_stamp;
|
||||
RecordLoopBoundary(*current_audio);
|
||||
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:
|
||||
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() {
|
||||
Stop();
|
||||
if (fmt != nullptr) {
|
||||
|
|
@ -1014,6 +1030,8 @@ private:
|
|||
audio_done = true;
|
||||
seek_video_frame_pending = false;
|
||||
last_audio_ts = 0;
|
||||
last_output_loop_offset = 0;
|
||||
pending_loop_warnings = 0;
|
||||
current_video = std::move(delivered_video);
|
||||
current_audio = std::move(delivered_audio);
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
warnings.Push(AVPLAYER_WARNING_LOOPING_BACK);
|
||||
continue;
|
||||
}
|
||||
if (result != AVERROR_EOF && !worker_stop) {
|
||||
|
|
@ -1340,6 +1357,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
ready.info.time_stamp += timestamp_offset;
|
||||
ready.timestamp_offset = timestamp_offset;
|
||||
frames.Push(std::move(ready));
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
|
|
@ -1603,7 +1621,6 @@ private:
|
|||
std::optional<ReadyFrame> current_video;
|
||||
std::optional<ReadyFrame> current_audio;
|
||||
std::deque<std::unique_ptr<GuestBuffer>> retired_video;
|
||||
WorkQueue<int32_t> warnings;
|
||||
LibKernel::Pthread demux_thread = nullptr;
|
||||
LibKernel::Pthread video_thread = nullptr;
|
||||
LibKernel::Pthread audio_thread = nullptr;
|
||||
|
|
@ -1623,6 +1640,8 @@ private:
|
|||
uint32_t sync_mode = 0;
|
||||
uint64_t start_time_ms = 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 pause_time {};
|
||||
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.aspect_ratio = ex.details.video.aspect_ratio;
|
||||
std::memcpy(video_info->details.video.language_code, ex.details.video.language_code, 4);
|
||||
pump_warnings(h);
|
||||
return 1;
|
||||
}
|
||||
Bool KYTY_SYSV_ABI AvPlayerGetVideoDataEx(AvPlayerInternal* h, AvPlayerFrameInfoEx* video_info) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue