Skip to content

Commit c563a12

Browse files
committed
Start/Stop receiving stream method for VideoTrack (#25)
* Initial implementation of start/stop receive * move set_state call to signalling thread as well. https://source.chromium.org/chromium/_/webrtc/src.git/+/dfd69c22100e1d2e83295f33d06fa9916caa5c53 * separate should_receive from enabled for now * ios hooks * Fix ios compile errors * code cleanup * clean up * reuse frame buffers instead
1 parent 7d273ab commit c563a12

17 files changed

+167
-3
lines changed

api/media_stream_interface.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ const char* const MediaStreamTrackInterface::kVideoKind =
1818
const char* const MediaStreamTrackInterface::kAudioKind =
1919
cricket::kMediaTypeAudio;
2020

21+
bool VideoTrackInterface::should_receive() const {
22+
return true;
23+
}
24+
2125
VideoTrackInterface::ContentHint VideoTrackInterface::content_hint() const {
2226
return ContentHint::kNone;
2327
}

api/media_stream_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ class RTC_EXPORT VideoTrackInterface
188188

189189
virtual VideoTrackSourceInterface* GetSource() const = 0;
190190

191+
virtual void set_should_receive(bool should_receive) {}
192+
virtual bool should_receive() const;
191193
virtual ContentHint content_hint() const;
192194
virtual void set_content_hint(ContentHint hint) {}
193195

media/base/media_channel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,9 @@ class VideoMediaChannel : public MediaChannel, public Delayable {
913913
virtual void GenerateKeyFrame(uint32_t ssrc) = 0;
914914

915915
virtual std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const = 0;
916+
917+
virtual void StartReceive(uint32_t ssrc) {}
918+
virtual void StopReceive(uint32_t ssrc) {}
916919
};
917920

918921
// Info about data received in DataMediaChannel. For use in

media/engine/webrtc_video_engine.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,24 @@ void WebRtcVideoChannel::RequestEncoderSwitch(
970970
}
971971
}
972972

973+
void WebRtcVideoChannel::StartReceive(uint32_t ssrc) {
974+
RTC_DCHECK_RUN_ON(&thread_checker_);
975+
WebRtcVideoReceiveStream* stream = FindReceiveStream(ssrc);
976+
if(!stream) {
977+
return;
978+
}
979+
stream->StartStream();
980+
}
981+
982+
void WebRtcVideoChannel::StopReceive(uint32_t ssrc) {
983+
RTC_DCHECK_RUN_ON(&thread_checker_);
984+
WebRtcVideoReceiveStream* stream = FindReceiveStream(ssrc);
985+
if(!stream) {
986+
return;
987+
}
988+
stream->StopStream();
989+
}
990+
973991
bool WebRtcVideoChannel::ApplyChangedParams(
974992
const ChangedSendParameters& changed_params) {
975993
RTC_DCHECK_RUN_ON(&thread_checker_);
@@ -3056,6 +3074,17 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
30563074
}
30573075
}
30583076

3077+
void WebRtcVideoChannel::WebRtcVideoReceiveStream::StartStream(){
3078+
if (stream_) {
3079+
stream_->Start();
3080+
}
3081+
}
3082+
void WebRtcVideoChannel::WebRtcVideoReceiveStream::StopStream(){
3083+
if (stream_) {
3084+
stream_->Stop();
3085+
}
3086+
}
3087+
30593088
void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() {
30603089
absl::optional<int> base_minimum_playout_delay_ms;
30613090
absl::optional<webrtc::VideoReceiveStreamInterface::RecordingState>

media/engine/webrtc_video_engine.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ class WebRtcVideoChannel : public VideoMediaChannel,
254254
uint32_t ssrc,
255255
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
256256
override;
257-
257+
void StartReceive(uint32_t ssrc) override;
258+
void StopReceive(uint32_t ssrc) override;
258259
private:
259260
class WebRtcVideoReceiveStream;
260261

@@ -501,6 +502,9 @@ class WebRtcVideoChannel : public VideoMediaChannel,
501502
void SetDepacketizerToDecoderFrameTransformer(
502503
rtc::scoped_refptr<webrtc::FrameTransformerInterface>
503504
frame_transformer);
505+
506+
void StartStream();
507+
void StopStream();
504508

505509
void SetLocalSsrc(uint32_t local_ssrc);
506510

modules/video_coding/frame_buffer2.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,13 @@ void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) {
332332
protection_mode_ = mode;
333333
}
334334

