1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/media/media_stream_video_source.h"
7 #include "base/logging.h"
8 #include "content/renderer/media/media_stream_dependency_factory.h"
9 #include "content/renderer/media/rtc_media_constraints.h"
10 #include "media/base/video_frame.h"
11 #include "third_party/libjingle/source/talk/app/webrtc/remotevideocapturer.h"
12 #include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h"
16 MediaStreamVideoSource::MediaStreamVideoSource(
17 MediaStreamDependencyFactory* factory)
18 : initializing_(false),
22 first_frame_timestamp_(media::kNoTimestamp()) {
26 MediaStreamVideoSource::~MediaStreamVideoSource() {
28 adapter_->UnregisterObserver(this);
32 void MediaStreamVideoSource::AddTrack(
33 const blink::WebMediaStreamTrack& track,
34 const blink::WebMediaConstraints& constraints,
35 const ConstraintsCallback& callback) {
37 // Create the webrtc::MediaStreamVideoSourceInterface adapter.
38 InitAdapter(constraints);
41 current_constraints_ = constraints;
43 // Register to the adapter to get notified when it has been started
45 adapter_->RegisterObserver(this);
48 // TODO(perkj): Currently, reconfiguring the source is not supported. For now
49 // we ignore if |constraints| do not match the constraints that was used
50 // when the source was started
52 // There might be multiple tracks attaching to the source while it is being
54 constraints_callbacks_.push_back(callback);
55 TriggerConstraintsCallbackOnStateChange();
57 // TODO(perkj): Use the MediaStreamDependencyFactory for now to create the
58 // MediaStreamVideoTrack since creation is currently still depending on
59 // libjingle. The webrtc video track implementation will attach to the
60 // webrtc::VideoSourceInterface returned by GetAdapter() to receive video
62 factory_->CreateNativeMediaStreamTrack(track);
65 void MediaStreamVideoSource::RemoveTrack(
66 const blink::WebMediaStreamTrack& track) {
67 // TODO(ronghuawu): What should be done here? Do we really need RemoveTrack?
70 void MediaStreamVideoSource::InitAdapter(
71 const blink::WebMediaConstraints& constraints) {
73 RTCMediaConstraints webrtc_constraints(constraints);
74 adapter_ = factory_->CreateVideoSource(new webrtc::RemoteVideoCapturer(),
78 void MediaStreamVideoSource::SetReadyState(
79 blink::WebMediaStreamSource::ReadyState state) {
80 // TODO(ronghuawu): Sets WebMediaStreamSource's ready state and notifies the
81 // ready state to all registered tracks.
84 void MediaStreamVideoSource::DeliverVideoFrame(
85 const scoped_refptr<media::VideoFrame>& frame) {
86 if (first_frame_timestamp_ == media::kNoTimestamp()) {
87 first_frame_timestamp_ = frame->GetTimestamp();
90 cricket::VideoRenderer* input = adapter_->FrameInput();
91 if (width_ != frame->coded_size().width() ||
92 height_ != frame->coded_size().height()) {
93 width_ = frame->coded_size().width();
94 height_ = frame->coded_size().height();
95 const int reserved = 0;
96 input->SetSize(width_, height_, reserved);
99 cricket::WebRtcVideoFrame cricket_frame;
100 const int64 elapsed_time_ns =
101 (frame->GetTimestamp() - first_frame_timestamp_).InMicroseconds() *
102 base::Time::kNanosecondsPerMicrosecond;
103 const int64 time_stamp_ns = frame->GetTimestamp().InMicroseconds() *
104 base::Time::kNanosecondsPerMicrosecond;
106 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
107 const size_t pixel_width = 1;
108 const size_t pixel_height = 1;
109 const int rotation = 0;
110 cricket_frame.Alias(frame->data(0), size,
112 pixel_width, pixel_height,
113 elapsed_time_ns, time_stamp_ns,
115 input->RenderFrame(&cricket_frame);
118 void MediaStreamVideoSource::OnChanged() {
119 DCHECK(CalledOnValidThread());
120 TriggerConstraintsCallbackOnStateChange();
123 void MediaStreamVideoSource::TriggerConstraintsCallbackOnStateChange() {
124 if (adapter_->state() == webrtc::MediaSourceInterface::kInitializing)
128 adapter_->UnregisterObserver(this);
129 initializing_ = false;
132 std::vector<ConstraintsCallback> callbacks;
133 callbacks.swap(constraints_callbacks_);
135 bool success = (adapter_->state() == webrtc::MediaSourceInterface::kLive);
136 for (std::vector<ConstraintsCallback>::iterator it = callbacks.begin();
137 it != callbacks.end(); ++it) {
139 it->Run(this, success);
143 } // namespace content