1 // Copyright (c) 2013 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/video_source_handler.h"
9 #include "base/logging.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/synchronization/lock.h"
12 #include "base/trace_event/trace_event.h"
13 #include "content/public/renderer/media_stream_video_sink.h"
14 #include "content/renderer/media/media_stream.h"
15 #include "content/renderer/media/media_stream_registry_interface.h"
16 #include "media/base/bind_to_current_loop.h"
17 #include "media/video/capture/video_capture_types.h"
18 #include "third_party/WebKit/public/platform/WebMediaStream.h"
19 #include "third_party/WebKit/public/platform/WebURL.h"
20 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
25 // PpFrameReceiver implements MediaStreamVideoSink so that it can be attached
26 // to video track to receive the captured frame.
27 // It can be attached to a FrameReaderInterface to output the received frame.
28 class PpFrameReceiver
: public MediaStreamVideoSink
{
30 PpFrameReceiver(blink::WebMediaStreamTrack track
)
36 ~PpFrameReceiver() override
{}
38 void SetReader(FrameReaderInterface
* reader
) {
41 MediaStreamVideoSink::AddToVideoTrack(
43 media::BindToCurrentLoop(
45 &PpFrameReceiver::OnVideoFrame
,
46 weak_factory_
.GetWeakPtr())),
50 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_
);
51 weak_factory_
.InvalidateWeakPtrs();
57 const scoped_refptr
<media::VideoFrame
>& frame
,
58 const media::VideoCaptureFormat
& format
,
59 const base::TimeTicks
& estimated_capture_time
) {
60 TRACE_EVENT0("video", "PpFrameReceiver::OnVideoFrame");
62 reader_
->GotFrame(frame
);
67 blink::WebMediaStreamTrack track_
;
68 FrameReaderInterface
* reader_
;
69 base::WeakPtrFactory
<PpFrameReceiver
> weak_factory_
;
71 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver
);
74 VideoSourceHandler::VideoSourceHandler(
75 MediaStreamRegistryInterface
* registry
)
76 : registry_(registry
) {
79 VideoSourceHandler::~VideoSourceHandler() {
80 for (SourceInfoMap::iterator it
= reader_to_receiver_
.begin();
81 it
!= reader_to_receiver_
.end();
87 bool VideoSourceHandler::Open(const std::string
& url
,
88 FrameReaderInterface
* reader
) {
89 DCHECK(thread_checker_
.CalledOnValidThread());
90 const blink::WebMediaStreamTrack
& track
= GetFirstVideoTrack(url
);
94 reader_to_receiver_
[reader
] = new SourceInfo(track
, reader
);
98 bool VideoSourceHandler::Close(FrameReaderInterface
* reader
) {
99 DCHECK(thread_checker_
. CalledOnValidThread());
100 SourceInfoMap::iterator it
= reader_to_receiver_
.find(reader
);
101 if (it
== reader_to_receiver_
.end()) {
105 reader_to_receiver_
.erase(it
);
109 blink::WebMediaStreamTrack
VideoSourceHandler::GetFirstVideoTrack(
110 const std::string
& url
) {
111 blink::WebMediaStream stream
;
113 stream
= registry_
->GetMediaStream(url
);
116 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url
));
119 if (stream
.isNull()) {
120 LOG(ERROR
) << "GetFirstVideoSource - invalid url: " << url
;
121 return blink::WebMediaStreamTrack();
124 // Get the first video track from the stream.
125 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
126 stream
.videoTracks(video_tracks
);
127 if (video_tracks
.isEmpty()) {
128 LOG(ERROR
) << "GetFirstVideoSource - non video tracks available."
130 return blink::WebMediaStreamTrack();
133 return video_tracks
[0];
136 void VideoSourceHandler::DeliverFrameForTesting(
137 FrameReaderInterface
* reader
,
138 const scoped_refptr
<media::VideoFrame
>& frame
) {
139 SourceInfoMap::iterator it
= reader_to_receiver_
.find(reader
);
140 if (it
== reader_to_receiver_
.end()) {
143 PpFrameReceiver
* receiver
= it
->second
->receiver_
.get();
144 receiver
->OnVideoFrame(frame
, media::VideoCaptureFormat(),
148 VideoSourceHandler::SourceInfo::SourceInfo(
149 const blink::WebMediaStreamTrack
& blink_track
,
150 FrameReaderInterface
* reader
)
151 : receiver_(new PpFrameReceiver(blink_track
)) {
152 receiver_
->SetReader(reader
);
155 VideoSourceHandler::SourceInfo::~SourceInfo() {
156 receiver_
->SetReader(NULL
);
159 } // namespace content