Propagate MediaStreamSource state to video tracks the same way as audio.
Also removes unused track states kLive and kFailed. Since this also required a Video source to exist in all unit tests that create a track, a FakeVideoTrackSource is added and used in tests. BUG=webrtc:5426 Review URL: https://codereview.webrtc.org/1790633002 Cr-Commit-Position: refs/heads/master@{#12098}
This commit is contained in:
@ -111,28 +111,20 @@
|
||||
+ (webrtc::MediaStreamTrackInterface::TrackState)
|
||||
convertTrackStateToNative:(RTCTrackState)state {
|
||||
switch (state) {
|
||||
case RTCTrackStateInitializing:
|
||||
return webrtc::MediaStreamTrackInterface::kInitializing;
|
||||
case RTCTrackStateLive:
|
||||
return webrtc::MediaStreamTrackInterface::kLive;
|
||||
case RTCTrackStateEnded:
|
||||
return webrtc::MediaStreamTrackInterface::kEnded;
|
||||
case RTCTrackStateFailed:
|
||||
return webrtc::MediaStreamTrackInterface::kFailed;
|
||||
}
|
||||
}
|
||||
|
||||
+ (RTCTrackState)convertTrackStateToObjC:
|
||||
(webrtc::MediaStreamTrackInterface::TrackState)nativeState {
|
||||
switch (nativeState) {
|
||||
case webrtc::MediaStreamTrackInterface::kInitializing:
|
||||
return RTCTrackStateInitializing;
|
||||
case webrtc::MediaStreamTrackInterface::kLive:
|
||||
return RTCTrackStateLive;
|
||||
case webrtc::MediaStreamTrackInterface::kEnded:
|
||||
return RTCTrackStateEnded;
|
||||
case webrtc::MediaStreamTrackInterface::kFailed:
|
||||
return RTCTrackStateFailed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,8 +72,6 @@ typedef enum {
|
||||
|
||||
// RTCTrackState corresponds to the states in webrtc::TrackState.
|
||||
typedef enum {
|
||||
RTCTrackStateInitializing,
|
||||
RTCTrackStateLive,
|
||||
RTCTrackStateEnded,
|
||||
RTCTrackStateFailed,
|
||||
} RTCTrackState;
|
||||
|
||||
@ -65,27 +65,11 @@ void AudioTrack::RemoveSink(AudioTrackSinkInterface* sink) {
|
||||
|
||||
void AudioTrack::OnChanged() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
if (state() == kFailed)
|
||||
return; // We can't recover from this state (do we ever set it?).
|
||||
|
||||
TrackState new_state = kInitializing;
|
||||
|
||||
// |audio_source_| must be non-null if we ever get here.
|
||||
switch (audio_source_->state()) {
|
||||
case MediaSourceInterface::kLive:
|
||||
case MediaSourceInterface::kMuted:
|
||||
new_state = kLive;
|
||||
break;
|
||||
case MediaSourceInterface::kEnded:
|
||||
new_state = kEnded;
|
||||
break;
|
||||
case MediaSourceInterface::kInitializing:
|
||||
default:
|
||||
// use kInitializing.
|
||||
break;
|
||||
if (audio_source_->state() == MediaSourceInterface::kEnded) {
|
||||
set_state(kEnded);
|
||||
} else {
|
||||
set_state(kLive);
|
||||
}
|
||||
|
||||
set_state(new_state);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -13,9 +13,7 @@ package org.webrtc;
|
||||
/** Java wrapper for a C++ MediaStreamTrackInterface. */
|
||||
public class MediaStreamTrack {
|
||||
/** Tracks MediaStreamTrackInterface.TrackState */
|
||||
public enum State {
|
||||
INITIALIZING, LIVE, ENDED, FAILED
|
||||
}
|
||||
public enum State { LIVE, ENDED }
|
||||
|
||||
final long nativeTrack;
|
||||
|
||||
|
||||
@ -60,12 +60,12 @@ class MediaStreamTest: public testing::Test {
|
||||
video_track_ =
|
||||
VideoTrack::Create(kVideoTrackId, FakeVideoTrackSource::Create());
|
||||
ASSERT_TRUE(video_track_.get() != NULL);
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kInitializing, video_track_->state());
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());
|
||||
|
||||
audio_track_ = AudioTrack::Create(kAudioTrackId, NULL);
|
||||
|
||||
ASSERT_TRUE(audio_track_.get() != NULL);
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kInitializing, audio_track_->state());
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive, audio_track_->state());
|
||||
|
||||
EXPECT_TRUE(stream_->AddTrack(video_track_));
|
||||
EXPECT_FALSE(stream_->AddTrack(video_track_));
|
||||
@ -83,8 +83,8 @@ class MediaStreamTest: public testing::Test {
|
||||
|
||||
EXPECT_CALL(observer, OnChanged())
|
||||
.Times(Exactly(1));
|
||||
track->set_state(MediaStreamTrackInterface::kLive);
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive, track->state());
|
||||
track->set_state(MediaStreamTrackInterface::kEnded);
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kEnded, track->state());
|
||||
}
|
||||
|
||||
scoped_refptr<MediaStreamInterface> stream_;
|
||||
|
||||
@ -80,10 +80,8 @@ class MediaStreamTrackInterface : public rtc::RefCountInterface,
|
||||
public NotifierInterface {
|
||||
public:
|
||||
enum TrackState {
|
||||
kInitializing, // Track is beeing negotiated.
|
||||
kLive = 1, // Track alive
|
||||
kEnded = 2, // Track have ended
|
||||
kFailed = 3, // Track negotiation failed.
|
||||
kLive,
|
||||
kEnded,
|
||||
};
|
||||
|
||||
static const char kAudioKind[];
|
||||
|
||||
@ -48,10 +48,7 @@ class MediaStreamTrack : public Notifier<T> {
|
||||
|
||||
protected:
|
||||
explicit MediaStreamTrack(const std::string& id)
|
||||
: enabled_(true),
|
||||
id_(id),
|
||||
state_(MediaStreamTrackInterface::kInitializing) {
|
||||
}
|
||||
: enabled_(true), id_(id), state_(MediaStreamTrackInterface::kLive) {}
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
|
||||
@ -11,14 +11,11 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Represents the state of the track. This exposes the same states in C++,
|
||||
* which include two more states than are in the W3C spec.
|
||||
* Represents the state of the track. This exposes the same states in C++.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, RTCMediaStreamTrackState) {
|
||||
RTCMediaStreamTrackStateInitializing,
|
||||
RTCMediaStreamTrackStateLive,
|
||||
RTCMediaStreamTrackStateEnded,
|
||||
RTCMediaStreamTrackStateFailed,
|
||||
RTCMediaStreamTrackStateEnded
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@ -67,41 +67,29 @@
|
||||
+ (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState:
|
||||
(RTCMediaStreamTrackState)state {
|
||||
switch (state) {
|
||||
case RTCMediaStreamTrackStateInitializing:
|
||||
return webrtc::MediaStreamTrackInterface::kInitializing;
|
||||
case RTCMediaStreamTrackStateLive:
|
||||
return webrtc::MediaStreamTrackInterface::kLive;
|
||||
case RTCMediaStreamTrackStateEnded:
|
||||
return webrtc::MediaStreamTrackInterface::kEnded;
|
||||
case RTCMediaStreamTrackStateFailed:
|
||||
return webrtc::MediaStreamTrackInterface::kFailed;
|
||||
}
|
||||
}
|
||||
|
||||
+ (RTCMediaStreamTrackState)trackStateForNativeState:
|
||||
(webrtc::MediaStreamTrackInterface::TrackState)nativeState {
|
||||
switch (nativeState) {
|
||||
case webrtc::MediaStreamTrackInterface::kInitializing:
|
||||
return RTCMediaStreamTrackStateInitializing;
|
||||
case webrtc::MediaStreamTrackInterface::kLive:
|
||||
return RTCMediaStreamTrackStateLive;
|
||||
case webrtc::MediaStreamTrackInterface::kEnded:
|
||||
return RTCMediaStreamTrackStateEnded;
|
||||
case webrtc::MediaStreamTrackInterface::kFailed:
|
||||
return RTCMediaStreamTrackStateFailed;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)stringForState:(RTCMediaStreamTrackState)state {
|
||||
switch (state) {
|
||||
case RTCMediaStreamTrackStateInitializing:
|
||||
return @"Initializing";
|
||||
case RTCMediaStreamTrackStateLive:
|
||||
return @"Live";
|
||||
case RTCMediaStreamTrackStateEnded:
|
||||
return @"Ended";
|
||||
case RTCMediaStreamTrackStateFailed:
|
||||
return @"Failed";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -81,10 +81,6 @@ VideoRtpReceiver::VideoRtpReceiver(MediaStreamInterface* stream,
|
||||
rtc::Thread::Current(),
|
||||
VideoTrack::Create(track_id, source_.get()))) {
|
||||
source_->SetState(MediaSourceInterface::kLive);
|
||||
// TODO(perkj): It should be enough to set the source state. All tracks
|
||||
// belonging to the same source should get its state from the source.
|
||||
// I.e. if a track has been cloned from a remote source.
|
||||
track_->set_state(webrtc::MediaStreamTrackInterface::kLive);
|
||||
provider_->SetVideoPlayout(ssrc_, true, &broadcaster_);
|
||||
stream->AddTrack(track_);
|
||||
}
|
||||
@ -102,9 +98,6 @@ void VideoRtpReceiver::Stop() {
|
||||
}
|
||||
source_->SetState(MediaSourceInterface::kEnded);
|
||||
source_->OnSourceDestroyed();
|
||||
// TODO(perkj): It should be enough to set the source state. All tracks
|
||||
// belonging to the same source should get its state from the source.
|
||||
track_->set_state(MediaStreamTrackInterface::kEnded);
|
||||
provider_->SetVideoPlayout(ssrc_, false, nullptr);
|
||||
provider_ = nullptr;
|
||||
}
|
||||
|
||||
@ -20,9 +20,11 @@ VideoTrack::VideoTrack(const std::string& label,
|
||||
VideoTrackSourceInterface* video_source)
|
||||
: MediaStreamTrack<VideoTrackInterface>(label),
|
||||
video_source_(video_source) {
|
||||
video_source_->RegisterObserver(this);
|
||||
}
|
||||
|
||||
VideoTrack::~VideoTrack() {
|
||||
video_source_->UnregisterObserver(this);
|
||||
}
|
||||
|
||||
std::string VideoTrack::kind() const {
|
||||
@ -56,6 +58,15 @@ bool VideoTrack::set_enabled(bool enable) {
|
||||
return MediaStreamTrack<VideoTrackInterface>::set_enabled(enable);
|
||||
}
|
||||
|
||||
void VideoTrack::OnChanged() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
if (video_source_->state() == MediaSourceInterface::kEnded) {
|
||||
set_state(kEnded);
|
||||
} else {
|
||||
set_state(kLive);
|
||||
}
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<VideoTrack> VideoTrack::Create(
|
||||
const std::string& id,
|
||||
VideoTrackSourceInterface* source) {
|
||||
|
||||
@ -22,7 +22,8 @@
|
||||
namespace webrtc {
|
||||
|
||||
class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,
|
||||
public rtc::VideoSourceBase {
|
||||
public rtc::VideoSourceBase,
|
||||
public ObserverInterface {
|
||||
public:
|
||||
static rtc::scoped_refptr<VideoTrack> Create(
|
||||
const std::string& label,
|
||||
@ -43,6 +44,9 @@ class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,
|
||||
~VideoTrack();
|
||||
|
||||
private:
|
||||
// Implements ObserverInterface. Observes |video_source_| state.
|
||||
void OnChanged() override;
|
||||
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
rtc::scoped_refptr<VideoTrackSourceInterface> video_source_;
|
||||
};
|
||||
|
||||
@ -21,19 +21,19 @@
|
||||
|
||||
using webrtc::FakeVideoTrackRenderer;
|
||||
using webrtc::FakeVideoTrackRendererOld;
|
||||
using webrtc::MediaSourceInterface;
|
||||
using webrtc::MediaStreamTrackInterface;
|
||||
using webrtc::VideoTrackSource;
|
||||
using webrtc::VideoTrack;
|
||||
using webrtc::VideoTrackInterface;
|
||||
|
||||
|
||||
class VideoTrackTest : public testing::Test {
|
||||
public:
|
||||
VideoTrackTest() {
|
||||
static const char kVideoTrackId[] = "track_id";
|
||||
video_track_ = VideoTrack::Create(
|
||||
kVideoTrackId,
|
||||
new rtc::RefCountedObject<VideoTrackSource>(
|
||||
&capturer_, rtc::Thread::Current(), true /* remote */));
|
||||
video_track_source_ = new rtc::RefCountedObject<VideoTrackSource>(
|
||||
&capturer_, rtc::Thread::Current(), true /* remote */);
|
||||
video_track_ = VideoTrack::Create(kVideoTrackId, video_track_source_);
|
||||
capturer_.Start(
|
||||
cricket::VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30),
|
||||
cricket::FOURCC_I420));
|
||||
@ -41,9 +41,17 @@ class VideoTrackTest : public testing::Test {
|
||||
|
||||
protected:
|
||||
cricket::FakeVideoCapturer capturer_;
|
||||
rtc::scoped_refptr<VideoTrackSource> video_track_source_;
|
||||
rtc::scoped_refptr<VideoTrackInterface> video_track_;
|
||||
};
|
||||
|
||||
// Test changing the source state also changes the track state.
|
||||
TEST_F(VideoTrackTest, SourceStateChangeTrackState) {
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());
|
||||
video_track_source_->SetState(MediaSourceInterface::kEnded);
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kEnded, video_track_->state());
|
||||
}
|
||||
|
||||
// Test adding renderers to a video track and render to them by providing
|
||||
// frames to the source.
|
||||
TEST_F(VideoTrackTest, RenderVideo) {
|
||||
|
||||
Reference in New Issue
Block a user