When stopping a transceiver, end the receiver's track.

Bug: webrtc:11840
Change-Id: Ib8171c58fcb13c33ab03398eb3021c07e55ff008
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185181
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32188}
This commit is contained in:
Harald Alvestrand 2020-09-24 13:31:15 +00:00 committed by Commit Bot
parent 39a3f081c1
commit 1ee3325051
10 changed files with 77 additions and 8 deletions

View File

@ -42,8 +42,9 @@ AudioRtpReceiver::AudioRtpReceiver(
: worker_thread_(worker_thread),
id_(receiver_id),
source_(new rtc::RefCountedObject<RemoteAudioSource>(worker_thread)),
track_(AudioTrackProxy::Create(rtc::Thread::Current(),
AudioTrack::Create(receiver_id, source_))),
track_(AudioTrackProxyWithInternal<AudioTrack>::Create(
rtc::Thread::Current(),
AudioTrack::Create(receiver_id, source_))),
cached_track_enabled_(track_->enabled()),
attachment_id_(GenerateUniqueId()),
delay_(JitterBufferDelayProxy::Create(
@ -146,6 +147,11 @@ void AudioRtpReceiver::Stop() {
stopped_ = true;
}
void AudioRtpReceiver::StopAndEndTrack() {
Stop();
track_->internal()->set_ended();
}
void AudioRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
RTC_DCHECK(media_channel_);
if (!stopped_ && ssrc_ == ssrc) {

View File

@ -19,10 +19,12 @@
#include "absl/types/optional.h"
#include "api/crypto/frame_decryptor_interface.h"
#include "api/media_stream_interface.h"
#include "api/media_stream_track_proxy.h"
#include "api/media_types.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "media/base/media_channel.h"
#include "pc/audio_track.h"
#include "pc/jitter_buffer_delay_interface.h"
#include "pc/remote_audio_source.h"
#include "pc/rtp_receiver.h"
@ -84,6 +86,7 @@ class AudioRtpReceiver : public ObserverInterface,
// RtpReceiverInternal implementation.
void Stop() override;
void StopAndEndTrack() override;
void SetupMediaChannel(uint32_t ssrc) override;
void SetupUnsignaledMediaChannel() override;
uint32_t ssrc() const override { return ssrc_.value_or(0); }
@ -116,7 +119,7 @@ class AudioRtpReceiver : public ObserverInterface,
rtc::Thread* const worker_thread_;
const std::string id_;
const rtc::scoped_refptr<RemoteAudioSource> source_;
const rtc::scoped_refptr<AudioTrackInterface> track_;
const rtc::scoped_refptr<AudioTrackProxyWithInternal<AudioTrack>> track_;
cricket::VoiceMediaChannel* media_channel_ = nullptr;
absl::optional<uint32_t> ssrc_;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_;

View File

@ -34,10 +34,10 @@ class AudioTrack : public MediaStreamTrack<AudioTrackInterface>,
const std::string& id,
const rtc::scoped_refptr<AudioSourceInterface>& source);
private:
// MediaStreamTrack implementation.
std::string kind() const override;
private:
// AudioTrackInterface implementation.
AudioSourceInterface* GetSource() const override;

View File

@ -15,6 +15,7 @@
#include "api/media_stream_interface.h"
#include "api/notifier.h"
#include "rtc_base/logging.h"
namespace webrtc {
@ -38,6 +39,7 @@ class MediaStreamTrack : public Notifier<T> {
}
return fire_on_change;
}
void set_ended() { set_state(MediaStreamTrackInterface::TrackState::kEnded); }
protected:
explicit MediaStreamTrack(const std::string& id)

View File

@ -5603,6 +5603,52 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
PeerConnectionInterface::kIceGatheringNew));
}
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
StopTransceiverEndsIncomingAudioTrack) {
RTCConfiguration config;
ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
ConnectFakeSignaling();
auto audio_transceiver_or_error =
caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
ASSERT_TRUE(audio_transceiver_or_error.ok());
auto audio_transceiver = audio_transceiver_or_error.MoveValue();
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
auto caller_track = audio_transceiver->receiver()->track();
auto callee_track = callee()->pc()->GetReceivers()[0]->track();
audio_transceiver->StopStandard();
EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
caller_track->state());
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
callee_track->state());
}
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
StopTransceiverEndsIncomingVideoTrack) {
RTCConfiguration config;
ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
ConnectFakeSignaling();
auto audio_transceiver_or_error =
caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
ASSERT_TRUE(audio_transceiver_or_error.ok());
auto audio_transceiver = audio_transceiver_or_error.MoveValue();
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
auto caller_track = audio_transceiver->receiver()->track();
auto callee_track = callee()->pc()->GetReceivers()[0]->track();
audio_transceiver->StopStandard();
EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
caller_track->state());
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
callee_track->state());
}
#ifdef HAVE_SCTP
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,

