Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #include "video/frame_decode_timing.h" |
| 12 | |
Evan Shrubsole | f7a1937 | 2022-02-14 13:05:10 | [diff] [blame] | 13 | #include <algorithm> |
| 14 | |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 15 | #include "absl/types/optional.h" |
Evan Shrubsole | f7a1937 | 2022-02-14 13:05:10 | [diff] [blame] | 16 | #include "api/units/time_delta.h" |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 17 | #include "rtc_base/logging.h" |
| 18 | |
| 19 | namespace webrtc { |
| 20 | |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 21 | FrameDecodeTiming::FrameDecodeTiming(Clock* clock, |
| 22 | webrtc::VCMTiming const* timing) |
| 23 | : clock_(clock), timing_(timing) { |
| 24 | RTC_DCHECK(clock_); |
| 25 | RTC_DCHECK(timing_); |
| 26 | } |
| 27 | |
| 28 | absl::optional<FrameDecodeTiming::FrameSchedule> |
| 29 | FrameDecodeTiming::OnFrameBufferUpdated(uint32_t next_temporal_unit_rtp, |
| 30 | uint32_t last_temporal_unit_rtp, |
Evan Shrubsole | 3fa9a66 | 2022-06-13 14:19:10 | [diff] [blame] | 31 | TimeDelta max_wait_for_frame, |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 32 | bool too_many_frames_queued) { |
Evan Shrubsole | 4d3ba77 | 2022-06-22 14:32:36 | [diff] [blame] | 33 | RTC_DCHECK_GE(max_wait_for_frame, TimeDelta::Zero()); |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 34 | const Timestamp now = clock_->CurrentTime(); |
Evan Shrubsole | d6cdf80 | 2022-03-02 14:13:55 | [diff] [blame] | 35 | Timestamp render_time = timing_->RenderTime(next_temporal_unit_rtp, now); |
| 36 | TimeDelta max_wait = |
| 37 | timing_->MaxWaitingTime(render_time, now, too_many_frames_queued); |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 38 | |
| 39 | // If the delay is not too far in the past, or this is the last decodable |
| 40 | // frame then it is the best frame to be decoded. Otherwise, fast-forward |
| 41 | // to the next frame in the buffer. |
| 42 | if (max_wait <= -kMaxAllowedFrameDelay && |
| 43 | next_temporal_unit_rtp != last_temporal_unit_rtp) { |
| 44 | RTC_DLOG(LS_VERBOSE) << "Fast-forwarded frame " << next_temporal_unit_rtp |
Evan Shrubsole | 4d3ba77 | 2022-06-22 14:32:36 | [diff] [blame] | 45 | << " render time " << render_time << " with delay " |
| 46 | << max_wait; |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 47 | return absl::nullopt; |
| 48 | } |
Evan Shrubsole | f7a1937 | 2022-02-14 13:05:10 | [diff] [blame] | 49 | |
Evan Shrubsole | 3fa9a66 | 2022-06-13 14:19:10 | [diff] [blame] | 50 | max_wait.Clamp(TimeDelta::Zero(), max_wait_for_frame); |
Evan Shrubsole | 4d3ba77 | 2022-06-22 14:32:36 | [diff] [blame] | 51 | RTC_DLOG(LS_VERBOSE) << "Selected frame with rtp " << next_temporal_unit_rtp |
| 52 | << " render time " << render_time |
| 53 | << " with a max wait of " << max_wait_for_frame |
| 54 | << " clamped to " << max_wait; |
Evan Shrubsole | 3fa9a66 | 2022-06-13 14:19:10 | [diff] [blame] | 55 | Timestamp latest_decode_time = now + max_wait; |
Evan Shrubsole | f7a1937 | 2022-02-14 13:05:10 | [diff] [blame] | 56 | return FrameSchedule{.latest_decode_time = latest_decode_time, |
Evan Shrubsole | 9a99905 | 2021-12-12 14:27:00 | [diff] [blame] | 57 | .render_time = render_time}; |
| 58 | } |
| 59 | |
| 60 | } // namespace webrtc |