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 "content/public/renderer/media_stream_video_sink.h"
13 #include "content/renderer/media/media_stream.h"
14 #include "content/renderer/media/media_stream_registry_interface.h"
15 #include "media/base/bind_to_current_loop.h"
16 #include "media/video/capture/video_capture_types.h"
17 #include "third_party/WebKit/public/platform/WebMediaStream.h"
18 #include "third_party/WebKit/public/platform/WebURL.h"
19 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
24 // PpFrameReceiver implements MediaStreamVideoSink so that it can be attached
25 // to video track to receive the captured frame.
26 // It can be attached to a FrameReaderInterface to output the received frame.
27 class PpFrameReceiver
: public MediaStreamVideoSink
{
29 PpFrameReceiver(blink::WebMediaStreamTrack track
)
35 virtual ~PpFrameReceiver() {}
37 void SetReader(FrameReaderInterface
* reader
) {
40 MediaStreamVideoSink::AddToVideoTrack(
42 media::BindToCurrentLoop(
44 &PpFrameReceiver::OnVideoFrame
,
45 weak_factory_
.GetWeakPtr())),
49 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_
);
50 weak_factory_
.InvalidateWeakPtrs();
56 const scoped_refptr
<media::VideoFrame
>& frame
,
57 const media::VideoCaptureFormat
& format
) {
59 reader_
->GotFrame(frame
);
64 blink::WebMediaStreamTrack track_
;
65 FrameReaderInterface
* reader_
;
66 base::WeakPtrFactory
<PpFrameReceiver
> weak_factory_
;
68 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver
);
71 VideoSourceHandler::VideoSourceHandler(
72 MediaStreamRegistryInterface
* registry
)
73 : registry_(registry
) {
76 VideoSourceHandler::~VideoSourceHandler() {
77 for (SourceInfoMap::iterator it
= reader_to_receiver_
.begin();
78 it
!= reader_to_receiver_
.end();
84 bool VideoSourceHandler::Open(const std::string
& url
,
85 FrameReaderInterface
* reader
) {
86 DCHECK(thread_checker_
.CalledOnValidThread());
87 const blink::WebMediaStreamTrack
& track
= GetFirstVideoTrack(url
);
91 reader_to_receiver_
[reader
] = new SourceInfo(track
, reader
);
95 bool VideoSourceHandler::Close(FrameReaderInterface
* reader
) {
96 DCHECK(thread_checker_
. CalledOnValidThread());
97 SourceInfoMap::iterator it
= reader_to_receiver_
.find(reader
);
98 if (it
== reader_to_receiver_
.end()) {
102 reader_to_receiver_
.erase(it
);
106 blink::WebMediaStreamTrack
VideoSourceHandler::GetFirstVideoTrack(
107 const std::string
& url
) {
108 blink::WebMediaStream stream
;
110 stream
= registry_
->GetMediaStream(url
);
113 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url
));
116 if (stream
.isNull()) {
117 LOG(ERROR
) << "GetFirstVideoSource - invalid url: " << url
;
118 return blink::WebMediaStreamTrack();
121 // Get the first video track from the stream.
122 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
123 stream
.videoTracks(video_tracks
);
124 if (video_tracks
.isEmpty()) {
125 LOG(ERROR
) << "GetFirstVideoSource - non video tracks available."
127 return blink::WebMediaStreamTrack();
130 return video_tracks
[0];
133 void VideoSourceHandler::DeliverFrameForTesting(
134 FrameReaderInterface
* reader
,
135 const scoped_refptr
<media::VideoFrame
>& frame
) {
136 SourceInfoMap::iterator it
= reader_to_receiver_
.find(reader
);
137 if (it
== reader_to_receiver_
.end()) {
140 PpFrameReceiver
* receiver
= it
->second
->receiver_
.get();
141 receiver
->OnVideoFrame(frame
, media::VideoCaptureFormat());
144 VideoSourceHandler::SourceInfo::SourceInfo(
145 const blink::WebMediaStreamTrack
& blink_track
,
146 FrameReaderInterface
* reader
)
147 : receiver_(new PpFrameReceiver(blink_track
)) {
148 receiver_
->SetReader(reader
);
151 VideoSourceHandler::SourceInfo::~SourceInfo() {
152 receiver_
->SetReader(NULL
);
155 } // namespace content