blob: c3042d9fad1445e063de111d7bbfa8f9d2138906 [file] [log] [blame]
Danil Chapovalov02b17a52020-02-05 15:06:17 +01001/*
2 * Copyright (c) 2020 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#include "modules/video_coding/frame_dependencies_calculator.h"
11
12#include <stdint.h>
13
14#include <iterator>
15#include <set>
16
17#include "absl/algorithm/container.h"
18#include "absl/container/inlined_vector.h"
19#include "api/array_view.h"
20#include "api/video/video_frame_type.h"
21#include "rtc_base/checks.h"
22#include "rtc_base/logging.h"
23#include "rtc_base/synchronization/sequence_checker.h"
24
25namespace webrtc {
26
27absl::InlinedVector<int64_t, 5> FrameDependenciesCalculator::FromBuffersUsage(
28 VideoFrameType frame_type,
29 int64_t frame_id,
30 rtc::ArrayView<const CodecBufferUsage> buffers_usage) {
31 RTC_DCHECK_RUN_ON(&checker_);
32
33 absl::InlinedVector<int64_t, 5> dependencies;
34 RTC_DCHECK_GT(buffers_usage.size(), 0);
35 for (const CodecBufferUsage& buffer_usage : buffers_usage) {
36 RTC_CHECK_GE(buffer_usage.id, 0);
37 if (buffers_.size() <= static_cast<size_t>(buffer_usage.id)) {
38 buffers_.resize(buffer_usage.id + 1);
39 }
40 }
41 std::set<int64_t> direct_depenendencies;
42 std::set<int64_t> indirect_depenendencies;
43 if (frame_type == VideoFrameType::kVideoFrameDelta) {
44 for (const CodecBufferUsage& buffer_usage : buffers_usage) {
45 if (!buffer_usage.referenced) {
46 continue;
47 }
48 const BufferUsage& buffer = buffers_[buffer_usage.id];
49 if (buffer.frame_id == absl::nullopt) {
50 RTC_LOG(LS_ERROR) << "Odd configuration: frame " << frame_id
51 << " references buffer #" << buffer_usage.id
52 << " that was never updated.";
53 continue;
54 }
55 direct_depenendencies.insert(*buffer.frame_id);
56 indirect_depenendencies.insert(buffer.dependencies.begin(),
57 buffer.dependencies.end());
58 }
59 // Reduce references: if frame #3 depends on frame #2 and #1, and frame #2
60 // depends on frame #1, then frame #3 needs to depend just on frame #2.
61 // Though this set diff removes only 1 level of indirection, it seems
62 // enough for all currently used structures.
63 absl::c_set_difference(direct_depenendencies, indirect_depenendencies,
64 std::back_inserter(dependencies));
65 }
66
67 // Update buffers.
68 for (const CodecBufferUsage& buffer_usage : buffers_usage) {
69 if (!buffer_usage.updated) {
70 continue;
71 }
72 BufferUsage& buffer = buffers_[buffer_usage.id];
73 buffer.frame_id = frame_id;
74 buffer.dependencies.assign(direct_depenendencies.begin(),
75 direct_depenendencies.end());
76 }
77
78 return dependencies;
79}
80
81} // namespace webrtc