• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #include "webrtc/video/encoder_state_feedback.h"
12 
13 #include <assert.h>
14 
15 #include "webrtc/base/checks.h"
16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
18 #include "webrtc/video/vie_encoder.h"
19 
20 namespace webrtc {
21 
22 // Helper class registered at the RTP module relaying callbacks to
23 // EncoderStatFeedback.
24 class EncoderStateFeedbackObserver : public  RtcpIntraFrameObserver {
25  public:
EncoderStateFeedbackObserver(EncoderStateFeedback * owner)26   explicit EncoderStateFeedbackObserver(EncoderStateFeedback* owner)
27       : owner_(owner) {}
~EncoderStateFeedbackObserver()28   ~EncoderStateFeedbackObserver() {}
29 
30   // Implements RtcpIntraFrameObserver.
OnReceivedIntraFrameRequest(uint32_t ssrc)31   virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
32     owner_->OnReceivedIntraFrameRequest(ssrc);
33   }
OnReceivedSLI(uint32_t ssrc,uint8_t picture_id)34   virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
35     owner_->OnReceivedSLI(ssrc, picture_id);
36   }
OnReceivedRPSI(uint32_t ssrc,uint64_t picture_id)37   virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
38     owner_->OnReceivedRPSI(ssrc, picture_id);
39   }
40 
OnLocalSsrcChanged(uint32_t old_ssrc,uint32_t new_ssrc)41   virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {
42     owner_->OnLocalSsrcChanged(old_ssrc, new_ssrc);
43   }
44 
45  private:
46   EncoderStateFeedback* owner_;
47 };
48 
EncoderStateFeedback()49 EncoderStateFeedback::EncoderStateFeedback()
50     : crit_(CriticalSectionWrapper::CreateCriticalSection()),
51       observer_(new EncoderStateFeedbackObserver(this)) {}
52 
~EncoderStateFeedback()53 EncoderStateFeedback::~EncoderStateFeedback() {
54   assert(encoders_.empty());
55 }
56 
AddEncoder(const std::vector<uint32_t> & ssrcs,ViEEncoder * encoder)57 void EncoderStateFeedback::AddEncoder(const std::vector<uint32_t>& ssrcs,
58                                       ViEEncoder* encoder) {
59   RTC_DCHECK(!ssrcs.empty());
60   CriticalSectionScoped lock(crit_.get());
61   for (uint32_t ssrc : ssrcs) {
62     RTC_DCHECK(encoders_.find(ssrc) == encoders_.end());
63     encoders_[ssrc] = encoder;
64   }
65 }
66 
RemoveEncoder(const ViEEncoder * encoder)67 void EncoderStateFeedback::RemoveEncoder(const ViEEncoder* encoder)  {
68   CriticalSectionScoped lock(crit_.get());
69   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   }
77 }
78 
GetRtcpIntraFrameObserver()79 RtcpIntraFrameObserver* EncoderStateFeedback::GetRtcpIntraFrameObserver() {
80   return observer_.get();
81 }
82 
OnReceivedIntraFrameRequest(uint32_t ssrc)83 void 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 
OnReceivedSLI(uint32_t ssrc,uint8_t picture_id)92 void 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 
OnReceivedRPSI(uint32_t ssrc,uint64_t picture_id)101 void 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 
OnLocalSsrcChanged(uint32_t old_ssrc,uint32_t new_ssrc)110 void 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 
118   ViEEncoder* encoder = it->second;
119   encoders_.erase(it);
120   encoders_[new_ssrc] = encoder;
121   encoder->OnLocalSsrcChanged(old_ssrc, new_ssrc);
122 }
123 
124 }  // namespace webrtc
125