Add SetKeyFrameRequestCallback to MediaTransportInterface

And implemented in LoopbackMediaTransport.

Bug: webrtc:9719
Change-Id: I68b16c2b6ed5583ffe9a5266e3d4cb1d94afbb97
Reviewed-on: https://webrtc-review.googlesource.com/c/113523
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25948}
This commit is contained in:
Niels Möller
2018-12-10 11:06:02 +01:00
committed by Commit Bot
parent f04feee41e
commit 1c7f5f63d1
5 changed files with 75 additions and 0 deletions

View File

@ -158,6 +158,9 @@ MediaTransportFactory::CreateMediaTransport(
return std::unique_ptr<MediaTransportInterface>(nullptr);
}
void MediaTransportInterface::SetKeyFrameRequestCallback(
MediaTransportKeyFrameRequestCallback* callback) {}
absl::optional<TargetTransferRate>
MediaTransportInterface::GetLatestTargetTransferRate() {
return absl::nullopt;

View File

@ -239,6 +239,15 @@ class MediaTransportVideoSinkInterface {
RTC_DEPRECATED virtual void OnKeyFrameRequested(uint64_t channel_id) {}
};
// Interface for video sender to be notified of received key frame request.
class MediaTransportKeyFrameRequestCallback {
public:
virtual ~MediaTransportKeyFrameRequestCallback() = default;
// Called when a key frame request is received on the transport.
virtual void OnKeyFrameRequested(uint64_t channel_id) = 0;
};
// State of the media transport. Media transport begins in the pending state.
// It transitions to writable when it is ready to send media. It may transition
// back to pending if the connection is blocked. It may transition to closed at
@ -339,6 +348,10 @@ class MediaTransportInterface {
uint64_t channel_id,
const MediaTransportEncodedVideoFrame& frame) = 0;
// Used by video sender to be notified on key frame requests.
virtual void SetKeyFrameRequestCallback(
MediaTransportKeyFrameRequestCallback* callback);
// Requests a keyframe for the particular channel (stream). The caller should
// check that the keyframe is not present in a jitter buffer already (i.e.
// don't request a keyframe if there is one that you will get from the jitter

View File

@ -34,6 +34,11 @@ class WrapperMediaTransport : public MediaTransportInterface {
return wrapped_->SendVideoFrame(channel_id, frame);
}
void SetKeyFrameRequestCallback(
MediaTransportKeyFrameRequestCallback* callback) override {
wrapped_->SetKeyFrameRequestCallback(callback);
}
RTCError RequestKeyFrame(uint64_t channel_id) override {
return wrapped_->RequestKeyFrame(channel_id);
}
@ -125,8 +130,20 @@ RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
return RTCError::OK();
}
void MediaTransportPair::LoopbackMediaTransport::SetKeyFrameRequestCallback(
MediaTransportKeyFrameRequestCallback* callback) {
rtc::CritScope lock(&sink_lock_);
if (callback) {
RTC_CHECK(key_frame_callback_ == nullptr);
}
key_frame_callback_ = callback;
}
RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
uint64_t channel_id) {
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
other_->OnKeyFrameRequested(channel_id);
});
return RTCError::OK();
}
@ -245,6 +262,14 @@ void MediaTransportPair::LoopbackMediaTransport::OnData(
}
}
void MediaTransportPair::LoopbackMediaTransport::OnKeyFrameRequested(
int channel_id) {
rtc::CritScope lock(&sink_lock_);
if (key_frame_callback_) {
key_frame_callback_->OnKeyFrameRequested(channel_id);
}
}
void MediaTransportPair::LoopbackMediaTransport::OnRemoteCloseChannel(
int channel_id) {
rtc::CritScope lock(&sink_lock_);

View File

@ -90,6 +90,9 @@ class MediaTransportPair {
uint64_t channel_id,
const MediaTransportEncodedVideoFrame& frame) override;
void SetKeyFrameRequestCallback(
MediaTransportKeyFrameRequestCallback* callback) override;
RTCError RequestKeyFrame(uint64_t channel_id) override;
void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override;
@ -122,6 +125,8 @@ class MediaTransportPair {
DataMessageType type,
const rtc::CopyOnWriteBuffer& buffer);
void OnKeyFrameRequested(int channel_id);
void OnRemoteCloseChannel(int channel_id);
void OnStateChanged() RTC_RUN_ON(thread_);
@ -135,6 +140,10 @@ class MediaTransportPair {
MediaTransportVideoSinkInterface* video_sink_ RTC_GUARDED_BY(sink_lock_) =
nullptr;
DataChannelSink* data_sink_ RTC_GUARDED_BY(sink_lock_) = nullptr;
MediaTransportKeyFrameRequestCallback* key_frame_callback_
RTC_GUARDED_BY(sink_lock_) = nullptr;
MediaTransportStateCallback* state_callback_ RTC_GUARDED_BY(sink_lock_) =
nullptr;

View File

@ -29,6 +29,11 @@ class MockMediaTransportVideoSinkInterface
: public MediaTransportVideoSinkInterface {
public:
MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedVideoFrame));
};
class MockMediaTransportKeyFrameRequestCallback
: public MediaTransportKeyFrameRequestCallback {
public:
MOCK_METHOD1(OnKeyFrameRequested, void(uint64_t));
};
@ -125,6 +130,26 @@ TEST(LoopbackMediaTransport, VideoDeliveredToSink) {
transport_pair.second()->SetReceiveVideoSink(nullptr);
}
TEST(LoopbackMediaTransport, VideoKeyFrameRequestDeliveredToCallback) {
std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
thread->Start();
MediaTransportPair transport_pair(thread.get());
testing::StrictMock<MockMediaTransportKeyFrameRequestCallback> callback1;
testing::StrictMock<MockMediaTransportKeyFrameRequestCallback> callback2;
const uint64_t kFirstChannelId = 1111;
const uint64_t kSecondChannelId = 2222;
EXPECT_CALL(callback1, OnKeyFrameRequested(kSecondChannelId));
EXPECT_CALL(callback2, OnKeyFrameRequested(kFirstChannelId));
transport_pair.first()->SetKeyFrameRequestCallback(&callback1);
transport_pair.second()->SetKeyFrameRequestCallback(&callback2);
transport_pair.first()->RequestKeyFrame(kFirstChannelId);
transport_pair.second()->RequestKeyFrame(kSecondChannelId);
transport_pair.FlushAsyncInvokes();
}
TEST(LoopbackMediaTransport, DataDeliveredToSink) {
std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
thread->Start();