blob: a44b76bf152ee85d9c2e183496acbc2182f413ef [file] [log] [blame]
philipel02447bc2016-05-13 06:01:03 -07001/*
2 * Copyright (c) 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/video_coding/rtp_frame_reference_finder.h"
philipel02447bc2016-05-13 06:01:03 -070012
philipel4e702162020-11-27 17:56:37 +010013#include <utility>
philipel02447bc2016-05-13 06:01:03 -070014
philipel4e702162020-11-27 17:56:37 +010015#include "absl/types/variant.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/video_coding/frame_object.h"
philipel4e702162020-11-27 17:56:37 +010017#include "modules/video_coding/rtp_frame_id_only_ref_finder.h"
18#include "modules/video_coding/rtp_generic_ref_finder.h"
19#include "modules/video_coding/rtp_seq_num_only_ref_finder.h"
20#include "modules/video_coding/rtp_vp8_ref_finder.h"
21#include "modules/video_coding/rtp_vp9_ref_finder.h"
philipel02447bc2016-05-13 06:01:03 -070022
23namespace webrtc {
philipel4e702162020-11-27 17:56:37 +010024namespace internal {
25class RtpFrameReferenceFinderImpl {
26 public:
27 RtpFrameReferenceFinderImpl() = default;
28
29 RtpFrameReferenceFinder::ReturnVector ManageFrame(
philipelca188092021-03-23 12:00:49 +010030 std::unique_ptr<RtpFrameObject> frame);
philipel4e702162020-11-27 17:56:37 +010031 RtpFrameReferenceFinder::ReturnVector PaddingReceived(uint16_t seq_num);
32 void ClearTo(uint16_t seq_num);
33
34 private:
35 using RefFinder = absl::variant<absl::monostate,
36 RtpGenericFrameRefFinder,
37 RtpFrameIdOnlyRefFinder,
38 RtpSeqNumOnlyRefFinder,
39 RtpVp8RefFinder,
40 RtpVp9RefFinder>;
41
42 template <typename T>
43 T& GetRefFinderAs();
44 RefFinder ref_finder_;
45};
46
47RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinderImpl::ManageFrame(
philipelca188092021-03-23 12:00:49 +010048 std::unique_ptr<RtpFrameObject> frame) {
philipel4e702162020-11-27 17:56:37 +010049 const RTPVideoHeader& video_header = frame->GetRtpVideoHeader();
50
51 if (video_header.generic.has_value()) {
52 return GetRefFinderAs<RtpGenericFrameRefFinder>().ManageFrame(
53 std::move(frame), *video_header.generic);
54 }
55
56 switch (frame->codec_type()) {
57 case kVideoCodecVP8: {
58 const RTPVideoHeaderVP8& vp8_header =
59 absl::get<RTPVideoHeaderVP8>(video_header.video_type_header);
60
61 if (vp8_header.temporalIdx == kNoTemporalIdx ||
62 vp8_header.tl0PicIdx == kNoTl0PicIdx) {
63 if (vp8_header.pictureId == kNoPictureId) {
64 return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
65 std::move(frame));
66 }
67
68 return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
69 std::move(frame), vp8_header.pictureId);
70 }
71
72 return GetRefFinderAs<RtpVp8RefFinder>().ManageFrame(std::move(frame));
73 }
74 case kVideoCodecVP9: {
75 const RTPVideoHeaderVP9& vp9_header =
76 absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
77
78 if (vp9_header.temporal_idx == kNoTemporalIdx) {
79 if (vp9_header.picture_id == kNoPictureId) {
80 return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
81 std::move(frame));
82 }
83
84 return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
85 std::move(frame), vp9_header.picture_id);
86 }
87
88 return GetRefFinderAs<RtpVp9RefFinder>().ManageFrame(std::move(frame));
89 }
philipel4e702162020-11-27 17:56:37 +010090 case kVideoCodecGeneric: {
91 if (auto* generic_header = absl::get_if<RTPVideoHeaderLegacyGeneric>(
92 &video_header.video_type_header)) {
93 return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
94 std::move(frame), generic_header->picture_id);
95 }
96
97 return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
98 std::move(frame));
99 }
100 default: {
philipel39f09b42020-12-01 11:47:12 +0100101 return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
102 std::move(frame));
philipel4e702162020-11-27 17:56:37 +0100103 }
104 }
105}
106
107RtpFrameReferenceFinder::ReturnVector
108RtpFrameReferenceFinderImpl::PaddingReceived(uint16_t seq_num) {
109 if (auto* ref_finder = absl::get_if<RtpSeqNumOnlyRefFinder>(&ref_finder_)) {
110 return ref_finder->PaddingReceived(seq_num);
111 }
112 return {};
113}
114
115void RtpFrameReferenceFinderImpl::ClearTo(uint16_t seq_num) {
116 struct ClearToVisitor {
117 void operator()(absl::monostate& ref_finder) {}
118 void operator()(RtpGenericFrameRefFinder& ref_finder) {}
119 void operator()(RtpFrameIdOnlyRefFinder& ref_finder) {}
120 void operator()(RtpSeqNumOnlyRefFinder& ref_finder) {
121 ref_finder.ClearTo(seq_num);
122 }
123 void operator()(RtpVp8RefFinder& ref_finder) {
124 ref_finder.ClearTo(seq_num);
125 }
126 void operator()(RtpVp9RefFinder& ref_finder) {
127 ref_finder.ClearTo(seq_num);
128 }
129 uint16_t seq_num;
130 };
131
132 absl::visit(ClearToVisitor{seq_num}, ref_finder_);
133}
134
135template <typename T>
136T& RtpFrameReferenceFinderImpl::GetRefFinderAs() {
137 if (auto* ref_finder = absl::get_if<T>(&ref_finder_)) {
138 return *ref_finder;
139 }
140 return ref_finder_.emplace<T>();
141}
142
143} // namespace internal
philipel02447bc2016-05-13 06:01:03 -0700144
philipel21820962021-05-25 15:35:57 +0200145RtpFrameReferenceFinder::RtpFrameReferenceFinder()
146 : RtpFrameReferenceFinder(0) {}
philipel7acc4a42019-09-26 11:25:52 +0200147
148RtpFrameReferenceFinder::RtpFrameReferenceFinder(
philipel7acc4a42019-09-26 11:25:52 +0200149 int64_t picture_id_offset)
philipel4e702162020-11-27 17:56:37 +0100150 : picture_id_offset_(picture_id_offset),
philipel4e702162020-11-27 17:56:37 +0100151 impl_(std::make_unique<internal::RtpFrameReferenceFinderImpl>()) {}
philipel02447bc2016-05-13 06:01:03 -0700152
Mirko Bonadei8fdcac32018-08-28 16:30:18 +0200153RtpFrameReferenceFinder::~RtpFrameReferenceFinder() = default;
154
philipel21820962021-05-25 15:35:57 +0200155RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::ManageFrame(
philipelca188092021-03-23 12:00:49 +0100156 std::unique_ptr<RtpFrameObject> frame) {
philipel463d3012016-09-09 03:32:44 -0700157 // If we have cleared past this frame, drop it.
158 if (cleared_to_seq_num_ != -1 &&
159 AheadOf<uint16_t>(cleared_to_seq_num_, frame->first_seq_num())) {
philipel21820962021-05-25 15:35:57 +0200160 return {};
philipel463d3012016-09-09 03:32:44 -0700161 }
philipel21820962021-05-25 15:35:57 +0200162
163 auto frames = impl_->ManageFrame(std::move(frame));
164 AddPictureIdOffset(frames);
165 return frames;
philipel02447bc2016-05-13 06:01:03 -0700166}
167
philipel21820962021-05-25 15:35:57 +0200168RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::PaddingReceived(
169 uint16_t seq_num) {
170 auto frames = impl_->PaddingReceived(seq_num);
171 AddPictureIdOffset(frames);
172 return frames;
philipel9b2ce6b2016-07-05 05:04:46 -0700173}
174
philipel463d3012016-09-09 03:32:44 -0700175void RtpFrameReferenceFinder::ClearTo(uint16_t seq_num) {
philipel463d3012016-09-09 03:32:44 -0700176 cleared_to_seq_num_ = seq_num;
philipel4e702162020-11-27 17:56:37 +0100177 impl_->ClearTo(seq_num);
philipel463d3012016-09-09 03:32:44 -0700178}
179
philipel21820962021-05-25 15:35:57 +0200180void RtpFrameReferenceFinder::AddPictureIdOffset(ReturnVector& frames) {
philipel4e702162020-11-27 17:56:37 +0100181 for (auto& frame : frames) {
philipel9aa9b8d2021-02-15 13:31:29 +0100182 frame->SetId(frame->Id() + picture_id_offset_);
philipel02447bc2016-05-13 06:01:03 -0700183 for (size_t i = 0; i < frame->num_references; ++i) {
philipel4e702162020-11-27 17:56:37 +0100184 frame->references[i] += picture_id_offset_;
philipel02447bc2016-05-13 06:01:03 -0700185 }
philipel02447bc2016-05-13 06:01:03 -0700186 }
philipel02447bc2016-05-13 06:01:03 -0700187}
188
philipel02447bc2016-05-13 06:01:03 -0700189} // namespace webrtc