• 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_engine/encoder_state_feedback.h"
12 
13 #include <assert.h>
14 
15 #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"
18 
19 namespace webrtc {
20 
21 // Helper class registered at the RTP module relaying callbacks to
22 // EncoderStatFeedback.
23 class EncoderStateFeedbackObserver : public  RtcpIntraFrameObserver {
24  public:
EncoderStateFeedbackObserver(EncoderStateFeedback * owner)25   explicit EncoderStateFeedbackObserver(EncoderStateFeedback* owner)
26       : owner_(owner) {}
~EncoderStateFeedbackObserver()27   ~EncoderStateFeedbackObserver() {}
28 
29   // Implements RtcpIntraFrameObserver.
OnReceivedIntraFrameRequest(uint32_t ssrc)30   virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
31     owner_->OnReceivedIntraFrameRequest(ssrc);
32   }
OnReceivedSLI(uint32_t ssrc,uint8_t picture_id)33   virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
34     owner_->OnReceivedSLI(ssrc, picture_id);
35   }
OnReceivedRPSI(uint32_t ssrc,uint64_t picture_id)36   virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
37     owner_->OnReceivedRPSI(ssrc, picture_id);
38   }
39 
OnLocalSsrcChanged(uint32_t old_ssrc,uint32_t new_ssrc)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 
EncoderStateFeedback()48 EncoderStateFeedback::EncoderStateFeedback()
49     : crit_(CriticalSectionWrapper::CreateCriticalSection()),
50       observer_(new EncoderStateFeedbackObserver(this)) {}
51 
~EncoderStateFeedback()52 EncoderStateFeedback::~EncoderStateFeedback() {
53   assert(encoders_.empty());
54 }
55 
AddEncoder(uint32_t ssrc,ViEEncoder * encoder)56 bool 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 
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