335+
void FrameBuffer::Start() {
336+
TRACE_EVENT0("webrtc", "FrameBuffer::Stop");
337+
MutexLock lock(&mutex_);
338+
if (!stopped_)
339+
return;
340+
stopped_ = false;
341+
}
335342
void FrameBuffer::Stop() {
336343
TRACE_EVENT0("webrtc", "FrameBuffer::Stop");
337344
MutexLock lock(&mutex_);

modules/video_coding/frame_buffer2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class FrameBuffer {
7878
// Stop the frame buffer, causing any sleeping thread in NextFrame to
7979
// return immediately.
8080
void Stop();
81+
// Unstop the frame buffer, re-allowing new frames to be inserted and read.
82+
void Start();
8183

8284
// Updates the RTT for jitter buffer estimation.
8385
void UpdateRtt(int64_t rtt_ms);

pc/media_stream_track_proxy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ PROXY_SECONDARY_METHOD2(void,
5555
PROXY_SECONDARY_METHOD1(void, RemoveSink, rtc::VideoSinkInterface<VideoFrame>*)
5656
PROXY_SECONDARY_METHOD0(void, RequestRefreshFrame)
5757
BYPASS_PROXY_CONSTMETHOD0(VideoTrackSourceInterface*, GetSource)
58+
PROXY_CONSTMETHOD0(bool, should_receive)
59+
PROXY_METHOD1(void, set_should_receive, bool)
5860

5961
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
6062
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)

pc/video_rtp_receiver.cc

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "rtc_base/location.h"
2323
#include "rtc_base/logging.h"
2424
#include "rtc_base/ref_counted_object.h"
25+
#include "rtc_base/task_utils/to_queued_task.h"
2526

2627
namespace webrtc {
2728

@@ -43,9 +44,12 @@ VideoRtpReceiver::VideoRtpReceiver(
4344
rtc::Thread::Current(),
4445
worker_thread,
4546
VideoTrack::Create(receiver_id, source_, worker_thread))),
46-
attachment_id_(GenerateUniqueId()) {
47+
cached_track_should_receive_(track_->should_receive()),
48+
attachment_id_(GenerateUniqueId()),
49+
worker_thread_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()) {
4750
RTC_DCHECK(worker_thread_);
4851
SetStreams(streams);
52+
track_->RegisterObserver(this);
4953
RTC_DCHECK_EQ(source_->state(), MediaSourceInterface::kInitializing);
5054
}
5155

@@ -114,6 +118,40 @@ void VideoRtpReceiver::Stop() {
114118
track_->internal()->set_ended();
115119
}
116120

121+
void VideoRtpReceiver::OnChanged() {
122+
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
123+
if (cached_track_should_receive_ != track_->should_receive()) {
124+
cached_track_should_receive_ = track_->should_receive();
125+
worker_thread_->PostTask(ToQueuedTask(
126+
worker_thread_safety_,
127+
[this, receive = cached_track_should_receive_]() {
128+
RTC_DCHECK_RUN_ON(worker_thread_);
129+
if(receive) {
130+
StartMediaChannel();
131+
} else {
132+
StopMediaChannel();
133+
}
134+
}));
135+
}
136+
}
137+
138+
void VideoRtpReceiver::StartMediaChannel() {
139+
RTC_DCHECK_RUN_ON(worker_thread_);
140+
if (!media_channel_) {
141+
return;
142+
}
143+
media_channel_->StartReceive(ssrc_.value_or(0));
144+
OnGenerateKeyFrame();
145+
}
146+
147+
void VideoRtpReceiver::StopMediaChannel() {
148+
RTC_DCHECK_RUN_ON(worker_thread_);
149+
if (!media_channel_) {
150+
return;
151+
}
152+
media_channel_->StopReceive(ssrc_.value_or(0));
153+
}
154+
117155
// RTC_RUN_ON(&signaling_thread_checker_)
118156
void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
119157
MediaSourceInterface::SourceState state = source_->state();
@@ -205,6 +243,7 @@ void VideoRtpReceiver::set_transport(
205243
void VideoRtpReceiver::SetStreams(
206244
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
207245
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
246+
208247
// Remove remote track from any streams that are going away.
209248
for (const auto& existing_stream : streams_) {
210249
bool removed = true;
@@ -276,6 +315,8 @@ void VideoRtpReceiver::SetMediaChannel_w(cricket::MediaChannel* media_channel) {
276315
SetEncodedSinkEnabled(false);
277316
}
278317

318+
media_channel ? worker_thread_safety_->SetAlive()
319+
: worker_thread_safety_->SetNotAlive();
279320
media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
280321

281322
if (media_channel_) {

pc/video_rtp_receiver.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343

4444
namespace webrtc {
4545

46-
class VideoRtpReceiver : public RtpReceiverInternal {
46+
class VideoRtpReceiver : public RtpReceiverInternal,
47+
public ObserverInterface {
4748
public:
4849
// An SSRC of 0 will create a receiver that will match the first SSRC it
4950
// sees. Must be called on signaling thread.
@@ -61,6 +62,9 @@ class VideoRtpReceiver : public RtpReceiverInternal {
6162

6263
rtc::scoped_refptr<VideoTrackInterface> video_track() const { return track_; }
6364

65+
// ObserverInterface implementation
66+
void OnChanged() override;
67+
6468
// RtpReceiverInterface implementation
6569
rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
6670
return track_;
@@ -115,6 +119,8 @@ class VideoRtpReceiver : public RtpReceiverInternal {
115119
cricket::MediaChannel* media_channel);
116120

117121
private:
122+
void StartMediaChannel();
123+
void StopMediaChannel();
118124
void RestartMediaChannel(absl::optional<uint32_t> ssrc)
119125
RTC_RUN_ON(&signaling_thread_checker_);
120126
void RestartMediaChannel_w(absl::optional<uint32_t> ssrc,
@@ -162,6 +168,8 @@ class VideoRtpReceiver : public RtpReceiverInternal {
162168
RTC_GUARDED_BY(&signaling_thread_checker_) = nullptr;
163169
bool received_first_packet_ RTC_GUARDED_BY(&signaling_thread_checker_) =
164170
false;
171+
172+
bool cached_track_should_receive_ RTC_GUARDED_BY(&signaling_thread_checker_);
165173
const int attachment_id_;
166174
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_
167175
RTC_GUARDED_BY(worker_thread_);
@@ -177,6 +185,7 @@ class VideoRtpReceiver : public RtpReceiverInternal {
177185
// or switched.
178186
bool saved_generate_keyframe_ RTC_GUARDED_BY(worker_thread_) = false;
179187
bool saved_encoded_sink_enabled_ RTC_GUARDED_BY(worker_thread_) = false;
188+
const rtc::scoped_refptr<PendingTaskSafetyFlag> worker_thread_safety_;
180189
};
181190

182191
} // namespace webrtc

0 commit comments

Comments
 (0)