IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / renderer / media / video_source_handler.cc
blob69b83557939faf35550b3a2da02ac094fd845789
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 "content/renderer/media/media_stream_dependency_factory.h"
11 #include "content/renderer/media/media_stream_registry_interface.h"
12 #include "content/renderer/render_thread_impl.h"
13 #include "third_party/WebKit/public/platform/WebMediaStream.h"
14 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
15 #include "third_party/libjingle/source/talk/media/base/videoframe.h"
16 #include "third_party/libjingle/source/talk/media/base/videorenderer.h"
18 using cricket::VideoFrame;
19 using cricket::VideoRenderer;
20 using webrtc::VideoSourceInterface;
22 namespace content {
24 // PpFrameReceiver implements cricket::VideoRenderer so that it can be attached
25 // to native video track's video source to receive the captured frame.
26 // It can be attached to a FrameReaderInterface to output the received frame.
27 class PpFrameReceiver : public cricket::VideoRenderer {
28 public:
29 PpFrameReceiver() : reader_(NULL) {}
30 virtual ~PpFrameReceiver() {}
32 // Implements VideoRenderer.
33 virtual bool SetSize(int width, int height, int reserved) OVERRIDE {
34 return true;
36 virtual bool RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
37 base::AutoLock auto_lock(lock_);
38 if (reader_) {
39 // Make a shallow copy of the frame as the |reader_| may need to queue it.
40 // Both frames will share a single reference-counted frame buffer.
41 reader_->GotFrame(frame->Copy());
43 return true;
46 void SetReader(FrameReaderInterface* reader) {
47 base::AutoLock auto_lock(lock_);
48 reader_ = reader;
51 private:
52 FrameReaderInterface* reader_;
53 base::Lock lock_;
55 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
58 VideoSourceHandler::VideoSourceHandler(
59 MediaStreamRegistryInterface* registry)
60 : registry_(registry) {
63 VideoSourceHandler::~VideoSourceHandler() {
64 // All the opened readers should have been closed by now.
65 DCHECK(reader_to_receiver_.empty());
68 bool VideoSourceHandler::Open(const std::string& url,
69 FrameReaderInterface* reader) {
70 scoped_refptr<webrtc::VideoSourceInterface> source = GetFirstVideoSource(url);
71 if (!source.get()) {
72 return false;
74 PpFrameReceiver* receiver = new PpFrameReceiver();
75 receiver->SetReader(reader);
76 source->AddSink(receiver);
77 reader_to_receiver_[reader] = receiver;
78 return true;
81 bool VideoSourceHandler::Close(const std::string& url,
82 FrameReaderInterface* reader) {
83 scoped_refptr<webrtc::VideoSourceInterface> source = GetFirstVideoSource(url);
84 if (!source.get()) {
85 LOG(ERROR) << "VideoSourceHandler::Close - Failed to get the video source "
86 << "from MediaStream with url: " << url;
87 return false;
89 PpFrameReceiver* receiver =
90 static_cast<PpFrameReceiver*>(GetReceiver(reader));
91 if (!receiver) {
92 LOG(ERROR) << "VideoSourceHandler::Close - Failed to find receiver that "
93 << "is associated with the given reader.";
94 return false;
96 receiver->SetReader(NULL);
97 source->RemoveSink(receiver);
98 reader_to_receiver_.erase(reader);
99 delete receiver;
100 return true;
103 scoped_refptr<VideoSourceInterface> VideoSourceHandler::GetFirstVideoSource(
104 const std::string& url) {
105 scoped_refptr<webrtc::VideoSourceInterface> source;
106 blink::WebMediaStream stream;
107 if (registry_) {
108 stream = registry_->GetMediaStream(url);
109 } else {
110 stream =
111 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
113 if (stream.isNull() || !stream.extraData()) {
114 LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
115 return source;
118 // Get the first video track from the stream.
119 MediaStreamExtraData* extra_data =
120 static_cast<MediaStreamExtraData*>(stream.extraData());
121 if (!extra_data) {
122 LOG(ERROR) << "GetFirstVideoSource - MediaStreamExtraData is NULL.";
123 return source;
125 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get();
126 if (!native_stream) {
127 LOG(ERROR) << "GetFirstVideoSource - native stream is NULL.";
128 return source;
130 webrtc::VideoTrackVector native_video_tracks =
131 native_stream->GetVideoTracks();
132 if (native_video_tracks.empty()) {
133 LOG(ERROR) << "GetFirstVideoSource - stream has no video track.";
134 return source;
136 source = native_video_tracks[0]->GetSource();
137 return source;
140 VideoRenderer* VideoSourceHandler::GetReceiver(
141 FrameReaderInterface* reader) {
142 std::map<FrameReaderInterface*, VideoRenderer*>::iterator it;
143 it = reader_to_receiver_.find(reader);
144 if (it == reader_to_receiver_.end()) {
145 return NULL;
147 return it->second;
150 } // namespace content