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

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: Rebased 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/video_destination_handler.cc b/content/renderer/media/webrtc/video_destination_handler.cc
similarity index 40%
rename from content/renderer/media/video_destination_handler.cc
rename to content/renderer/media/webrtc/video_destination_handler.cc
index a76ca8974d855aa24476d9354ec7b6766848d951..ca3d4e45ffabc05c62e53bc147a09a0ffb04fd15 100644
--- a/content/renderer/media/video_destination_handler.cc
+++ b/content/renderer/media/webrtc/video_destination_handler.cc
@@ -2,102 +2,65 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/video_destination_handler.h"
+#include "content/renderer/media/webrtc/video_destination_handler.h"
#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"
-using cricket::CaptureState;
-using cricket::VideoFormat;
-using webrtc::VideoTrackInterface;
-using webrtc::VideoTrackVector;
-
-static const cricket::FourCC kEffectColorFormat = cricket::FOURCC_BGRA;
-
namespace content {
-PpFrameWriter::PpFrameWriter()
- : started_(false) {}
-
-PpFrameWriter::~PpFrameWriter() {}
-
-CaptureState PpFrameWriter::Start(const VideoFormat& capture_format) {
- base::AutoLock auto_lock(lock_);
- if (started_) {
- LOG(ERROR) << "PpFrameWriter::Start - "
- << "Got a StartCapture when already started!";
- return cricket::CS_FAILED;
- }
- started_ = true;
- return cricket::CS_STARTING;
-}
-
-void PpFrameWriter::Stop() {
- base::AutoLock auto_lock(lock_);
- started_ = false;
- SignalStateChange(this, cricket::CS_STOPPED);
+PpFrameWriter::PpFrameWriter(MediaStreamDependencyFactory* factory)
+ : MediaStreamVideoSource(factory), first_frame_received_(false) {
+ DVLOG(3) << "PpFrameWriter ctor";
}
-bool PpFrameWriter::IsRunning() {
- return started_;
+PpFrameWriter::~PpFrameWriter() {
+ DVLOG(3) << "PpFrameWriter dtor";
}
-bool PpFrameWriter::GetPreferredFourccs(std::vector<uint32>* fourccs) {
- if (!fourccs) {
- LOG(ERROR) << "PpFrameWriter::GetPreferredFourccs - "
- << "fourccs is NULL.";
- return false;
+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);
}
- // The effects plugin output BGRA.
- fourccs->push_back(kEffectColorFormat);
- return true;
}
-bool PpFrameWriter::GetBestCaptureFormat(const VideoFormat& desired,
- VideoFormat* best_format) {
- if (!best_format) {
- LOG(ERROR) << "PpFrameWriter::GetBestCaptureFormat - "
- << "best_format is NULL.";
- return false;
- }
-
- // Use the desired format as the best format.
- best_format->width = desired.width;
- best_format->height = desired.height;
- best_format->fourcc = kEffectColorFormat;
- best_format->interval = desired.interval;
- return true;
+void PpFrameWriter::StartSourceImpl(
+ const media::VideoCaptureParams& params) {
+ DCHECK(CalledOnValidThread());
+ DVLOG(3) << "PpFrameWriter::StartSourceImpl()";
+ OnStartDone(true);
}
-bool PpFrameWriter::IsScreencast() const {
- return false;
+void PpFrameWriter::StopSourceImpl() {
+ DCHECK(CalledOnValidThread());
}
void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
int64 time_stamp_ns) {
- base::AutoLock auto_lock(lock_);
- // This assumes the handler of the SignalFrameCaptured won't call Start/Stop.
- // TODO(ronghuawu): Avoid the using of lock. One way is to post this call to
- // libjingle worker thread, which will require an extra copy of |image_data|.
- // However if pepper host can hand over the ownership of |image_data|
- // then we can avoid this extra copy.
- if (!started_) {
- LOG(ERROR) << "PpFrameWriter::PutFrame - "
- << "Called when capturer is not started.";
- return;
- }
+ DCHECK(CalledOnValidThread());
+ DVLOG(3) << "PpFrameWriter::PutFrame()";
+
if (!image_data) {
LOG(ERROR) << "PpFrameWriter::PutFrame - Called with NULL image_data.";
return;
@@ -115,36 +78,51 @@ void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
return;
}
- cricket::CapturedFrame frame;
- frame.elapsed_time = 0;
- frame.time_stamp = time_stamp_ns;
- frame.pixel_height = 1;
- frame.pixel_width = 1;
- frame.width = bitmap->width();
- frame.height = bitmap->height();
- if (image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
- frame.fourcc = cricket::FOURCC_BGRA;
- } else {
- LOG(ERROR) << "PpFrameWriter::PutFrame - Got RGBA which is not supported.";
- return;
+ const gfx::Size frame_size(bitmap->width(), bitmap->height());
+
+ if (!first_frame_received_) {
+ first_frame_received_ = true;
+ format_ = media::VideoCaptureFormat(
+ frame_size,
+ MediaStreamVideoSource::kDefaultFrameRate,
+ media::PIXEL_FORMAT_I420);
+ if (state() == MediaStreamVideoSource::RETRIEVING_CAPABILITIES) {
+ media::VideoCaptureFormats formats;
+ formats.push_back(format_);
+ OnSupportedFormats(formats);
+ }
}
- frame.data_size = bitmap->getSize();
- frame.data = bitmap->getPixels();
- // This signals to libJingle that a new VideoFrame is available.
- // libJingle have no assumptions on what thread this signal come from.
- SignalFrameCaptured(this, &frame);
+ 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 -
+// PpFrameWriter after it is released (IOW its owner - WebMediaStreamSource -
// is released).
class PpFrameWriterProxy : public FrameWriterInterface {
public:
- PpFrameWriterProxy(VideoTrackInterface* track,
- PpFrameWriter* writer)
- : track_(track),
- writer_(writer) {
+ explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer)
+ : writer_(writer) {
DCHECK(writer_ != NULL);
}
@@ -156,8 +134,7 @@ class PpFrameWriterProxy : public FrameWriterInterface {
}
private:
- scoped_refptr<VideoTrackInterface> track_;
- PpFrameWriter* writer_;
+ base::WeakPtr<PpFrameWriter> writer_;
DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
};
@@ -167,6 +144,7 @@ bool VideoDestinationHandler::Open(
MediaStreamRegistryInterface* registry,
const std::string& url,
FrameWriterInterface** frame_writer) {
+ DVLOG(3) << "VideoDestinationHandler::Open";
if (!factory) {
factory = RenderThreadImpl::current()->GetMediaStreamDependencyFactory();
DCHECK(factory != NULL);
@@ -178,32 +156,38 @@ bool VideoDestinationHandler::Open(
stream =
blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
}
- if (stream.isNull() || !stream.extraData()) {
+ 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.
+ // According to spec, a media stream source's id should be unique per
+ // application. 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 sources.
base::Base64Encode(base::RandBytesAsString(64), &track_id);
- PpFrameWriter* writer = new PpFrameWriter();
- if (!factory->AddNativeVideoMediaTrack(track_id, &stream, writer)) {
- delete writer;
- return false;
- }
+ 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;
- // Gets a handler to the native video track, which owns the |writer|.
- webrtc::MediaStreamInterface* native_stream = MediaStream::GetAdapter(stream);
- DCHECK(native_stream);
- VideoTrackVector video_tracks = native_stream->GetVideoTracks();
- // Currently one supports one video track per media stream.
- DCHECK(video_tracks.size() == 1);
+ stream.addTrack(MediaStreamVideoTrack::CreateVideoTrack(
+ writer, constraints, MediaStreamVideoSource::ConstraintsCallback(),
+ track_enabled, factory));
- *frame_writer = new PpFrameWriterProxy(video_tracks[0].get(), writer);
+ *frame_writer = new PpFrameWriterProxy(writer->AsWeakPtr());
return true;
}

Powered by Google App Engine
This is Rietveld 408576698