Adding "first packet received" notification to PeerConnectionObserver.
R=glaznev@webrtc.org, pthatcher@webrtc.org, tkchin@webrtc.org
Review URL: https://codereview.webrtc.org/1581693006 .
Cr-Commit-Position: refs/heads/master@{#11401}
diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc
index 1e138f6..85e10a9 100644
--- a/talk/app/webrtc/java/jni/peerconnection_jni.cc
+++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc
@@ -374,6 +374,14 @@
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}
+ void OnFirstMediaPacketReceived() override {
+ ScopedLocalRefFrame local_ref_frame(jni());
+ jmethodID m = GetMethodID(jni(), *j_observer_class_,
+ "onFirstMediaPacketReceived", "()V");
+ jni()->CallVoidMethod(*j_observer_global_, m);
+ CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
+ }
+
void SetConstraints(ConstraintsWrapper* constraints) {
RTC_CHECK(!constraints_.get()) << "constraints already set!";
constraints_.reset(constraints);
diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
index 36cd075..331c062 100644
--- a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
+++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
@@ -86,6 +86,9 @@
/** Triggered when renegotiation is necessary. */
public void onRenegotiationNeeded();
+
+ /** Called when the first RTP packet is received. */
+ public void onFirstMediaPacketReceived();
}
/** Java version of PeerConnectionInterface.IceServer. */
diff --git a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java b/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
index 50f4d73..8db0ded 100644
--- a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
+++ b/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
@@ -289,6 +289,9 @@
++expectedStatsCallbacks;
}
+ @Override
+ public synchronized void onFirstMediaPacketReceived() {}
+
public synchronized LinkedList<StatsReport[]> takeStatsReports() {
LinkedList<StatsReport[]> got = gotStatsReports;
gotStatsReports = new LinkedList<StatsReport[]>();
diff --git a/talk/app/webrtc/objc/RTCPeerConnectionObserver.h b/talk/app/webrtc/objc/RTCPeerConnectionObserver.h
index 9b981b9..f5fb8dc 100644
--- a/talk/app/webrtc/objc/RTCPeerConnectionObserver.h
+++ b/talk/app/webrtc/objc/RTCPeerConnectionObserver.h
@@ -68,6 +68,9 @@
// New Ice candidate have been found.
void OnIceCandidate(const IceCandidateInterface* candidate) override;
+ // Called when the first RTP packet is received.
+ void OnFirstMediaPacketReceived() override;
+
private:
__weak RTCPeerConnection* _peerConnection;
};
diff --git a/talk/app/webrtc/objc/RTCPeerConnectionObserver.mm b/talk/app/webrtc/objc/RTCPeerConnectionObserver.mm
index 411cd6c..47246cb 100644
--- a/talk/app/webrtc/objc/RTCPeerConnectionObserver.mm
+++ b/talk/app/webrtc/objc/RTCPeerConnectionObserver.mm
@@ -105,4 +105,9 @@
gotICECandidate:iceCandidate];
}
+void RTCPeerConnectionObserver::OnFirstMediaPacketReceived() {
+ id<RTCPeerConnectionDelegate> delegate = _peerConnection.delegate;
+ [delegate peerConnectionOnFirstMediaPacketReceived:_peerConnection];
+}
+
} // namespace webrtc
diff --git a/talk/app/webrtc/objc/public/RTCPeerConnectionDelegate.h b/talk/app/webrtc/objc/public/RTCPeerConnectionDelegate.h
index bf0c231..63529cb 100644
--- a/talk/app/webrtc/objc/public/RTCPeerConnectionDelegate.h
+++ b/talk/app/webrtc/objc/public/RTCPeerConnectionDelegate.h
@@ -69,4 +69,8 @@
- (void)peerConnection:(RTCPeerConnection*)peerConnection
didOpenDataChannel:(RTCDataChannel*)dataChannel;
+// Called when the first RTP packet is received.
+- (void)peerConnectionOnFirstMediaPacketReceived:
+ (RTCPeerConnection *)peerConnection;
+
@end
diff --git a/talk/app/webrtc/objctests/RTCPeerConnectionSyncObserver.m b/talk/app/webrtc/objctests/RTCPeerConnectionSyncObserver.m
index 892c461..3f23726 100644
--- a/talk/app/webrtc/objctests/RTCPeerConnectionSyncObserver.m
+++ b/talk/app/webrtc/objctests/RTCPeerConnectionSyncObserver.m
@@ -233,6 +233,10 @@
@"Unexpected state");
}
+- (void)peerConnectionOnFirstMediaPacketReceived:
+ (RTCPeerConnection*)peerConnection {
+}
+
#pragma mark - RTCDataChannelDelegate
- (void)channelDidChangeState:(RTCDataChannel*)channel {
diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc
index beae770..d2f8d77 100644
--- a/talk/app/webrtc/peerconnection.cc
+++ b/talk/app/webrtc/peerconnection.cc
@@ -663,6 +663,8 @@
this, &PeerConnection::OnDataChannelDestroyed);
session_->SignalDataChannelOpenMessage.connect(
this, &PeerConnection::OnDataChannelOpenMessage);
+ session_->SignalFirstMediaPacketReceived.connect(
+ this, &PeerConnection::OnFirstMediaPacketReceived);
return true;
}
@@ -2029,6 +2031,11 @@
DataChannelProxy::Create(signaling_thread(), channel));
}
+void PeerConnection::OnFirstMediaPacketReceived() {
+ RTC_DCHECK(signaling_thread()->IsCurrent());
+ observer_->OnFirstMediaPacketReceived();
+}
+
RtpSenderInterface* PeerConnection::FindSenderById(const std::string& id) {
auto it =
std::find_if(senders_.begin(), senders_.end(),
diff --git a/talk/app/webrtc/peerconnection.h b/talk/app/webrtc/peerconnection.h
index 03b5853..83c408b 100644
--- a/talk/app/webrtc/peerconnection.h
+++ b/talk/app/webrtc/peerconnection.h
@@ -326,6 +326,7 @@
// webrtc::DataChannel should be opened.
void OnDataChannelOpenMessage(const std::string& label,
const InternalDataChannelInit& config);
+ void OnFirstMediaPacketReceived();
RtpSenderInterface* FindSenderById(const std::string& id);
diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc
index cf53c44..9e5ca2f 100644
--- a/talk/app/webrtc/peerconnection_unittest.cc
+++ b/talk/app/webrtc/peerconnection_unittest.cc
@@ -251,6 +251,7 @@
signaling_message_receiver_->ReceiveIceMessage(
candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
}
+ void OnFirstMediaPacketReceived() override { received_media_packet_ = true; }
// MediaStreamInterface callback
void OnChanged() override {
@@ -386,6 +387,8 @@
return true;
}
+ bool received_media_packet() const { return received_media_packet_; }
+
void OnIceComplete() override { LOG(INFO) << id_ << "OnIceComplete"; }
void OnDataChannel(DataChannelInterface* data_channel) override {
@@ -924,6 +927,10 @@
rtc::scoped_refptr<DataChannelInterface> data_channel_;
rtc::scoped_ptr<MockDataChannelObserver> data_observer_;
+
+ // "true" if the PeerConnection indicated that a packet was received,
+ // through PeerConnectionObserverInterface.
+ bool received_media_packet_ = false;
};
class P2PTestConductor : public testing::Test {
@@ -1104,6 +1111,10 @@
EXPECT_TRUE_WAIT(FramesNotPending(audio_frame_count, video_frame_count),
kMaxWaitForFramesMs);
+ if (audio_frame_count != -1 || video_frame_count != -1) {
+ EXPECT_TRUE(initiating_client_->received_media_packet());
+ EXPECT_TRUE(receiving_client_->received_media_packet());
+ }
}
void SetupAndVerifyDtlsCall() {
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index e449dc4..42b5ae0 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -501,6 +501,9 @@
// Called when the ICE connection receiving status changes.
virtual void OnIceConnectionReceivingChange(bool receiving) {}
+ // Called when the first RTP packet is received.
+ virtual void OnFirstMediaPacketReceived() {}
+
protected:
// Dtor protected as objects shouldn't be deleted via this interface.
~PeerConnectionObserver() {}
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
index c6d1856..0270c55 100644
--- a/talk/app/webrtc/webrtcsession.cc
+++ b/talk/app/webrtc/webrtcsession.cc
@@ -1844,6 +1844,8 @@
voice_channel_->SignalDtlsSetupFailure.connect(
this, &WebRtcSession::OnDtlsSetupFailure);
+ voice_channel_->SignalFirstPacketReceived.connect(
+ this, &WebRtcSession::OnChannelFirstPacketReceived);
SignalVoiceChannelCreated();
voice_channel_->transport_channel()->SignalSentPacket.connect(
@@ -1861,6 +1863,8 @@
video_channel_->SignalDtlsSetupFailure.connect(
this, &WebRtcSession::OnDtlsSetupFailure);
+ video_channel_->SignalFirstPacketReceived.connect(
+ this, &WebRtcSession::OnChannelFirstPacketReceived);
SignalVideoChannelCreated();
video_channel_->transport_channel()->SignalSentPacket.connect(
@@ -1895,6 +1899,14 @@
rtcp ? kDtlsSetupFailureRtcp : kDtlsSetupFailureRtp);
}
+void WebRtcSession::OnChannelFirstPacketReceived(cricket::BaseChannel*) {
+ ASSERT(signaling_thread()->IsCurrent());
+ if (!has_received_media_packet_) {
+ has_received_media_packet_ = true;
+ SignalFirstMediaPacketReceived();
+ }
+}
+
void WebRtcSession::OnDataChannelMessageReceived(
cricket::DataChannel* channel,
const cricket::ReceiveDataParams& params,
diff --git a/talk/app/webrtc/webrtcsession.h b/talk/app/webrtc/webrtcsession.h
index cd3f896..3848014 100644
--- a/talk/app/webrtc/webrtcsession.h
+++ b/talk/app/webrtc/webrtcsession.h
@@ -309,6 +309,7 @@
void OnCertificateReady(
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
void OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp);
+ void OnChannelFirstPacketReceived(cricket::BaseChannel*);
// For unit test.
bool waiting_for_certificate_for_testing() const;
@@ -335,6 +336,9 @@
sigslot::signal2<const std::string&, const InternalDataChannelInit&>
SignalDataChannelOpenMessage;
+ // Called when the first RTP packet is received.
+ sigslot::signal0<> SignalFirstMediaPacketReceived;
+
private:
// Indicates the type of SessionDescription in a call to SetLocalDescription
// and SetRemoteDescription.
@@ -518,6 +522,8 @@
// Declares the RTCP mux policy for the WebRTCSession.
PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy_;
+ bool has_received_media_packet_ = false;
+
RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSession);
};
} // namespace webrtc
diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
index eb4d959..91f46b2 100644
--- a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
+++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
@@ -1000,6 +1000,10 @@
// No need to do anything; AppRTC follows a pre-agreed-upon
// signaling/negotiation protocol.
}
+
+ @Override
+ public void onFirstMediaPacketReceived() {
+ }
}
// Implementation detail: handle offer creation/signaling and answer setting,
diff --git a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
index 33e00ed..50fac5d 100644
--- a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
+++ b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
@@ -384,6 +384,11 @@
didOpenDataChannel:(RTCDataChannel *)dataChannel {
}
+- (void)peerConnectionOnFirstMediaPacketReceived:
+ (RTCPeerConnection *)peerConnection {
+ RTCLog(@"Received first media packet.");
+}
+
#pragma mark - RTCStatsDelegate
- (void)peerConnection:(RTCPeerConnection *)peerConnection