Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / video_source_handler.cc
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.
4
5 #include "content/renderer/media/video_source_handler.h"
6
7 #include <string>
8
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"
21
22 namespace content {
23
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) {
33   }
34
35   virtual ~PpFrameReceiver() {}
36
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();
51     }
52     reader_ = reader;
53   }
54
55   void OnVideoFrame(
56       const scoped_refptr<media::VideoFrame>& frame,
57       const media::VideoCaptureFormat& format) {
58     if (reader_) {
59       reader_->GotFrame(frame);
60     }
61   }
62
63  private:
64   blink::WebMediaStreamTrack track_;
65   FrameReaderInterface* reader_;
66   base::WeakPtrFactory<PpFrameReceiver> weak_factory_;
67
68   DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
69 };
70
71 VideoSourceHandler::VideoSourceHandler(
72     MediaStreamRegistryInterface* registry)
73     : registry_(registry) {
74 }
75
76 VideoSourceHandler::~VideoSourceHandler() {
77   for (SourceInfoMap::iterator it = reader_to_receiver_.begin();
78        it != reader_to_receiver_.end();
79        ++it) {
80     delete it->second;
81   }
82 }
83
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;
90   }
91   reader_to_receiver_[reader] = new SourceInfo(track, reader);
92   return true;
93 }
94
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;
100   }
101   delete it->second;
102   reader_to_receiver_.erase(it);
103   return true;
104 }
105
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));
114   }
115
116   if (stream.isNull()) {
117     LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
118     return blink::WebMediaStreamTrack();
119   }
120
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();
128   }
129
130   return video_tracks[0];
131 }
132
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;
139   }
140   PpFrameReceiver* receiver = it->second->receiver_.get();
141   receiver->OnVideoFrame(frame, media::VideoCaptureFormat());
142 }
143
144 VideoSourceHandler::SourceInfo::SourceInfo(
145     const blink::WebMediaStreamTrack& blink_track,
146     FrameReaderInterface* reader)
147     : receiver_(new PpFrameReceiver(blink_track)) {
148   receiver_->SetReader(reader);
149 }
150
151 VideoSourceHandler::SourceInfo::~SourceInfo() {
152   receiver_->SetReader(NULL);
153 }
154
155 }  // namespace content