Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / content / renderer / media / video_source_handler.cc
blob12185fb1bbcbf382e5d3e31913806cccee628c8e
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 "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"
21 #include "url/gurl.h"
23 namespace content {
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 {
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 if (reader) {
40 DCHECK(!reader_);
41 MediaStreamVideoSink::AddToVideoTrack(
42 this,
43 media::BindToCurrentLoop(
44 base::Bind(
45 &PpFrameReceiver::OnVideoFrame,
46 weak_factory_.GetWeakPtr())),
47 track_);
48 } else {
49 DCHECK(reader_);
50 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_);
51 weak_factory_.InvalidateWeakPtrs();
53 reader_ = reader;
56 void OnVideoFrame(
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");
61 if (reader_) {
62 reader_->GotFrame(frame);
66 private:
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();
82 ++it) {
83 delete it->second;
87 bool VideoSourceHandler::Open(const std::string& url,
88 FrameReaderInterface* reader) {
89 DCHECK(thread_checker_.CalledOnValidThread());
90 const blink::WebMediaStreamTrack& track = GetFirstVideoTrack(url);
91 if (track.isNull()) {
92 return false;
94 reader_to_receiver_[reader] = new SourceInfo(track, reader);
95 return true;
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()) {
102 return false;
104 delete it->second;
105 reader_to_receiver_.erase(it);
106 return true;
109 blink::WebMediaStreamTrack VideoSourceHandler::GetFirstVideoTrack(
110 const std::string& url) {
111 blink::WebMediaStream stream;
112 if (registry_) {
113 stream = registry_->GetMediaStream(url);
114 } else {
115 stream =
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."
129 << " url: " << url;
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()) {
141 return;
143 PpFrameReceiver* receiver = it->second->receiver_.get();
144 receiver->OnVideoFrame(frame, media::VideoCaptureFormat(),
145 base::TimeTicks());
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