OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 #include "video/call_stats.h" | 55 #include "video/call_stats.h" |
56 #include "video/send_delay_stats.h" | 56 #include "video/send_delay_stats.h" |
57 #include "video/stats_counter.h" | 57 #include "video/stats_counter.h" |
58 #include "video/video_receive_stream.h" | 58 #include "video/video_receive_stream.h" |
59 #include "video/video_send_stream.h" | 59 #include "video/video_send_stream.h" |
60 | 60 |
61 namespace webrtc { | 61 namespace webrtc { |
62 | 62 |
63 namespace { | 63 namespace { |
64 | 64 |
65 // TODO(nisse): This really begs for a shared context struct. | 65 bool UseTransportSeqno(const std::vector<RtpExtension>& extensions) { |
66 bool UseSendSideBwe(const std::vector<RtpExtension>& extensions, | |
67 bool transport_cc) { | |
68 if (!transport_cc) | |
69 return false; | |
70 for (const auto& extension : extensions) { | 66 for (const auto& extension : extensions) { |
71 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) | 67 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) |
72 return true; | 68 return true; |
73 } | 69 } |
74 return false; | 70 return false; |
75 } | 71 } |
76 | 72 |
77 bool UseSendSideBwe(const VideoReceiveStream::Config& config) { | 73 bool UseSendSideBwe(const std::vector<RtpExtension>& extensions, |
78 return UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc); | 74 bool transport_cc) { |
| 75 return transport_cc && UseTransportSeqno(extensions); |
79 } | 76 } |
80 | 77 |
81 bool UseSendSideBwe(const AudioReceiveStream::Config& config) { | 78 bool UseSendSideBwe(const AudioReceiveStream::Config& config) { |
82 return UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc); | 79 return UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc); |
83 } | 80 } |
84 | 81 |
85 bool UseSendSideBwe(const FlexfecReceiveStream::Config& config) { | |
86 return UseSendSideBwe(config.rtp_header_extensions, config.transport_cc); | |
87 } | |
88 | |
89 const int* FindKeyByValue(const std::map<int, int>& m, int v) { | 82 const int* FindKeyByValue(const std::map<int, int>& m, int v) { |
90 for (const auto& kv : m) { | 83 for (const auto& kv : m) { |
91 if (kv.second == v) | 84 if (kv.second == v) |
92 return &kv.first; | 85 return &kv.first; |
93 } | 86 } |
94 return nullptr; | 87 return nullptr; |
95 } | 88 } |
96 | 89 |
97 std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig( | 90 std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig( |
98 const VideoReceiveStream::Config& config) { | 91 const VideoReceiveStream::Config& config) { |
99 auto rtclog_config = rtc::MakeUnique<rtclog::StreamConfig>(); | 92 auto rtclog_config = rtc::MakeUnique<rtclog::StreamConfig>(); |
100 rtclog_config->remote_ssrc = config.rtp.remote_ssrc; | 93 rtclog_config->remote_ssrc = config.rtp.remote_ssrc; |
101 rtclog_config->local_ssrc = config.rtp.local_ssrc; | 94 rtclog_config->local_ssrc = config.rtp.local_ssrc; |
102 rtclog_config->rtx_ssrc = config.rtp.rtx_ssrc; | 95 rtclog_config->rtx_ssrc = config.rtp.rtx_ssrc; |
103 rtclog_config->rtcp_mode = config.rtp.rtcp_mode; | 96 rtclog_config->rtcp_mode = config.rtp.rtcp_mode; |
104 rtclog_config->remb = config.rtp.remb; | 97 rtclog_config->remb = config.rtp.remb; |
| 98 #if 0 |
105 rtclog_config->rtp_extensions = config.rtp.extensions; | 99 rtclog_config->rtp_extensions = config.rtp.extensions; |
106 | 100 #endif |
107 for (const auto& d : config.decoders) { | 101 for (const auto& d : config.decoders) { |
108 const int* search = | 102 const int* search = |
109 FindKeyByValue(config.rtp.rtx_associated_payload_types, d.payload_type); | 103 FindKeyByValue(config.rtp.rtx_associated_payload_types, d.payload_type); |
110 rtclog_config->codecs.emplace_back(d.payload_name, d.payload_type, | 104 rtclog_config->codecs.emplace_back(d.payload_name, d.payload_type, |
111 search ? *search : 0); | 105 search ? *search : 0); |
112 } | 106 } |
113 return rtclog_config; | 107 return rtclog_config; |
114 } | 108 } |
115 | 109 |
116 std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig( | 110 std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 public SendSideCongestionController::Observer, | 155 public SendSideCongestionController::Observer, |
162 public BitrateAllocator::LimitObserver { | 156 public BitrateAllocator::LimitObserver { |
163 public: | 157 public: |
164 Call(const Call::Config& config, | 158 Call(const Call::Config& config, |
165 std::unique_ptr<RtpTransportControllerSendInterface> transport_send); | 159 std::unique_ptr<RtpTransportControllerSendInterface> transport_send); |
166 virtual ~Call(); | 160 virtual ~Call(); |
167 | 161 |
168 // Implements webrtc::Call. | 162 // Implements webrtc::Call. |
169 PacketReceiver* Receiver() override; | 163 PacketReceiver* Receiver() override; |
170 | 164 |
| 165 void SetVideoReceiveRtpHeaderExtensions( |
| 166 const std::vector<RtpExtension>& extensions) override; |
| 167 |
171 webrtc::AudioSendStream* CreateAudioSendStream( | 168 webrtc::AudioSendStream* CreateAudioSendStream( |
172 const webrtc::AudioSendStream::Config& config) override; | 169 const webrtc::AudioSendStream::Config& config) override; |
173 void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override; | 170 void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override; |
174 | 171 |
175 webrtc::AudioReceiveStream* CreateAudioReceiveStream( | 172 webrtc::AudioReceiveStream* CreateAudioReceiveStream( |
176 const webrtc::AudioReceiveStream::Config& config) override; | 173 const webrtc::AudioReceiveStream::Config& config) override; |
177 void DestroyAudioReceiveStream( | 174 void DestroyAudioReceiveStream( |
178 webrtc::AudioReceiveStream* receive_stream) override; | 175 webrtc::AudioReceiveStream* receive_stream) override; |
179 | 176 |
180 webrtc::VideoSendStream* CreateVideoSendStream( | 177 webrtc::VideoSendStream* CreateVideoSendStream( |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 RTC_GUARDED_BY(receive_crit_); | 277 RTC_GUARDED_BY(receive_crit_); |
281 | 278 |
282 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_ | 279 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_ |
283 RTC_GUARDED_BY(receive_crit_); | 280 RTC_GUARDED_BY(receive_crit_); |
284 | 281 |
285 // TODO(nisse): Should eventually be injected at creation, | 282 // TODO(nisse): Should eventually be injected at creation, |
286 // with a single object in the bundled case. | 283 // with a single object in the bundled case. |
287 RtpStreamReceiverController audio_receiver_controller_; | 284 RtpStreamReceiverController audio_receiver_controller_; |
288 RtpStreamReceiverController video_receiver_controller_; | 285 RtpStreamReceiverController video_receiver_controller_; |
289 | 286 |
| 287 std::vector<RtpExtension> video_rtp_header_extensions_ |
| 288 RTC_GUARDED_BY(receive_crit_); |
| 289 |
290 // This extra map is used for receive processing which is | 290 // This extra map is used for receive processing which is |
291 // independent of media type. | 291 // independent of media type. |
292 | 292 |
293 // TODO(nisse): In the RTP transport refactoring, we should have a | 293 // TODO(nisse): In the RTP transport refactoring, we should have a |
294 // single mapping from ssrc to a more abstract receive stream, with | 294 // single mapping from ssrc to a more abstract receive stream, with |
295 // accessor methods for all configuration we need at this level. | 295 // accessor methods for all configuration we need at this level. |
296 struct ReceiveRtpConfig { | 296 struct ReceiveRtpConfig { |
297 ReceiveRtpConfig() = default; // Needed by std::map | 297 ReceiveRtpConfig() = default; // Needed by std::map |
298 ReceiveRtpConfig(const std::vector<RtpExtension>& extensions, | 298 ReceiveRtpConfig(const std::vector<RtpExtension>& extensions, |
299 bool use_send_side_bwe) | 299 bool use_send_side_bwe) |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 LOG(LS_INFO) << "WebRTC.Call.BitrateReceivedInBps, " | 598 LOG(LS_INFO) << "WebRTC.Call.BitrateReceivedInBps, " |
599 << recv_bytes_per_sec.ToStringWithMultiplier(8); | 599 << recv_bytes_per_sec.ToStringWithMultiplier(8); |
600 } | 600 } |
601 } | 601 } |
602 | 602 |
603 PacketReceiver* Call::Receiver() { | 603 PacketReceiver* Call::Receiver() { |
604 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 604 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
605 return this; | 605 return this; |
606 } | 606 } |
607 | 607 |
| 608 void Call::SetVideoReceiveRtpHeaderExtensions( |
| 609 const std::vector<RtpExtension>& extensions) { |
| 610 WriteLockScoped write_lock(*receive_crit_); |
| 611 video_rtp_header_extensions_ = extensions; |
| 612 } |
| 613 |
608 webrtc::AudioSendStream* Call::CreateAudioSendStream( | 614 webrtc::AudioSendStream* Call::CreateAudioSendStream( |
609 const webrtc::AudioSendStream::Config& config) { | 615 const webrtc::AudioSendStream::Config& config) { |
610 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); | 616 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); |
611 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 617 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
612 event_log_->LogAudioSendStreamConfig(*CreateRtcLogStreamConfig(config)); | 618 event_log_->LogAudioSendStreamConfig(*CreateRtcLogStreamConfig(config)); |
613 | 619 |
614 rtc::Optional<RtpState> suspended_rtp_state; | 620 rtc::Optional<RtpState> suspended_rtp_state; |
615 { | 621 { |
616 const auto& iter = suspended_audio_send_ssrcs_.find(config.rtp.ssrc); | 622 const auto& iter = suspended_audio_send_ssrcs_.find(config.rtp.ssrc); |
617 if (iter != suspended_audio_send_ssrcs_.end()) { | 623 if (iter != suspended_audio_send_ssrcs_.end()) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 webrtc::VideoReceiveStream::Config configuration) { | 808 webrtc::VideoReceiveStream::Config configuration) { |
803 TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream"); | 809 TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream"); |
804 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 810 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
805 | 811 |
806 VideoReceiveStream* receive_stream = new VideoReceiveStream( | 812 VideoReceiveStream* receive_stream = new VideoReceiveStream( |
807 &video_receiver_controller_, num_cpu_cores_, | 813 &video_receiver_controller_, num_cpu_cores_, |
808 transport_send_->packet_router(), std::move(configuration), | 814 transport_send_->packet_router(), std::move(configuration), |
809 module_process_thread_.get(), call_stats_.get()); | 815 module_process_thread_.get(), call_stats_.get()); |
810 | 816 |
811 const webrtc::VideoReceiveStream::Config& config = receive_stream->config(); | 817 const webrtc::VideoReceiveStream::Config& config = receive_stream->config(); |
812 ReceiveRtpConfig receive_config(config.rtp.extensions, | |
813 UseSendSideBwe(config)); | |
814 { | 818 { |
815 WriteLockScoped write_lock(*receive_crit_); | 819 WriteLockScoped write_lock(*receive_crit_); |
| 820 ReceiveRtpConfig receive_config( |
| 821 video_rtp_header_extensions_, |
| 822 UseSendSideBwe(video_rtp_header_extensions_, |
| 823 configuration.rtp.transport_cc)); |
816 if (config.rtp.rtx_ssrc) { | 824 if (config.rtp.rtx_ssrc) { |
817 // We record identical config for the rtx stream as for the main | 825 // We record identical config for the rtx stream as for the main |
818 // stream. Since the transport_send_cc negotiation is per payload | 826 // stream. Since the transport_send_cc negotiation is per payload |
819 // type, we may get an incorrect value for the rtx stream, but | 827 // type, we may get an incorrect value for the rtx stream, but |
820 // that is unlikely to matter in practice. | 828 // that is unlikely to matter in practice. |
821 receive_rtp_config_[config.rtp.rtx_ssrc] = receive_config; | 829 receive_rtp_config_[config.rtp.rtx_ssrc] = receive_config; |
822 } | 830 } |
823 receive_rtp_config_[config.rtp.remote_ssrc] = receive_config; | 831 receive_rtp_config_[config.rtp.remote_ssrc] = receive_config; |
824 video_receive_streams_.insert(receive_stream); | 832 video_receive_streams_.insert(receive_stream); |
825 ConfigureSync(config.sync_group); | 833 ConfigureSync(config.sync_group); |
826 } | 834 } |
827 receive_stream->SignalNetworkState(video_network_state_); | 835 receive_stream->SignalNetworkState(video_network_state_); |
828 UpdateAggregateNetworkState(); | 836 UpdateAggregateNetworkState(); |
829 event_log_->LogVideoReceiveStreamConfig(*CreateRtcLogStreamConfig(config)); | 837 event_log_->LogVideoReceiveStreamConfig(*CreateRtcLogStreamConfig(config)); |
830 return receive_stream; | 838 return receive_stream; |
831 } | 839 } |
832 | 840 |
833 void Call::DestroyVideoReceiveStream( | 841 void Call::DestroyVideoReceiveStream( |
834 webrtc::VideoReceiveStream* receive_stream) { | 842 webrtc::VideoReceiveStream* receive_stream) { |
835 TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream"); | 843 TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream"); |
836 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 844 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
837 RTC_DCHECK(receive_stream != nullptr); | 845 RTC_DCHECK(receive_stream != nullptr); |
838 VideoReceiveStream* receive_stream_impl = | 846 VideoReceiveStream* receive_stream_impl = |
839 static_cast<VideoReceiveStream*>(receive_stream); | 847 static_cast<VideoReceiveStream*>(receive_stream); |
840 const VideoReceiveStream::Config& config = receive_stream_impl->config(); | 848 const VideoReceiveStream::Config& config = receive_stream_impl->config(); |
| 849 |
841 { | 850 { |
842 WriteLockScoped write_lock(*receive_crit_); | 851 WriteLockScoped write_lock(*receive_crit_); |
| 852 receive_side_cc_.GetRemoteBitrateEstimator( |
| 853 receive_rtp_config_[config.rtp.remote_ssrc].use_send_side_bwe) |
| 854 ->RemoveStream(config.rtp.remote_ssrc); |
843 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a | 855 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a |
844 // separate SSRC there can be either one or two. | 856 // separate SSRC there can be either one or two. |
845 receive_rtp_config_.erase(config.rtp.remote_ssrc); | 857 receive_rtp_config_.erase(config.rtp.remote_ssrc); |
846 if (config.rtp.rtx_ssrc) { | 858 if (config.rtp.rtx_ssrc) { |
847 receive_rtp_config_.erase(config.rtp.rtx_ssrc); | 859 receive_rtp_config_.erase(config.rtp.rtx_ssrc); |
848 } | 860 } |
849 video_receive_streams_.erase(receive_stream_impl); | 861 video_receive_streams_.erase(receive_stream_impl); |
850 ConfigureSync(config.sync_group); | 862 ConfigureSync(config.sync_group); |
851 } | 863 } |
852 | 864 |
853 receive_side_cc_.GetRemoteBitrateEstimator(UseSendSideBwe(config)) | |
854 ->RemoveStream(config.rtp.remote_ssrc); | |
855 | |
856 UpdateAggregateNetworkState(); | 865 UpdateAggregateNetworkState(); |
857 delete receive_stream_impl; | 866 delete receive_stream_impl; |
858 } | 867 } |
859 | 868 |
860 FlexfecReceiveStream* Call::CreateFlexfecReceiveStream( | 869 FlexfecReceiveStream* Call::CreateFlexfecReceiveStream( |
861 const FlexfecReceiveStream::Config& config) { | 870 const FlexfecReceiveStream::Config& config) { |
862 TRACE_EVENT0("webrtc", "Call::CreateFlexfecReceiveStream"); | 871 TRACE_EVENT0("webrtc", "Call::CreateFlexfecReceiveStream"); |
863 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 872 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
864 | 873 |
865 RecoveredPacketReceiver* recovered_packet_receiver = this; | 874 RecoveredPacketReceiver* recovered_packet_receiver = this; |
(...skipping 10 matching lines...) Expand all Loading... |
876 // object is in a valid state. | 885 // object is in a valid state. |
877 // TODO(nisse): Fix constructor so that it can be moved outside of | 886 // TODO(nisse): Fix constructor so that it can be moved outside of |
878 // this locked scope. | 887 // this locked scope. |
879 receive_stream = new FlexfecReceiveStreamImpl( | 888 receive_stream = new FlexfecReceiveStreamImpl( |
880 &video_receiver_controller_, config, recovered_packet_receiver, | 889 &video_receiver_controller_, config, recovered_packet_receiver, |
881 call_stats_->rtcp_rtt_stats(), module_process_thread_.get()); | 890 call_stats_->rtcp_rtt_stats(), module_process_thread_.get()); |
882 | 891 |
883 RTC_DCHECK(receive_rtp_config_.find(config.remote_ssrc) == | 892 RTC_DCHECK(receive_rtp_config_.find(config.remote_ssrc) == |
884 receive_rtp_config_.end()); | 893 receive_rtp_config_.end()); |
885 receive_rtp_config_[config.remote_ssrc] = | 894 receive_rtp_config_[config.remote_ssrc] = |
886 ReceiveRtpConfig(config.rtp_header_extensions, UseSendSideBwe(config)); | 895 ReceiveRtpConfig(video_rtp_header_extensions_, |
| 896 config.transport_cc && |
| 897 UseTransportSeqno(video_rtp_header_extensions_)); |
887 } | 898 } |
888 | 899 |
889 // TODO(brandtr): Store config in RtcEventLog here. | 900 // TODO(brandtr): Store config in RtcEventLog here. |
890 | 901 |
891 return receive_stream; | 902 return receive_stream; |
892 } | 903 } |
893 | 904 |
894 void Call::DestroyFlexfecReceiveStream(FlexfecReceiveStream* receive_stream) { | 905 void Call::DestroyFlexfecReceiveStream(FlexfecReceiveStream* receive_stream) { |
895 TRACE_EVENT0("webrtc", "Call::DestroyFlexfecReceiveStream"); | 906 TRACE_EVENT0("webrtc", "Call::DestroyFlexfecReceiveStream"); |
896 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 907 RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
897 | 908 |
898 RTC_DCHECK(receive_stream != nullptr); | 909 RTC_DCHECK(receive_stream != nullptr); |
899 { | 910 { |
900 WriteLockScoped write_lock(*receive_crit_); | 911 WriteLockScoped write_lock(*receive_crit_); |
901 | 912 |
902 const FlexfecReceiveStream::Config& config = receive_stream->GetConfig(); | 913 const FlexfecReceiveStream::Config& config = receive_stream->GetConfig(); |
903 uint32_t ssrc = config.remote_ssrc; | 914 uint32_t ssrc = config.remote_ssrc; |
| 915 receive_side_cc_.GetRemoteBitrateEstimator( |
| 916 receive_rtp_config_[ssrc].use_send_side_bwe) |
| 917 ->RemoveStream(ssrc); |
904 receive_rtp_config_.erase(ssrc); | 918 receive_rtp_config_.erase(ssrc); |
905 | |
906 // Remove all SSRCs pointing to the FlexfecReceiveStreamImpl to be | |
907 // destroyed. | |
908 receive_side_cc_.GetRemoteBitrateEstimator(UseSendSideBwe(config)) | |
909 ->RemoveStream(ssrc); | |
910 } | 919 } |
911 | 920 |
912 delete receive_stream; | 921 delete receive_stream; |
913 } | 922 } |
914 | 923 |
915 Call::Stats Call::GetStats() const { | 924 Call::Stats Call::GetStats() const { |
916 // TODO(solenberg): Some test cases in EndToEndTest use this from a different | 925 // TODO(solenberg): Some test cases in EndToEndTest use this from a different |
917 // thread. Re-enable once that is fixed. | 926 // thread. Re-enable once that is fixed. |
918 // RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); | 927 // RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_); |
919 Stats stats; | 928 Stats stats; |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 (use_send_side_bwe && header.extension.hasTransportSequenceNumber)) { | 1448 (use_send_side_bwe && header.extension.hasTransportSequenceNumber)) { |
1440 receive_side_cc_.OnReceivedPacket( | 1449 receive_side_cc_.OnReceivedPacket( |
1441 packet.arrival_time_ms(), packet.payload_size() + packet.padding_size(), | 1450 packet.arrival_time_ms(), packet.payload_size() + packet.padding_size(), |
1442 header); | 1451 header); |
1443 } | 1452 } |
1444 } | 1453 } |
1445 | 1454 |
1446 } // namespace internal | 1455 } // namespace internal |
1447 | 1456 |
1448 } // namespace webrtc | 1457 } // namespace webrtc |
OLD | NEW |