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/webrtc/webrtc_video_track_adapter.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/common/media/media_stream_options.h"
9 #include "content/renderer/media/media_stream_video_source.h"
10 #include "content/renderer/media/media_stream_video_track.h"
14 bool ConstraintKeyExists(const blink::WebMediaConstraints
& constraints
,
15 const blink::WebString
& name
) {
16 blink::WebString value_str
;
17 return constraints
.getMandatoryConstraintValue(name
, value_str
) ||
18 constraints
.getOptionalConstraintValue(name
, value_str
);
21 } // anonymouse namespace
25 // Used to make sure |source| is released on the main render thread.
26 void ReleaseWebRtcSourceOnMainRenderThread(
27 webrtc::VideoSourceInterface
* source
) {
31 // Simple help class used for receiving video frames on the IO-thread from
32 // a MediaStreamVideoTrack and forward the frames to a
33 // WebRtcVideoCapturerAdapter that implements a video capturer for libjingle.
34 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
35 : public base::RefCountedThreadSafe
<WebRtcVideoSourceAdapter
> {
37 WebRtcVideoSourceAdapter(
38 const scoped_refptr
<webrtc::VideoSourceInterface
>& source
,
39 WebRtcVideoCapturerAdapter
* capture_adapter
);
41 void OnVideoFrameOnIO(const scoped_refptr
<media::VideoFrame
>& frame
,
42 const media::VideoCaptureFormat
& format
);
45 friend class base::RefCountedThreadSafe
<WebRtcVideoSourceAdapter
>;
46 virtual ~WebRtcVideoSourceAdapter();
48 scoped_refptr
<base::MessageLoopProxy
> render_thread_message_loop_
;
49 // Used to DCHECK that frames are called on the IO-thread.
50 base::ThreadChecker io_thread_checker_
;
52 // |video_source_| is a libjingle object that must be released on the main
54 scoped_refptr
<webrtc::VideoSourceInterface
> video_source_
;
55 // |capture_adapter_| is owned by |video_source_|
56 WebRtcVideoCapturerAdapter
* capture_adapter_
;
59 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
60 const scoped_refptr
<webrtc::VideoSourceInterface
>& source
,
61 WebRtcVideoCapturerAdapter
* capture_adapter
)
62 : render_thread_message_loop_(base::MessageLoopProxy::current()),
63 video_source_(source
),
64 capture_adapter_(capture_adapter
) {
65 io_thread_checker_
.DetachFromThread();
68 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
69 if (!render_thread_message_loop_
->BelongsToCurrentThread()) {
70 webrtc::VideoSourceInterface
* source
= video_source_
.get();
73 render_thread_message_loop_
->PostTask(
75 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread
,
76 base::Unretained(source
)));
80 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
81 const scoped_refptr
<media::VideoFrame
>& frame
,
82 const media::VideoCaptureFormat
& format
) {
83 DCHECK(io_thread_checker_
.CalledOnValidThread());
84 capture_adapter_
->OnFrameCaptured(frame
);
87 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
88 const blink::WebMediaStreamTrack
& track
,
89 MediaStreamDependencyFactory
* factory
)
91 const blink::WebMediaConstraints
& constraints
=
92 MediaStreamVideoTrack::GetVideoTrack(track
)->constraints();
94 bool is_screencast
= ConstraintKeyExists(
95 constraints
, base::UTF8ToUTF16(kMediaStreamSource
));
96 WebRtcVideoCapturerAdapter
* capture_adapter
=
97 factory
->CreateVideoCapturer(is_screencast
);
99 // |video_source| owns |capture_adapter|
100 scoped_refptr
<webrtc::VideoSourceInterface
> video_source(
101 factory
->CreateVideoSource(capture_adapter
,
102 track
.source().constraints()));
104 video_track_
= factory
->CreateLocalVideoTrack(web_track_
.id().utf8(),
107 video_track_
->set_enabled(web_track_
.isEnabled());
109 source_adapter_
= new WebRtcVideoSourceAdapter(video_source
,
112 MediaStreamVideoTrack::GetVideoTrack(track
)->AddSink(
113 this, base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO
,
116 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
120 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
121 DCHECK(thread_checker_
.CalledOnValidThread());
122 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
123 MediaStreamVideoTrack::GetVideoTrack(web_track_
)->RemoveSink(this);
126 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled
) {
127 DCHECK(thread_checker_
.CalledOnValidThread());
128 video_track_
->set_enabled(enabled
);
131 } // namespace content