Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / media / video_track_to_pepper_adapter.cc
blob6a5947d3d34f7397453834e47eccefe7c8558b07
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_track_to_pepper_adapter.h"
7 #include <string>
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/base/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"
21 #include "url/gurl.h"
23 namespace content {
25 // PpFrameReceiver implements MediaStreamVideoSink so that it can be attached
26 // to video track to receive captured frames.
27 // It can be attached to a FrameReaderInterface to output the received frame.
28 class PpFrameReceiver : public MediaStreamVideoSink {
29 public:
30 PpFrameReceiver(blink::WebMediaStreamTrack track)
31 : track_(track),
32 reader_(NULL),
33 weak_factory_(this) {
36 ~PpFrameReceiver() override {}
38 void SetReader(FrameReaderInterface* reader) {
39 DCHECK((reader_ && !reader) || (!reader_ && reader))
40 << " |reader| = " << reader << ", |reader_| = " << reader_;
41 if (reader) {
42 AddToVideoTrack(this,
43 media::BindToCurrentLoop(
44 base::Bind(&PpFrameReceiver::OnVideoFrame,
45 weak_factory_.GetWeakPtr())),
46 track_);
47 } else {
48 RemoveFromVideoTrack(this, track_);
49 weak_factory_.InvalidateWeakPtrs();
51 reader_ = reader;
54 void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
55 base::TimeTicks estimated_capture_time) {
56 TRACE_EVENT0("video", "PpFrameReceiver::OnVideoFrame");
57 if (reader_)
58 reader_->GotFrame(frame);
61 private:
62 const blink::WebMediaStreamTrack track_;
63 FrameReaderInterface* reader_;
64 base::WeakPtrFactory<PpFrameReceiver> weak_factory_;
66 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
69 VideoTrackToPepperAdapter::VideoTrackToPepperAdapter(
70 MediaStreamRegistryInterface* registry)
71 : registry_(registry) {}
73 VideoTrackToPepperAdapter::~VideoTrackToPepperAdapter() {
74 for (const auto& reader_and_receiver : reader_to_receiver_)
75 delete reader_and_receiver.second;
78 bool VideoTrackToPepperAdapter::Open(const std::string& url,
79 FrameReaderInterface* reader) {
80 DCHECK(thread_checker_.CalledOnValidThread());
81 const blink::WebMediaStreamTrack& track = GetFirstVideoTrack(url);
82 if (track.isNull())
83 return false;
84 reader_to_receiver_[reader] = new SourceInfo(track, reader);
85 return true;
88 bool VideoTrackToPepperAdapter::Close(FrameReaderInterface* reader) {
89 DCHECK(thread_checker_. CalledOnValidThread());
90 SourceInfoMap::iterator it = reader_to_receiver_.find(reader);
91 if (it == reader_to_receiver_.end())
92 return false;
93 delete it->second;
94 reader_to_receiver_.erase(it);
95 return true;
98 blink::WebMediaStreamTrack VideoTrackToPepperAdapter::GetFirstVideoTrack(
99 const std::string& url) {
100 DCHECK(thread_checker_.CalledOnValidThread());
101 const blink::WebMediaStream stream = registry_
102 ? registry_->GetMediaStream(url)
103 : blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
105 if (stream.isNull()) {
106 LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
107 return blink::WebMediaStreamTrack();
110 // Get the first video track from the stream.
111 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
112 stream.videoTracks(video_tracks);
113 if (video_tracks.isEmpty()) {
114 LOG(ERROR) << "GetFirstVideoSource - no video tracks. url: " << url;
115 return blink::WebMediaStreamTrack();
118 return video_tracks[0];
121 void VideoTrackToPepperAdapter::DeliverFrameForTesting(
122 FrameReaderInterface* reader,
123 const scoped_refptr<media::VideoFrame>& frame) {
124 SourceInfoMap::const_iterator it = reader_to_receiver_.find(reader);
125 if (it == reader_to_receiver_.end())
126 return;
127 PpFrameReceiver* receiver = it->second->receiver_.get();
128 receiver->OnVideoFrame(frame, base::TimeTicks());
131 VideoTrackToPepperAdapter::SourceInfo::SourceInfo(
132 const blink::WebMediaStreamTrack& blink_track,
133 FrameReaderInterface* reader)
134 : receiver_(new PpFrameReceiver(blink_track)) {
135 receiver_->SetReader(reader);
138 VideoTrackToPepperAdapter::SourceInfo::~SourceInfo() {
139 receiver_->SetReader(NULL);
142 } // namespace content