Chromium Code Reviews| Index: content/renderer/media/media_stream_video_source.cc |
| diff --git a/content/renderer/media/media_stream_video_source.cc b/content/renderer/media/media_stream_video_source.cc |
| index a9912cdeca0073441ec573488ccc36c864e687e2..c6022d0a1c4bb56c3aafa5507276995a58e6db51 100644 |
| --- a/content/renderer/media/media_stream_video_source.cc |
| +++ b/content/renderer/media/media_stream_video_source.cc |
| @@ -5,24 +5,92 @@ |
| #include "content/renderer/media/media_stream_video_source.h" |
| #include "content/renderer/media/media_stream_dependency_factory.h" |
| +#include "content/renderer/media/rtc_media_constraints.h" |
| #include "media/base/video_frame.h" |
| #include "third_party/libjingle/source/talk/app/webrtc/remotevideocapturer.h" |
| #include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h" |
| +namespace { |
| + |
| +// Returns true if the mandatory constraints in |c2| match the mandatory |
| +// constraints in |c1|. All mandatory constraints in |c1| do not need to exist |
| +// in |c2|. |
| +bool MandatoryConstraintsMatch(const blink::WebMediaConstraints& c1, |
|
Ronghua Wu (Left Chromium)
2014/01/16 23:02:37
c1->original
c2->new
perkj_chrome
2014/01/17 13:19:45
Done.
|
| + const blink::WebMediaConstraints& c2) { |
| + if (c1.isNull() && c2.isNull()) { |
| + // WebMediaConstraints are NULL in unit tests unfortunately. |
|
Ronghua Wu (Left Chromium)
2014/01/16 23:02:37
being null makes sense in real case also, right? i
perkj_chrome
2014/01/17 13:19:45
Not 100% sure.
Better safe than sorry.
|
| + return true; |
| + } |
| + blink::WebVector<blink::WebMediaConstraint> m1; |
| + c1.getMandatoryConstraints(m1); |
| + blink::WebVector<blink::WebMediaConstraint> m2; |
| + c2.getMandatoryConstraints(m2); |
| + |
| + if (m1.size() < m2.size()) |
| + return false; |
| + |
| + size_t matched_constraints = 0; |
| + |
| + for (size_t i = 0; i < m1.size(); ++i) { |
| + blink::WebString value; |
| + if (!c2.getMandatoryConstraintValue(m1[i].m_name, value)) |
| + continue; |
| + if (value != m1[i].m_value) |
| + return false; |
| + ++matched_constraints; |
| + } |
| + return m1.size() >= matched_constraints + m2.size(); |
|
Ronghua Wu (Left Chromium)
2014/01/16 23:02:37
sorry I don't get this one. Why matched_constraint
Jói
2014/01/17 08:57:08
Perhaps the check you want is |matched_constraints
perkj_chrome
2014/01/17 13:19:45
Thinking about it more I think we need to skip thi
|
| +} |
| + |
| +} // anonymous namespace |
| + |
| namespace content { |
| MediaStreamVideoSource::MediaStreamVideoSource( |
| MediaStreamDependencyFactory* factory) |
| - : factory_(factory), |
| + : initializing_(false), |
| + factory_(factory), |
| width_(0), |
| height_(0), |
| first_frame_timestamp_(media::kNoTimestamp()) { |
| DCHECK(factory_); |
| } |
| +MediaStreamVideoSource::~MediaStreamVideoSource() { |
| + if (initializing_) { |
| + GetAdapter()->UnregisterObserver(this); |
| + } |
| +} |
| + |
| void MediaStreamVideoSource::AddTrack( |
| const blink::WebMediaStreamTrack& track, |
| - const blink::WebMediaConstraints& constraints) { |
| + const blink::WebMediaConstraints& constraints, |
| + const ConstraintsCallback& callback) { |
| + if (!GetAdapter()) { |
| + Init(constraints); |
| + DCHECK(GetAdapter()); |
|
Ronghua Wu (Left Chromium)
2014/01/16 23:02:37
any particular reason why use getter instead of us
perkj_chrome
2014/01/17 13:19:45
Done.
|
| + |
| + current_constraints_ = constraints; |
| + initializing_ = true; |
| + GetAdapter()->RegisterObserver(this); |
|
Ronghua Wu (Left Chromium)
2014/01/16 23:02:37
this doesn't seem be right. i.e. when will you Reg
perkj_chrome
2014/01/17 13:19:45
The adapter is the webrtc::source and I register t
|
| + } |
| + |
| + // Currently, reconfiguring the source is not supported. |
| + if (!MandatoryConstraintsMatch(current_constraints_, constraints)) { |
| + callback.Run(this, false); |
| + return; |
| + } |
| + |
| + // There might be multiple tracks attaching to the source while it is being |
| + // configured. |
| + constraints_callbacks_.push_back(callback); |
| + CheckIfAdapterIsLive(); |
| + |
| + // TODO(perkj): Use the MediaStreamDependencyFactory for now to create the |
| + // MediaStreamVideoTrack since creation is currently still depending on |
| + // libjingle. The webrtc video track implementation will attach to the |
| + // webrtc::VideoSourceInterface returned by GetAdapter() to receive video |
| + // frames. |
| factory_->CreateNativeMediaStreamTrack(track); |
| } |
| @@ -31,12 +99,12 @@ void MediaStreamVideoSource::RemoveTrack( |
| // TODO(ronghuawu): What should be done here? Do we really need RemoveTrack? |
| } |
| -void MediaStreamVideoSource::Init() { |
| - if (!adapter_) { |
| - const webrtc::MediaConstraintsInterface* constraints = NULL; |
| - adapter_ = factory_->CreateVideoSource(new webrtc::RemoteVideoCapturer(), |
| - constraints); |
| - } |
| +void MediaStreamVideoSource::Init( |
| + const blink::WebMediaConstraints& constraints) { |
| + DCHECK(!adapter_); |
| + RTCMediaConstraints webrtc_constraints(constraints); |
| + adapter_ = factory_->CreateVideoSource(new webrtc::RemoteVideoCapturer(), |
| + &webrtc_constraints); |
| } |
| void MediaStreamVideoSource::SetReadyState( |
| @@ -79,7 +147,33 @@ void MediaStreamVideoSource::DeliverVideoFrame( |
| input->RenderFrame(&cricket_frame); |
| } |
| -MediaStreamVideoSource::~MediaStreamVideoSource() { |
| +void MediaStreamVideoSource::OnChanged() { |
| + DCHECK(CalledOnValidThread()); |
| + CheckIfAdapterIsLive(); |
| +} |
| + |
| +void MediaStreamVideoSource::CheckIfAdapterIsLive() { |
| + webrtc::VideoSourceInterface* webrtc_source = GetAdapter(); |
| + |
| + if (webrtc_source->state() == webrtc::MediaSourceInterface::kInitializing) |
| + return; |
| + |
| + bool success = webrtc_source->state() == webrtc::MediaSourceInterface::kLive |
| + ? true : false; |
| + |
| + if (initializing_) { |
| + webrtc_source->UnregisterObserver(this); |
| + initializing_ = false; |
| + } |
| + |
| + std::vector<ConstraintsCallback> callbacks(constraints_callbacks_); |
| + constraints_callbacks_.clear(); |
| + |
| + for (std::vector<ConstraintsCallback>::iterator it = callbacks.begin(); |
| + it != callbacks.end(); ++it) { |
| + if (!it->is_null()) |
| + it->Run(this, success); |
| + } |
| } |
| } // namespace content |