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

Unified Diff: content/renderer/media/webrtc/video_destination_handler.cc

Issue 212973002: Refactor VideoDestinationHandler to implement MediaStreamVideoSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/webrtc/video_destination_handler.cc
diff --git a/content/renderer/media/webrtc/video_destination_handler.cc b/content/renderer/media/webrtc/video_destination_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c067463baae5e79e65b62f15629c29306ce26c4b
--- /dev/null
+++ b/content/renderer/media/webrtc/video_destination_handler.cc
@@ -0,0 +1,194 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/video_destination_handler.h"
+
Jói 2014/03/26 21:36:13 Any chance this file can show up as a move? Perhap
Ronghua Wu (Left Chromium) 2014/03/26 22:27:53 +1 would like see the diff svn cp will do if you
+#include <string>
+
+#include "base/base64.h"
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/renderer/media/media_stream.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/media_stream_registry_interface.h"
+#include "content/renderer/media/media_stream_video_track.h"
+#include "content/renderer/pepper/ppb_image_data_impl.h"
+#include "content/renderer/render_thread_impl.h"
+#include "media/video/capture/video_capture_types.h"
+#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
+#include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "url/gurl.h"
+
+namespace content {
+
+PpFrameWriter::PpFrameWriter(MediaStreamDependencyFactory* factory)
+ : MediaStreamVideoSource(factory), first_frame_received_(false) {
+ DVLOG(3) << "PpFrameWriter ctor";
+}
+
+PpFrameWriter::~PpFrameWriter() {
+ DVLOG(3) << "PpFrameWriter dtor";
+}
+
+void PpFrameWriter::GetCurrentSupportedFormats(int max_requested_width,
+ int max_requested_height) {
+ DCHECK(CalledOnValidThread());
+ DVLOG(3) << "PpFrameWriter::GetCurrentSupportedFormats()";
+ if (format_.IsValid()) {
+ media::VideoCaptureFormats formats;
+ formats.push_back(format_);
+ OnSupportedFormats(formats);
+ }
+}
+
+void PpFrameWriter::StartSourceImpl(
+ const media::VideoCaptureParams& params) {
+ DCHECK(CalledOnValidThread());
+ DVLOG(3) << "PpFrameWriter::StartSourceImpl()";
+ OnStartDone(true);
+}
+
+void PpFrameWriter::StopSourceImpl() {
+ DCHECK(CalledOnValidThread());
+}
+
+void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) {
+ DCHECK(CalledOnValidThread());
+ DVLOG(3) << "PpFrameWriter::PutFrame()";
+
+ if (!image_data) {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - Called with NULL image_data.";
+ return;
+ }
+ ImageDataAutoMapper mapper(image_data);
+ if (!mapper.is_valid()) {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - "
+ << "The image could not be mapped and is unusable.";
+ return;
+ }
+ const SkBitmap* bitmap = image_data->GetMappedBitmap();
+ if (!bitmap) {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - "
+ << "The image_data's mapped bitmap is NULL.";
+ return;
+ }
+
+ const gfx::Size frame_size(bitmap->width(), bitmap->height());
+
+ if (!first_frame_received_) {
+ first_frame_received_ = true;
Jói 2014/03/26 21:36:13 indenting is off, 2 spaces too much indent
perkj_chrome 2014/03/27 11:24:32 Done.
+ format_ = media::VideoCaptureFormat(
+ frame_size,
+ MediaStreamVideoSource::kDefaultFrameRate,
+ media::PIXEL_FORMAT_YV12);
+ if (state() == MediaStreamVideoSource::RETRIEVING_CAPABILITIES) {
+ media::VideoCaptureFormats formats;
+ formats.push_back(format_);
+ OnSupportedFormats(formats);
+ }
+ }
+
+ if (state() != MediaStreamVideoSource::STARTED)
+ return;
+
+ const base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
+ time_stamp_ns / talk_base::kNumNanosecsPerMillisec);
+
+ scoped_refptr<media::VideoFrame> new_frame =
+ frame_pool_.CreateFrame(media::VideoFrame::I420, frame_size,
+ gfx::Rect(frame_size), frame_size, timestamp);
+
+ libyuv::BGRAToI420(reinterpret_cast<uint8*>(bitmap->getPixels()),
+ bitmap->rowBytes(),
+ new_frame->data(media::VideoFrame::kYPlane),
+ new_frame->stride(media::VideoFrame::kYPlane),
+ new_frame->data(media::VideoFrame::kUPlane),
+ new_frame->stride(media::VideoFrame::kUPlane),
+ new_frame->data(media::VideoFrame::kVPlane),
+ new_frame->stride(media::VideoFrame::kVPlane),
+ frame_size.width(), frame_size.height());
+
+ DeliverVideoFrame(new_frame);
+}
+
+// PpFrameWriterProxy is a helper class to make sure the user won't use
+// PpFrameWriter after it is released (IOW its owner - WebMediaStreamTrack -
+// is released).
+class PpFrameWriterProxy : public FrameWriterInterface {
+ public:
+ explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer)
+ : writer_(writer) {
+ DCHECK(writer_ != NULL);
+ }
+
+ virtual ~PpFrameWriterProxy() {}
+
+ virtual void PutFrame(PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) OVERRIDE {
+ writer_->PutFrame(image_data, time_stamp_ns);
+ }
+
+ private:
+ base::WeakPtr<PpFrameWriter> writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
+};
+
+bool VideoDestinationHandler::Open(
+ MediaStreamDependencyFactory* factory,
+ MediaStreamRegistryInterface* registry,
+ const std::string& url,
+ FrameWriterInterface** frame_writer) {
+ DVLOG(3) << "VideoDestinationHandler::Open";
+ if (!factory) {
+ factory = RenderThreadImpl::current()->GetMediaStreamDependencyFactory();
+ DCHECK(factory != NULL);
+ }
+ blink::WebMediaStream stream;
+ if (registry) {
+ stream = registry->GetMediaStream(url);
+ } else {
+ stream =
+ blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
+ }
+ if (stream.isNull()) {
+ LOG(ERROR) << "VideoDestinationHandler::Open - invalid url: " << url;
+ return false;
+ }
+
+ // Create a new native video track and add it to |stream|.
+ std::string track_id;
+ // According to spec, a media stream track's id should be globally unique.
+ // There's no easy way to strictly achieve that. The id generated with this
+ // method should be unique for most of the cases but theoretically it's
+ // possible we can get an id that's duplicated with the existing tracks.
+ // base::Base64Encode(base::RandBytesAsString(64), &track_id);
+ PpFrameWriter* writer = new PpFrameWriter(factory);
+
+ // Create a new webkit video track.
+ blink::WebMediaStreamSource webkit_source;
+ blink::WebMediaStreamSource::Type type =
+ blink::WebMediaStreamSource::TypeVideo;
+ blink::WebString webkit_track_id = base::UTF8ToUTF16(track_id);
+ webkit_source.initialize(webkit_track_id, type, webkit_track_id);
+ webkit_source.setExtraData(writer);
+
+ blink::WebMediaConstraints constraints;
+ constraints.initialize();
+ bool track_enabled = true;
+
+ stream.addTrack(MediaStreamVideoTrack::CreateVideoTrack(
+ writer, constraints, MediaStreamVideoSource::ConstraintsCallback(),
+ track_enabled, factory));
+
+ *frame_writer = new PpFrameWriterProxy(writer->AsWeakPtr());
+ return true;
+}
+
+} // namespace content
+

Powered by Google App Engine
This is Rietveld 408576698