blob: e5d6bd69decf3ce293c731bb78ca0e0c0a54f28f [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 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
pbos@webrtc.org281cff82013-05-17 13:44:48 +000011#include "webrtc/video_engine/encoder_state_feedback.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000012
13#include <assert.h>
14
pbos@webrtc.org281cff82013-05-17 13:44:48 +000015#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
16#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
17#include "webrtc/video_engine/vie_encoder.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000018
19namespace webrtc {
20
21// Helper class registered at the RTP module relaying callbacks to
22// EncoderStatFeedback.
23class EncoderStateFeedbackObserver : public RtcpIntraFrameObserver {
24 public:
25 explicit EncoderStateFeedbackObserver(EncoderStateFeedback* owner)
26 : owner_(owner) {}
27 ~EncoderStateFeedbackObserver() {}
28
29 // Implements RtcpIntraFrameObserver.
30 virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
31 owner_->OnReceivedIntraFrameRequest(ssrc);
32 }
33 virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
34 owner_->OnReceivedSLI(ssrc, picture_id);
35 }
36 virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
37 owner_->OnReceivedRPSI(ssrc, picture_id);
38 }
39
40 virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {
41 owner_->OnLocalSsrcChanged(old_ssrc, new_ssrc);
42 }
43
44 private:
45 EncoderStateFeedback* owner_;
46};
47
48EncoderStateFeedback::EncoderStateFeedback()
49 : crit_(CriticalSectionWrapper::CreateCriticalSection()),
50 observer_(new EncoderStateFeedbackObserver(this)) {}
51
52EncoderStateFeedback::~EncoderStateFeedback() {
53 assert(encoders_.empty());
54}
55
56bool EncoderStateFeedback::AddEncoder(uint32_t ssrc, ViEEncoder* encoder) {
57 CriticalSectionScoped lock(crit_.get());
58 if (encoders_.find(ssrc) != encoders_.end()) {
59 // Two encoders must not have the same ssrc.
60 return false;
61 }
62
63 encoders_[ssrc] = encoder;
64 return true;
65}
66
mflodman@webrtc.orgb6d9cfc2012-10-25 11:30:29 +000067void EncoderStateFeedback::RemoveEncoder(const ViEEncoder* encoder) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000068 CriticalSectionScoped lock(crit_.get());
mflodman@webrtc.orgb6d9cfc2012-10-25 11:30:29 +000069 SsrcEncoderMap::iterator it = encoders_.begin();
70 while (it != encoders_.end()) {
71 if (it->second == encoder) {
72 encoders_.erase(it++);
73 } else {
74 ++it;
75 }
76 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000077}
78
79RtcpIntraFrameObserver* EncoderStateFeedback::GetRtcpIntraFrameObserver() {
80 return observer_.get();
81}
82
83void EncoderStateFeedback::OnReceivedIntraFrameRequest(uint32_t ssrc) {
84 CriticalSectionScoped lock(crit_.get());
85 SsrcEncoderMap::iterator it = encoders_.find(ssrc);
86 if (it == encoders_.end())
87 return;
88
89 it->second->OnReceivedIntraFrameRequest(ssrc);
90}
91
92void EncoderStateFeedback::OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
93 CriticalSectionScoped lock(crit_.get());
94 SsrcEncoderMap::iterator it = encoders_.find(ssrc);
95 if (it == encoders_.end())
96 return;
97
98 it->second->OnReceivedSLI(ssrc, picture_id);
99}
100
101void EncoderStateFeedback::OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
102 CriticalSectionScoped lock(crit_.get());
103 SsrcEncoderMap::iterator it = encoders_.find(ssrc);
104 if (it == encoders_.end())
105 return;
106
107 it->second->OnReceivedRPSI(ssrc, picture_id);
108}
109
110void EncoderStateFeedback::OnLocalSsrcChanged(uint32_t old_ssrc,
111 uint32_t new_ssrc) {
112 CriticalSectionScoped lock(crit_.get());
113 SsrcEncoderMap::iterator it = encoders_.find(old_ssrc);
114 if (it == encoders_.end() || encoders_.find(new_ssrc) != encoders_.end()) {
115 return;
116 }
117
mflodman@webrtc.orgb6d9cfc2012-10-25 11:30:29 +0000118 ViEEncoder* encoder = it->second;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000119 encoders_.erase(it);
mflodman@webrtc.orgb6d9cfc2012-10-25 11:30:29 +0000120 encoders_[new_ssrc] = encoder;
121 encoder->OnLocalSsrcChanged(old_ssrc, new_ssrc);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000122}
123
124} // namespace webrtc