View File

@ -41,7 +41,11 @@ namespace webrtc {
// Internal class used by PeerConnection.
class RtpReceiverInternal : public RtpReceiverInterface {
public:
// Stops receiving. The track may be reactivated.
virtual void Stop() = 0;
// Stops the receiver permanently.
// Causes the associated track to enter kEnded state. Cannot be reversed.
virtual void StopAndEndTrack() = 0;
// Sets the underlying MediaEngine channel associated with this RtpSender.
// A VoiceMediaChannel should be used for audio RtpSenders and

View File

@ -346,7 +346,7 @@ void RtpTransceiver::StopSendingAndReceiving() {
// 5. Stop receiving media with receiver.
for (const auto& receiver : receivers_)
receiver->internal()->Stop();
receiver->internal()->StopAndEndTrack();
stopping_ = true;
direction_ = webrtc::RtpTransceiverDirection::kInactive;

View File

@ -57,6 +57,7 @@ class MockRtpReceiverInternal : public RtpReceiverInternal {
// RtpReceiverInternal methods.
MOCK_METHOD(void, Stop, (), (override));
MOCK_METHOD(void, StopAndEndTrack, (), (override));
MOCK_METHOD(void, SetMediaChannel, (cricket::MediaChannel*), (override));
MOCK_METHOD(void, SetupMediaChannel, (uint32_t), (override));
MOCK_METHOD(void, SetupUnsignaledMediaChannel, (), (override));

View File

@ -16,7 +16,6 @@
#include <vector>
#include "api/media_stream_proxy.h"
#include "api/media_stream_track_proxy.h"
#include "api/video_track_source_proxy.h"
#include "pc/jitter_buffer_delay.h"
#include "pc/jitter_buffer_delay_proxy.h"
@ -43,7 +42,7 @@ VideoRtpReceiver::VideoRtpReceiver(
: worker_thread_(worker_thread),
id_(receiver_id),
source_(new RefCountedObject<VideoRtpTrackSource>(this)),
track_(VideoTrackProxy::Create(
track_(VideoTrackProxyWithInternal<VideoTrack>::Create(
rtc::Thread::Current(),
worker_thread,
VideoTrack::Create(
@ -136,6 +135,11 @@ void VideoRtpReceiver::Stop() {
stopped_ = true;
}
void VideoRtpReceiver::StopAndEndTrack() {
Stop();
track_->internal()->set_ended();
}
void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
RTC_DCHECK(media_channel_);
if (!stopped_ && ssrc_ == ssrc) {

View File

@ -20,6 +20,7 @@
#include "api/crypto/frame_decryptor_interface.h"
#include "api/frame_transformer_interface.h"
#include "api/media_stream_interface.h"
#include "api/media_stream_track_proxy.h"
#include "api/media_types.h"
#include "api/rtp_parameters.h"
#include "api/rtp_receiver_interface.h"
@ -31,6 +32,7 @@
#include "pc/jitter_buffer_delay_interface.h"
#include "pc/rtp_receiver.h"
#include "pc/video_rtp_track_source.h"
#include "pc/video_track.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/thread.h"
@ -89,6 +91,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal>,
// RtpReceiverInternal implementation.
void Stop() override;
void StopAndEndTrack() override;
void SetupMediaChannel(uint32_t ssrc) override;
void SetupUnsignaledMediaChannel() override;
uint32_t ssrc() const override { return ssrc_.value_or(0); }
@ -130,7 +133,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal>,
// |source_| is held here to be able to change the state of the source when
// the VideoRtpReceiver is stopped.
rtc::scoped_refptr<VideoRtpTrackSource> source_;
rtc::scoped_refptr<VideoTrackInterface> track_;
rtc::scoped_refptr<VideoTrackProxyWithInternal<VideoTrack>> track_;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_;
bool stopped_ = true;
RtpReceiverObserverInterface* observer_ = nullptr;