Skip to content

Commit

Permalink
Android improvements.
Browse files Browse the repository at this point in the history
Start/Stop receiving stream method for VideoTrack (#25)

Properly remove observer upon deconstruction (#26)

feat: Expose setCodecPreferences/getCapabilities for android. (#61)

Co-authored-by: davidliu <davidliu@deviange.net>
  • Loading branch information
davidliu authored and cloudwebrtc committed Jun 12, 2023
1 parent 03dc44e commit c70cf2e
Show file tree
Hide file tree
Showing 22 changed files with 491 additions and 2 deletions.
4 changes: 4 additions & 0 deletions api/media_stream_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const char* const MediaStreamTrackInterface::kVideoKind =
const char* const MediaStreamTrackInterface::kAudioKind =
cricket::kMediaTypeAudio;

bool VideoTrackInterface::should_receive() const {
return true;
}

VideoTrackInterface::ContentHint VideoTrackInterface::content_hint() const {
return ContentHint::kNone;
}
Expand Down
2 changes: 2 additions & 0 deletions api/media_stream_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ class RTC_EXPORT VideoTrackInterface

virtual VideoTrackSourceInterface* GetSource() const = 0;

virtual void set_should_receive(bool should_receive) {}
virtual bool should_receive() const;
virtual ContentHint content_hint() const;
virtual void set_content_hint(ContentHint hint) {}

Expand Down
2 changes: 2 additions & 0 deletions media/base/media_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,8 @@ class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface {
bool nack_enabled,
webrtc::RtcpMode rtcp_mode,
absl::optional<int> rtx_time) = 0;
virtual void StartReceive(uint32_t ssrc) {}
virtual void StopReceive(uint32_t ssrc) {}
};

} // namespace cricket
Expand Down
29 changes: 29 additions & 0 deletions media/engine/webrtc_video_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,24 @@ void WebRtcVideoChannel::RequestEncoderSwitch(
}
}

void WebRtcVideoChannel::StartReceive(uint32_t ssrc) {
RTC_DCHECK_RUN_ON(&thread_checker_);
WebRtcVideoReceiveStream* stream = FindReceiveStream(ssrc);
if(!stream) {
return;
}
stream->StartStream();
}

void WebRtcVideoChannel::StopReceive(uint32_t ssrc) {
RTC_DCHECK_RUN_ON(&thread_checker_);
WebRtcVideoReceiveStream* stream = FindReceiveStream(ssrc);
if(!stream) {
return;
}
stream->StopStream();
}

bool WebRtcVideoChannel::ApplyChangedParams(
const ChangedSendParameters& changed_params) {
RTC_DCHECK_RUN_ON(&thread_checker_);
Expand Down Expand Up @@ -3182,6 +3200,17 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
}
}

void WebRtcVideoChannel::WebRtcVideoReceiveStream::StartStream(){
if (stream_) {
stream_->Start();
}
}
void WebRtcVideoChannel::WebRtcVideoReceiveStream::StopStream(){
if (stream_) {
stream_->Stop();
}
}

void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() {
RTC_DCHECK(stream_);
absl::optional<int> base_minimum_playout_delay_ms;
Expand Down
5 changes: 5 additions & 0 deletions media/engine/webrtc_video_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ class WebRtcVideoChannel : public VideoMediaChannel,
webrtc::RtcpMode rtcp_mode,
absl::optional<int> rtx_time) override;

void StartReceive(uint32_t ssrc) override;
void StopReceive(uint32_t ssrc) override;
private:
class WebRtcVideoReceiveStream;

Expand Down Expand Up @@ -537,6 +539,9 @@ class WebRtcVideoChannel : public VideoMediaChannel,
void SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface>
frame_transformer);

void StartStream();
void StopStream();

void SetLocalSsrc(uint32_t local_ssrc);
void UpdateRtxSsrc(uint32_t ssrc);
Expand Down
2 changes: 2 additions & 0 deletions pc/media_stream_track_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ PROXY_SECONDARY_METHOD2(void,
PROXY_SECONDARY_METHOD1(void, RemoveSink, rtc::VideoSinkInterface<VideoFrame>*)
PROXY_SECONDARY_METHOD0(void, RequestRefreshFrame)
BYPASS_PROXY_CONSTMETHOD0(VideoTrackSourceInterface*, GetSource)
PROXY_CONSTMETHOD0(bool, should_receive)
PROXY_METHOD1(void, set_should_receive, bool)

PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
Expand Down
41 changes: 40 additions & 1 deletion pc/video_rtp_receiver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,20 @@ VideoRtpReceiver::VideoRtpReceiver(
rtc::Thread::Current(),
worker_thread,
VideoTrack::Create(receiver_id, source_, worker_thread))),
attachment_id_(GenerateUniqueId()) {
cached_track_should_receive_(track_->should_receive()),
attachment_id_(GenerateUniqueId()),
worker_thread_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()) {
RTC_DCHECK(worker_thread_);
SetStreams(streams);
track_->RegisterObserver(this);
RTC_DCHECK_EQ(source_->state(), MediaSourceInterface::kInitializing);
}

