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:
perkj
2016-03-23 00:33:56 -07:00
committed by Commit bot
parent 8549ed7638
commit c8f952deaa
13 changed files with 43 additions and 75 deletions

View File

@ -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;
}
}

View File

@ -72,8 +72,6 @@ typedef enum {
// RTCTrackState corresponds to the states in webrtc::TrackState.
typedef enum {
RTCTrackStateInitializing,
RTCTrackStateLive,
RTCTrackStateEnded,
RTCTrackStateFailed,
} RTCTrackState;

View File

@ -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

View File

@ -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;

View File

@ -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_;

View File

@ -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[];

View File

@ -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_;

View File

@ -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

View File

@ -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";
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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_;
};

View File

@ -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) {