Implement getMediaDevices.
[chromium-blink-merge.git] / content / renderer / media / video_source_handler.cc
blobdabc9cc1326187d68262f19b76977180d8074ff0
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"
7 #include <string>
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"
20 #include "url/gurl.h"
22 namespace content {
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 {
28 public:
29 PpFrameReceiver(blink::WebMediaStreamTrack track)
30 : track_(track),
31 reader_(NULL),
32 weak_factory_(this) {
35 virtual ~PpFrameReceiver() {}
37 void SetReader(FrameReaderInterface* reader) {
38 if (reader) {
39 DCHECK(!reader_);
40 MediaStreamVideoSink::AddToVideoTrack(
41 this,
42 media::BindToCurrentLoop(
43 base::Bind(
44 &PpFrameReceiver::OnVideoFrame,
45 weak_factory_.GetWeakPtr())),
46 track_);
47 } else {
48 DCHECK(reader_);
49 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_);
50 weak_factory_.InvalidateWeakPtrs();
52 reader_ = reader;
55 void OnVideoFrame(
56 const scoped_refptr<media::VideoFrame>& frame,
57 const media::VideoCaptureFormat& format) {
58 if (reader_) {
59 reader_->GotFrame(frame);
63 private:
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();
79 ++it) {
80 delete it->second;
84 bool VideoSourceHandler::Open(const std::string& url,
85 FrameReaderInterface* reader) {
86 DCHECK(thread_checker_.CalledOnValidThread());
87 const blink::WebMediaStreamTrack& track = GetFirstVideoTrack(url);
88 if (track.isNull()) {
89 return false;
91 reader_to_receiver_[reader] = new SourceInfo(track, reader);
92 return true;
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()) {
99 return false;
101 delete it->second;
102 reader_to_receiver_.erase(it);
103 return true;
106 blink::WebMediaStreamTrack VideoSourceHandler::GetFirstVideoTrack(
107 const std::string& url) {
108 blink::WebMediaStream stream;
109 if (registry_) {
110 stream = registry_->GetMediaStream(url);
111 } else {
112 stream =
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."
126 << " url: " << url;
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()) {
138 return;
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