VideoRtpReceiver::~VideoRtpReceiver() {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
RTC_DCHECK(!media_channel_);

track_->UnregisterObserver(this);
}

std::vector<std::string> VideoRtpReceiver::stream_ids() const {
Expand Down Expand Up @@ -114,6 +119,39 @@ void VideoRtpReceiver::Stop() {
track_->internal()->set_ended();
}

void VideoRtpReceiver::OnChanged() {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
if (cached_track_should_receive_ != track_->should_receive()) {
cached_track_should_receive_ = track_->should_receive();
worker_thread_->PostTask(
[this, receive = cached_track_should_receive_]() {
RTC_DCHECK_RUN_ON(worker_thread_);
if(receive) {
StartMediaChannel();
} else {
StopMediaChannel();
}
});
}
}

void VideoRtpReceiver::StartMediaChannel() {
RTC_DCHECK_RUN_ON(worker_thread_);
if (!media_channel_) {
return;
}
media_channel_->StartReceive(signaled_ssrc_.value_or(0));
OnGenerateKeyFrame();
}

void VideoRtpReceiver::StopMediaChannel() {
RTC_DCHECK_RUN_ON(worker_thread_);
if (!media_channel_) {
return;
}
media_channel_->StopReceive(signaled_ssrc_.value_or(0));
}

void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
MediaSourceInterface::SourceState state = source_->state();
Expand Down Expand Up @@ -209,6 +247,7 @@ void VideoRtpReceiver::set_transport(
void VideoRtpReceiver::SetStreams(
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);

// Remove remote track from any streams that are going away.
for (const auto& existing_stream : streams_) {
bool removed = true;
Expand Down
11 changes: 10 additions & 1 deletion pc/video_rtp_receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@

namespace webrtc {

class VideoRtpReceiver : public RtpReceiverInternal {
class VideoRtpReceiver : public RtpReceiverInternal,
public ObserverInterface {
public:
// An SSRC of 0 will create a receiver that will match the first SSRC it
// sees. Must be called on signaling thread.
Expand All @@ -60,6 +61,9 @@ class VideoRtpReceiver : public RtpReceiverInternal {

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

// ObserverInterface implementation
void OnChanged() override;

// RtpReceiverInterface implementation
rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
return track_;
Expand Down Expand Up @@ -115,6 +119,8 @@ class VideoRtpReceiver : public RtpReceiverInternal {
cricket::MediaReceiveChannelInterface* media_channel);

private:
void StartMediaChannel();
void StopMediaChannel();
void RestartMediaChannel(absl::optional<uint32_t> ssrc)
RTC_RUN_ON(&signaling_thread_checker_);
void RestartMediaChannel_w(absl::optional<uint32_t> ssrc,
Expand Down Expand Up @@ -162,6 +168,8 @@ class VideoRtpReceiver : public RtpReceiverInternal {
RTC_GUARDED_BY(&signaling_thread_checker_) = nullptr;
bool received_first_packet_ RTC_GUARDED_BY(&signaling_thread_checker_) =
false;

bool cached_track_should_receive_ RTC_GUARDED_BY(&signaling_thread_checker_);
const int attachment_id_;
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_
RTC_GUARDED_BY(worker_thread_);
Expand All @@ -177,6 +185,7 @@ class VideoRtpReceiver : public RtpReceiverInternal {
// or switched.
bool saved_generate_keyframe_ RTC_GUARDED_BY(worker_thread_) = false;
bool saved_encoded_sink_enabled_ RTC_GUARDED_BY(worker_thread_) = false;
const rtc::scoped_refptr<PendingTaskSafetyFlag> worker_thread_safety_;
};

} // namespace webrtc
Expand Down
13 changes: 13 additions & 0 deletions pc/video_track.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ VideoTrackSourceInterface* VideoTrack::GetSourceInternal() const {
return video_source_->internal();
}

void VideoTrack::set_should_receive(bool receive) {
RTC_DCHECK_RUN_ON(&signaling_thread_);
if (should_receive_ == receive)
return;
should_receive_ = receive;
Notifier<VideoTrackInterface>::FireOnChanged();
}

bool VideoTrack::should_receive() const {
RTC_DCHECK_RUN_ON(&signaling_thread_);
return should_receive_;
}

VideoTrackInterface::ContentHint VideoTrack::content_hint() const {
RTC_DCHECK_RUN_ON(&signaling_thread_);
return content_hint_;
Expand Down
4 changes: 4 additions & 0 deletions pc/video_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,
void RequestRefreshFrame() override;
VideoTrackSourceInterface* GetSource() const override;

void set_should_receive(bool should_receive) override;
bool should_receive() const override;

ContentHint content_hint() const override;
void set_content_hint(ContentHint hint) override;
bool set_enabled(bool enable) override;
Expand Down Expand Up @@ -81,6 +84,7 @@ class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,
// be queried without blocking on the worker thread by callers that don't
// use an api proxy to call the `enabled()` method.
bool enabled_w_ RTC_GUARDED_BY(worker_thread_) = true;
bool should_receive_ RTC_GUARDED_BY(signaling_thread_) = true;
};

} // namespace webrtc
Expand Down
4 changes: 4 additions & 0 deletions sdk/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ if (is_android) {
"api/org/webrtc/RTCStatsCollectorCallback.java",
"api/org/webrtc/RTCStatsReport.java",
"api/org/webrtc/RtcCertificatePem.java",
"api/org/webrtc/RtpCapabilities.java",
"api/org/webrtc/RtpParameters.java",
"api/org/webrtc/RtpReceiver.java",
"api/org/webrtc/RtpSender.java",
Expand Down Expand Up @@ -736,6 +737,8 @@ if (current_os == "linux" || is_android) {
"src/jni/pc/rtc_certificate.h",
"src/jni/pc/rtc_stats_collector_callback_wrapper.cc",
"src/jni/pc/rtc_stats_collector_callback_wrapper.h",
"src/jni/pc/rtp_capabilities.cc",
"src/jni/pc/rtp_capabilities.h",
"src/jni/pc/rtp_parameters.cc",
"src/jni/pc/rtp_parameters.h",
"src/jni/pc/rtp_receiver.cc",
Expand Down Expand Up @@ -1409,6 +1412,7 @@ if (current_os == "linux" || is_android) {
"api/org/webrtc/RTCStatsCollectorCallback.java",
"api/org/webrtc/RTCStatsReport.java",
"api/org/webrtc/RtcCertificatePem.java",
"api/org/webrtc/RtpCapabilities.java",
"api/org/webrtc/RtpParameters.java",
"api/org/webrtc/RtpReceiver.java",
"api/org/webrtc/RtpSender.java",
Expand Down
13 changes: 13 additions & 0 deletions sdk/android/api/org/webrtc/PeerConnectionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.webrtc.PeerConnection;
import org.webrtc.audio.AudioDeviceModule;
import org.webrtc.audio.JavaAudioDeviceModule;
import org.webrtc.RtpCapabilities;

/**
* Java wrapper for a C++ PeerConnectionFactoryInterface. Main entry point to
Expand Down Expand Up @@ -471,6 +472,16 @@ public AudioTrack createAudioTrack(String id, AudioSource source) {
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.getNativeAudioSource()));
}

public RtpCapabilities getRtpReceiverCapabilities(MediaStreamTrack.MediaType mediaType) {
checkPeerConnectionFactoryExists();
return nativeGetRtpReceiverCapabilities(nativeFactory, mediaType);
}

public RtpCapabilities getRtpSenderCapabilities(MediaStreamTrack.MediaType mediaType) {
checkPeerConnectionFactoryExists();
return nativeGetRtpSenderCapabilities(nativeFactory, mediaType);
}

// Starts recording an AEC dump. Ownership of the file is transfered to the
// native code. If an AEC dump is already in progress, it will be stopped and
// a new one will start using the provided file.
Expand Down Expand Up @@ -615,4 +626,6 @@ private static native boolean nativeStartAecDump(
private static native void nativeInjectLoggable(JNILogging jniLogging, int severity);
private static native void nativeDeleteLoggable();
private static native void nativePrintStackTrace(int tid);
private static native RtpCapabilities nativeGetRtpSenderCapabilities(long factory, MediaStreamTrack.MediaType mediaType);
private static native RtpCapabilities nativeGetRtpReceiverCapabilities(long factory, MediaStreamTrack.MediaType mediaType);
}
Loading

0 comments on commit c70cf2e

Please sign in to comment.