OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2012 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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 // there. | 585 // there. |
586 if (!network_thread()->Invoke<bool>( | 586 if (!network_thread()->Invoke<bool>( |
587 RTC_FROM_HERE, rtc::Bind(&PeerConnection::InitializePortAllocator_n, | 587 RTC_FROM_HERE, rtc::Bind(&PeerConnection::InitializePortAllocator_n, |
588 this, configuration))) { | 588 this, configuration))) { |
589 return false; | 589 return false; |
590 } | 590 } |
591 | 591 |
592 media_controller_.reset( | 592 media_controller_.reset( |
593 factory_->CreateMediaController(configuration.media_config)); | 593 factory_->CreateMediaController(configuration.media_config)); |
594 | 594 |
595 session_.reset( | 595 session_.reset(new WebRtcSession( |
596 new WebRtcSession(media_controller_.get(), factory_->network_thread(), | 596 media_controller_.get(), factory_->network_thread(), |
597 factory_->worker_thread(), factory_->signaling_thread(), | 597 factory_->worker_thread(), factory_->signaling_thread(), |
598 port_allocator_.get())); | 598 port_allocator_.get(), |
| 599 std::unique_ptr<cricket::TransportController>( |
| 600 factory_->CreateTransportController(port_allocator_.get())))); |
| 601 |
599 stats_.reset(new StatsCollector(this)); | 602 stats_.reset(new StatsCollector(this)); |
600 | 603 |
601 // Initialize the WebRtcSession. It creates transport channels etc. | 604 // Initialize the WebRtcSession. It creates transport channels etc. |
602 if (!session_->Initialize(factory_->options(), std::move(cert_generator), | 605 if (!session_->Initialize(factory_->options(), std::move(cert_generator), |
603 configuration)) { | 606 configuration)) { |
604 return false; | 607 return false; |
605 } | 608 } |
606 | 609 |
607 // Register PeerConnection as receiver of local ice candidates. | 610 // Register PeerConnection as receiver of local ice candidates. |
608 // All the callbacks will be posted to the application from PeerConnection. | 611 // All the callbacks will be posted to the application from PeerConnection. |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 (*it)->internal()->Stop(); | 762 (*it)->internal()->Stop(); |
760 senders_.erase(it); | 763 senders_.erase(it); |
761 | 764 |
762 observer_->OnRenegotiationNeeded(); | 765 observer_->OnRenegotiationNeeded(); |
763 return true; | 766 return true; |
764 } | 767 } |
765 | 768 |
766 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( | 769 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( |
767 AudioTrackInterface* track) { | 770 AudioTrackInterface* track) { |
768 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); | 771 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); |
| 772 if (IsClosed()) { |
| 773 return nullptr; |
| 774 } |
769 if (!track) { | 775 if (!track) { |
770 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL."; | 776 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL."; |
771 return NULL; | 777 return NULL; |
772 } | 778 } |
773 if (!local_streams_->FindAudioTrack(track->id())) { | 779 if (!local_streams_->FindAudioTrack(track->id())) { |
774 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track."; | 780 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track."; |
775 return NULL; | 781 return NULL; |
776 } | 782 } |
777 | 783 |
778 rtc::scoped_refptr<DtmfSenderInterface> sender( | 784 rtc::scoped_refptr<DtmfSenderInterface> sender( |
779 DtmfSender::Create(track, signaling_thread(), session_.get())); | 785 DtmfSender::Create(track, signaling_thread(), session_.get())); |
780 if (!sender.get()) { | 786 if (!sender.get()) { |
781 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; | 787 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; |
782 return NULL; | 788 return NULL; |
783 } | 789 } |
784 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); | 790 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); |
785 } | 791 } |
786 | 792 |
787 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( | 793 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( |
788 const std::string& kind, | 794 const std::string& kind, |
789 const std::string& stream_id) { | 795 const std::string& stream_id) { |
790 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender"); | 796 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender"); |
| 797 if (IsClosed()) { |
| 798 return nullptr; |
| 799 } |
791 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender; | 800 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender; |
792 if (kind == MediaStreamTrackInterface::kAudioKind) { | 801 if (kind == MediaStreamTrackInterface::kAudioKind) { |
793 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( | 802 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( |
794 signaling_thread(), new AudioRtpSender(session_.get(), stats_.get())); | 803 signaling_thread(), new AudioRtpSender(session_.get(), stats_.get())); |
795 } else if (kind == MediaStreamTrackInterface::kVideoKind) { | 804 } else if (kind == MediaStreamTrackInterface::kVideoKind) { |
796 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( | 805 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( |
797 signaling_thread(), new VideoRtpSender(session_.get())); | 806 signaling_thread(), new VideoRtpSender(session_.get())); |
798 } else { | 807 } else { |
799 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind; | 808 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind; |
800 return new_sender; | 809 return new_sender; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 return; | 1000 return; |
992 } | 1001 } |
993 | 1002 |
994 session_->CreateAnswer(observer, session_options); | 1003 session_->CreateAnswer(observer, session_options); |
995 } | 1004 } |
996 | 1005 |
997 void PeerConnection::SetLocalDescription( | 1006 void PeerConnection::SetLocalDescription( |
998 SetSessionDescriptionObserver* observer, | 1007 SetSessionDescriptionObserver* observer, |
999 SessionDescriptionInterface* desc) { | 1008 SessionDescriptionInterface* desc) { |
1000 TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription"); | 1009 TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription"); |
| 1010 if (IsClosed()) { |
| 1011 return; |
| 1012 } |
1001 if (!VERIFY(observer != nullptr)) { | 1013 if (!VERIFY(observer != nullptr)) { |
1002 LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; | 1014 LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; |
1003 return; | 1015 return; |
1004 } | 1016 } |
1005 if (!desc) { | 1017 if (!desc) { |
1006 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); | 1018 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); |
1007 return; | 1019 return; |
1008 } | 1020 } |
1009 // Update stats here so that we have the most recent stats for tracks and | 1021 // Update stats here so that we have the most recent stats for tracks and |
1010 // streams that might be removed by updating the session description. | 1022 // streams that might be removed by updating the session description. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 // MaybeStartGathering needs to be called after posting | 1082 // MaybeStartGathering needs to be called after posting |
1071 // MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates | 1083 // MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates |
1072 // before signaling that SetLocalDescription completed. | 1084 // before signaling that SetLocalDescription completed. |
1073 session_->MaybeStartGathering(); | 1085 session_->MaybeStartGathering(); |
1074 } | 1086 } |
1075 | 1087 |
1076 void PeerConnection::SetRemoteDescription( | 1088 void PeerConnection::SetRemoteDescription( |
1077 SetSessionDescriptionObserver* observer, | 1089 SetSessionDescriptionObserver* observer, |
1078 SessionDescriptionInterface* desc) { | 1090 SessionDescriptionInterface* desc) { |
1079 TRACE_EVENT0("webrtc", "PeerConnection::SetRemoteDescription"); | 1091 TRACE_EVENT0("webrtc", "PeerConnection::SetRemoteDescription"); |
| 1092 if (IsClosed()) { |
| 1093 return; |
| 1094 } |
1080 if (!VERIFY(observer != nullptr)) { | 1095 if (!VERIFY(observer != nullptr)) { |
1081 LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; | 1096 LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; |
1082 return; | 1097 return; |
1083 } | 1098 } |
1084 if (!desc) { | 1099 if (!desc) { |
1085 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); | 1100 PostSetSessionDescriptionFailure(observer, "SessionDescription is NULL."); |
1086 return; | 1101 return; |
1087 } | 1102 } |
1088 // Update stats here so that we have the most recent stats for tracks and | 1103 // Update stats here so that we have the most recent stats for tracks and |
1089 // streams that might be removed by updating the session description. | 1104 // streams that might be removed by updating the session description. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 } | 1207 } |
1193 | 1208 |
1194 // TODO(deadbeef): Shouldn't have to hop to the worker thread twice... | 1209 // TODO(deadbeef): Shouldn't have to hop to the worker thread twice... |
1195 session_->SetIceConfig(session_->ParseIceConfig(configuration)); | 1210 session_->SetIceConfig(session_->ParseIceConfig(configuration)); |
1196 return true; | 1211 return true; |
1197 } | 1212 } |
1198 | 1213 |
1199 bool PeerConnection::AddIceCandidate( | 1214 bool PeerConnection::AddIceCandidate( |
1200 const IceCandidateInterface* ice_candidate) { | 1215 const IceCandidateInterface* ice_candidate) { |
1201 TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); | 1216 TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); |
| 1217 if (IsClosed()) { |
| 1218 return false; |
| 1219 } |
1202 return session_->ProcessIceMessage(ice_candidate); | 1220 return session_->ProcessIceMessage(ice_candidate); |
1203 } | 1221 } |
1204 | 1222 |
1205 bool PeerConnection::RemoveIceCandidates( | 1223 bool PeerConnection::RemoveIceCandidates( |
1206 const std::vector<cricket::Candidate>& candidates) { | 1224 const std::vector<cricket::Candidate>& candidates) { |
1207 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates"); | 1225 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates"); |
1208 return session_->RemoveRemoteIceCandidates(candidates); | 1226 return session_->RemoveRemoteIceCandidates(candidates); |
1209 } | 1227 } |
1210 | 1228 |
1211 void PeerConnection::RegisterUMAObserver(UMAObserver* observer) { | 1229 void PeerConnection::RegisterUMAObserver(UMAObserver* observer) { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 RTC_DCHECK(signaling_thread()->IsCurrent()); | 1397 RTC_DCHECK(signaling_thread()->IsCurrent()); |
1380 if (IsClosed()) { | 1398 if (IsClosed()) { |
1381 return; | 1399 return; |
1382 } | 1400 } |
1383 ice_gathering_state_ = new_state; | 1401 ice_gathering_state_ = new_state; |
1384 observer_->OnIceGatheringChange(ice_gathering_state_); | 1402 observer_->OnIceGatheringChange(ice_gathering_state_); |
1385 } | 1403 } |
1386 | 1404 |
1387 void PeerConnection::OnIceCandidate(const IceCandidateInterface* candidate) { | 1405 void PeerConnection::OnIceCandidate(const IceCandidateInterface* candidate) { |
1388 RTC_DCHECK(signaling_thread()->IsCurrent()); | 1406 RTC_DCHECK(signaling_thread()->IsCurrent()); |
| 1407 if (IsClosed()) { |
| 1408 return; |
| 1409 } |
1389 observer_->OnIceCandidate(candidate); | 1410 observer_->OnIceCandidate(candidate); |
1390 } | 1411 } |
1391 | 1412 |
1392 void PeerConnection::OnIceCandidatesRemoved( | 1413 void PeerConnection::OnIceCandidatesRemoved( |
1393 const std::vector<cricket::Candidate>& candidates) { | 1414 const std::vector<cricket::Candidate>& candidates) { |
1394 RTC_DCHECK(signaling_thread()->IsCurrent()); | 1415 RTC_DCHECK(signaling_thread()->IsCurrent()); |
| 1416 if (IsClosed()) { |
| 1417 return; |
| 1418 } |
1395 observer_->OnIceCandidatesRemoved(candidates); | 1419 observer_->OnIceCandidatesRemoved(candidates); |
1396 } | 1420 } |
1397 | 1421 |
1398 void PeerConnection::OnIceConnectionReceivingChange(bool receiving) { | 1422 void PeerConnection::OnIceConnectionReceivingChange(bool receiving) { |
1399 RTC_DCHECK(signaling_thread()->IsCurrent()); | 1423 RTC_DCHECK(signaling_thread()->IsCurrent()); |
| 1424 if (IsClosed()) { |
| 1425 return; |
| 1426 } |
1400 observer_->OnIceConnectionReceivingChange(receiving); | 1427 observer_->OnIceConnectionReceivingChange(receiving); |
1401 } | 1428 } |
1402 | 1429 |
1403 void PeerConnection::ChangeSignalingState( | 1430 void PeerConnection::ChangeSignalingState( |
1404 PeerConnectionInterface::SignalingState signaling_state) { | 1431 PeerConnectionInterface::SignalingState signaling_state) { |
1405 signaling_state_ = signaling_state; | 1432 signaling_state_ = signaling_state; |
1406 if (signaling_state == kClosed) { | 1433 if (signaling_state == kClosed) { |
1407 ice_connection_state_ = kIceConnectionClosed; | 1434 ice_connection_state_ = kIceConnectionClosed; |
1408 observer_->OnIceConnectionChange(ice_connection_state_); | 1435 observer_->OnIceConnectionChange(ice_connection_state_); |
1409 if (ice_gathering_state_ != kIceGatheringComplete) { | 1436 if (ice_gathering_state_ != kIceGatheringComplete) { |
1410 ice_gathering_state_ = kIceGatheringComplete; | 1437 ice_gathering_state_ = kIceGatheringComplete; |
1411 observer_->OnIceGatheringChange(ice_gathering_state_); | 1438 observer_->OnIceGatheringChange(ice_gathering_state_); |
1412 } | 1439 } |
1413 } | 1440 } |
1414 observer_->OnSignalingChange(signaling_state_); | 1441 observer_->OnSignalingChange(signaling_state_); |
1415 } | 1442 } |
1416 | 1443 |
1417 void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, | 1444 void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, |
1418 MediaStreamInterface* stream) { | 1445 MediaStreamInterface* stream) { |
| 1446 if (IsClosed()) { |
| 1447 return; |
| 1448 } |
1419 auto sender = FindSenderForTrack(track); | 1449 auto sender = FindSenderForTrack(track); |
1420 if (sender != senders_.end()) { | 1450 if (sender != senders_.end()) { |
1421 // We already have a sender for this track, so just change the stream_id | 1451 // We already have a sender for this track, so just change the stream_id |
1422 // so that it's correct in the next call to CreateOffer. | 1452 // so that it's correct in the next call to CreateOffer. |
1423 (*sender)->internal()->set_stream_id(stream->label()); | 1453 (*sender)->internal()->set_stream_id(stream->label()); |
1424 return; | 1454 return; |
1425 } | 1455 } |
1426 | 1456 |
1427 // Normal case; we've never seen this track before. | 1457 // Normal case; we've never seen this track before. |
1428 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender = | 1458 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender = |
(...skipping 11 matching lines...) Expand all Loading... |
1440 FindTrackInfo(local_audio_tracks_, stream->label(), track->id()); | 1470 FindTrackInfo(local_audio_tracks_, stream->label(), track->id()); |
1441 if (track_info) { | 1471 if (track_info) { |
1442 new_sender->internal()->SetSsrc(track_info->ssrc); | 1472 new_sender->internal()->SetSsrc(track_info->ssrc); |
1443 } | 1473 } |
1444 } | 1474 } |
1445 | 1475 |
1446 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around | 1476 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around |
1447 // indefinitely, when we have unified plan SDP. | 1477 // indefinitely, when we have unified plan SDP. |
1448 void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, | 1478 void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, |
1449 MediaStreamInterface* stream) { | 1479 MediaStreamInterface* stream) { |
| 1480 if (IsClosed()) { |
| 1481 return; |
| 1482 } |
1450 auto sender = FindSenderForTrack(track); | 1483 auto sender = FindSenderForTrack(track); |
1451 if (sender == senders_.end()) { | 1484 if (sender == senders_.end()) { |
1452 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() | 1485 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
1453 << " doesn't exist."; | 1486 << " doesn't exist."; |
1454 return; | 1487 return; |
1455 } | 1488 } |
1456 (*sender)->internal()->Stop(); | 1489 (*sender)->internal()->Stop(); |
1457 senders_.erase(sender); | 1490 senders_.erase(sender); |
1458 } | 1491 } |
1459 | 1492 |
1460 void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, | 1493 void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, |
1461 MediaStreamInterface* stream) { | 1494 MediaStreamInterface* stream) { |
| 1495 if (IsClosed()) { |
| 1496 return; |
| 1497 } |
1462 auto sender = FindSenderForTrack(track); | 1498 auto sender = FindSenderForTrack(track); |
1463 if (sender != senders_.end()) { | 1499 if (sender != senders_.end()) { |
1464 // We already have a sender for this track, so just change the stream_id | 1500 // We already have a sender for this track, so just change the stream_id |
1465 // so that it's correct in the next call to CreateOffer. | 1501 // so that it's correct in the next call to CreateOffer. |
1466 (*sender)->internal()->set_stream_id(stream->label()); | 1502 (*sender)->internal()->set_stream_id(stream->label()); |
1467 return; | 1503 return; |
1468 } | 1504 } |
1469 | 1505 |
1470 // Normal case; we've never seen this track before. | 1506 // Normal case; we've never seen this track before. |
1471 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender = | 1507 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender = |
1472 RtpSenderProxyWithInternal<RtpSenderInternal>::Create( | 1508 RtpSenderProxyWithInternal<RtpSenderInternal>::Create( |
1473 signaling_thread(), | 1509 signaling_thread(), |
1474 new VideoRtpSender(track, stream->label(), session_.get())); | 1510 new VideoRtpSender(track, stream->label(), session_.get())); |
1475 senders_.push_back(new_sender); | 1511 senders_.push_back(new_sender); |
1476 const TrackInfo* track_info = | 1512 const TrackInfo* track_info = |
1477 FindTrackInfo(local_video_tracks_, stream->label(), track->id()); | 1513 FindTrackInfo(local_video_tracks_, stream->label(), track->id()); |
1478 if (track_info) { | 1514 if (track_info) { |
1479 new_sender->internal()->SetSsrc(track_info->ssrc); | 1515 new_sender->internal()->SetSsrc(track_info->ssrc); |
1480 } | 1516 } |
1481 } | 1517 } |
1482 | 1518 |
1483 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, | 1519 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, |
1484 MediaStreamInterface* stream) { | 1520 MediaStreamInterface* stream) { |
| 1521 if (IsClosed()) { |
| 1522 return; |
| 1523 } |
1485 auto sender = FindSenderForTrack(track); | 1524 auto sender = FindSenderForTrack(track); |
1486 if (sender == senders_.end()) { | 1525 if (sender == senders_.end()) { |
1487 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() | 1526 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
1488 << " doesn't exist."; | 1527 << " doesn't exist."; |
1489 return; | 1528 return; |
1490 } | 1529 } |
1491 (*sender)->internal()->Stop(); | 1530 (*sender)->internal()->Stop(); |
1492 senders_.erase(sender); | 1531 senders_.erase(sender); |
1493 } | 1532 } |
1494 | 1533 |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2187 port_allocator_->set_candidate_filter( | 2226 port_allocator_->set_candidate_filter( |
2188 ConvertIceTransportTypeToCandidateFilter(configuration.type)); | 2227 ConvertIceTransportTypeToCandidateFilter(configuration.type)); |
2189 // Call this last since it may create pooled allocator sessions using the | 2228 // Call this last since it may create pooled allocator sessions using the |
2190 // candidate filter set above. | 2229 // candidate filter set above. |
2191 port_allocator_->SetConfiguration(stun_servers, turn_servers, | 2230 port_allocator_->SetConfiguration(stun_servers, turn_servers, |
2192 configuration.ice_candidate_pool_size); | 2231 configuration.ice_candidate_pool_size); |
2193 return true; | 2232 return true; |
2194 } | 2233 } |
2195 | 2234 |
2196 } // namespace webrtc | 2235 } // namespace webrtc |
OLD | NEW |