Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: content/renderer/media/video_destination_handler.cc

Issue 212973002: Refactor VideoDestinationHandler to implement MediaStreamVideoSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_destination_handler.h"
6
7 #include <string>
8
9 #include "base/base64.h"
10 #include "base/logging.h"
11 #include "base/rand_util.h"
12 #include "content/renderer/media/media_stream.h"
13 #include "content/renderer/media/media_stream_dependency_factory.h"
14 #include "content/renderer/media/media_stream_registry_interface.h"
15 #include "content/renderer/pepper/ppb_image_data_impl.h"
16 #include "content/renderer/render_thread_impl.h"
17 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.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 using cricket::CaptureState;
23 using cricket::VideoFormat;
24 using webrtc::VideoTrackInterface;
25 using webrtc::VideoTrackVector;
26
27 static const cricket::FourCC kEffectColorFormat = cricket::FOURCC_BGRA;
28
29 namespace content {
30
31 PpFrameWriter::PpFrameWriter()
32 : started_(false) {}
33
34 PpFrameWriter::~PpFrameWriter() {}
35
36 CaptureState PpFrameWriter::Start(const VideoFormat& capture_format) {
37 base::AutoLock auto_lock(lock_);
38 if (started_) {
39 LOG(ERROR) << "PpFrameWriter::Start - "
40 << "Got a StartCapture when already started!";
41 return cricket::CS_FAILED;
42 }
43 started_ = true;
44 return cricket::CS_STARTING;
45 }
46
47 void PpFrameWriter::Stop() {
48 base::AutoLock auto_lock(lock_);
49 started_ = false;
50 SignalStateChange(this, cricket::CS_STOPPED);
51 }
52
53 bool PpFrameWriter::IsRunning() {
54 return started_;
55 }
56
57 bool PpFrameWriter::GetPreferredFourccs(std::vector<uint32>* fourccs) {
58 if (!fourccs) {
59 LOG(ERROR) << "PpFrameWriter::GetPreferredFourccs - "
60 << "fourccs is NULL.";
61 return false;
62 }
63 // The effects plugin output BGRA.
64 fourccs->push_back(kEffectColorFormat);
65 return true;
66 }
67
68 bool PpFrameWriter::GetBestCaptureFormat(const VideoFormat& desired,
69 VideoFormat* best_format) {
70 if (!best_format) {
71 LOG(ERROR) << "PpFrameWriter::GetBestCaptureFormat - "
72 << "best_format is NULL.";
73 return false;
74 }
75
76 // Use the desired format as the best format.
77 best_format->width = desired.width;
78 best_format->height = desired.height;
79 best_format->fourcc = kEffectColorFormat;
80 best_format->interval = desired.interval;
81 return true;
82 }
83
84 bool PpFrameWriter::IsScreencast() const {
85 return false;
86 }
87
88 void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
89 int64 time_stamp_ns) {
90 base::AutoLock auto_lock(lock_);
91 // This assumes the handler of the SignalFrameCaptured won't call Start/Stop.
92 // TODO(ronghuawu): Avoid the using of lock. One way is to post this call to
93 // libjingle worker thread, which will require an extra copy of |image_data|.
94 // However if pepper host can hand over the ownership of |image_data|
95 // then we can avoid this extra copy.
96 if (!started_) {
97 LOG(ERROR) << "PpFrameWriter::PutFrame - "
98 << "Called when capturer is not started.";
99 return;
100 }
101 if (!image_data) {
102 LOG(ERROR) << "PpFrameWriter::PutFrame - Called with NULL image_data.";
103 return;
104 }
105 ImageDataAutoMapper mapper(image_data);
106 if (!mapper.is_valid()) {
107 LOG(ERROR) << "PpFrameWriter::PutFrame - "
108 << "The image could not be mapped and is unusable.";
109 return;
110 }
111 const SkBitmap* bitmap = image_data->GetMappedBitmap();
112 if (!bitmap) {
113 LOG(ERROR) << "PpFrameWriter::PutFrame - "
114 << "The image_data's mapped bitmap is NULL.";
115 return;
116 }
117
118 cricket::CapturedFrame frame;
119 frame.elapsed_time = 0;
120 frame.time_stamp = time_stamp_ns;
121 frame.pixel_height = 1;
122 frame.pixel_width = 1;
123 frame.width = bitmap->width();
124 frame.height = bitmap->height();
125 if (image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
126 frame.fourcc = cricket::FOURCC_BGRA;
127 } else {
128 LOG(ERROR) << "PpFrameWriter::PutFrame - Got RGBA which is not supported.";
129 return;
130 }
131 frame.data_size = bitmap->getSize();
132 frame.data = bitmap->getPixels();
133
134 // This signals to libJingle that a new VideoFrame is available.
135 // libJingle have no assumptions on what thread this signal come from.
136 SignalFrameCaptured(this, &frame);
137 }
138
139 // PpFrameWriterProxy is a helper class to make sure the user won't use
140 // PpFrameWriter after it is released (IOW its owner - WebMediaStreamTrack -
141 // is released).
142 class PpFrameWriterProxy : public FrameWriterInterface {
143 public:
144 PpFrameWriterProxy(VideoTrackInterface* track,
145 PpFrameWriter* writer)
146 : track_(track),
147 writer_(writer) {
148 DCHECK(writer_ != NULL);
149 }
150
151 virtual ~PpFrameWriterProxy() {}
152
153 virtual void PutFrame(PPB_ImageData_Impl* image_data,
154 int64 time_stamp_ns) OVERRIDE {
155 writer_->PutFrame(image_data, time_stamp_ns);
156 }
157
158 private:
159 scoped_refptr<VideoTrackInterface> track_;
160 PpFrameWriter* writer_;
161
162 DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
163 };
164
165 bool VideoDestinationHandler::Open(
166 MediaStreamDependencyFactory* factory,
167 MediaStreamRegistryInterface* registry,
168 const std::string& url,
169 FrameWriterInterface** frame_writer) {
170 if (!factory) {
171 factory = RenderThreadImpl::current()->GetMediaStreamDependencyFactory();
172 DCHECK(factory != NULL);
173 }
174 blink::WebMediaStream stream;
175 if (registry) {
176 stream = registry->GetMediaStream(url);
177 } else {
178 stream =
179 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
180 }
181 if (stream.isNull() || !stream.extraData()) {
182 LOG(ERROR) << "VideoDestinationHandler::Open - invalid url: " << url;
183 return false;
184 }
185
186 // Create a new native video track and add it to |stream|.
187 std::string track_id;
188 // According to spec, a media stream track's id should be globally unique.
189 // There's no easy way to strictly achieve that. The id generated with this
190 // method should be unique for most of the cases but theoretically it's
191 // possible we can get an id that's duplicated with the existing tracks.
192 base::Base64Encode(base::RandBytesAsString(64), &track_id);
193 PpFrameWriter* writer = new PpFrameWriter();
194 if (!factory->AddNativeVideoMediaTrack(track_id, &stream, writer)) {
195 delete writer;
196 return false;
197 }
198
199 // Gets a handler to the native video track, which owns the |writer|.
200 webrtc::MediaStreamInterface* native_stream = MediaStream::GetAdapter(stream);
201 DCHECK(native_stream);
202 VideoTrackVector video_tracks = native_stream->GetVideoTracks();
203 // Currently one supports one video track per media stream.
204 DCHECK(video_tracks.size() == 1);
205
206 *frame_writer = new PpFrameWriterProxy(video_tracks[0].get(), writer);
207 return true;
208 }
209
210 } // namespace content
211
OLDNEW
« no previous file with comments | « content/renderer/media/video_destination_handler.h ('k') | content/renderer/media/video_destination_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698