0

Remove VideoDestination_Private and VideoSource_Private PPAPI

Those can only be used by the old Hangouts effect plugin and it isn't
used anymore.
Since those APIs depend on URL.createObjectURL(MediaStream) which is
deprecated, it is necessary to first remove them from the codebase
in order to continue removing URL.createObjectURL(MediaStream).

Bug: 852412
Change-Id: If64e8e7259a6d51ccf89362b59c9d6fc7c890a30
Reviewed-on: https://chromium-review.googlesource.com/1099159
Commit-Queue: Florent Castelli <orphis@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#588819}
This commit is contained in:
Florent Castelli
2018-09-05 10:32:50 +00:00
committed by Commit Bot
parent b1a7e23aa7
commit de49ea19de
63 changed files with 1 additions and 3591 deletions
BUILD.gn
chrome
content
ppapi

@ -139,7 +139,6 @@ group("gn_all") {
"//ppapi/examples/url_loader",
"//ppapi/examples/video_capture",
"//ppapi/examples/video_decode",
"//ppapi/examples/video_effects",
"//ppapi/examples/video_encode",
"//printing:printing_unittests",
"//third_party/SPIRV-Tools/src:SPIRV-Tools",

@ -96,8 +96,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/trusted/ppb_broker_trusted.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"

@ -1427,24 +1427,6 @@ ChromeContentRendererClient::OverrideSpeechSynthesizer(
return std::make_unique<TtsDispatcher>(client);
}
bool ChromeContentRendererClient::AllowPepperMediaStreamAPI(
const GURL& url) {
#if defined(OS_ANDROID)
return false;
#else
// Allow access for tests.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePepperTesting)) {
return true;
}
// Allow only the Hangouts app to use the MediaStream APIs. It's OK to check
// the whitelist in the renderer, since we're only preventing access until
// these APIs are public and stable.
return (AppCategorizer::IsHangoutsUrl(url));
#endif // !defined(OS_ANDROID)
}
void ChromeContentRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
key_systems_provider_.AddSupportedKeySystems(key_systems);

@ -185,7 +185,6 @@ class ChromeContentRendererClient
std::unique_ptr<blink::WebContentSettingsClient>
CreateWorkerContentSettingsClient(
content::RenderFrame* render_frame) override;
bool AllowPepperMediaStreamAPI(const GURL& url) override;
void AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
override;

@ -67,9 +67,9 @@ const bool kHostedApp = true;
const char kExtensionUrl[] = "chrome-extension://extension_id/background.html";
const char kChatManifestFS[] = "filesystem:https://talkgadget.google.com/foo";
#endif
const char kChatAppURL[] = "https://talkgadget.google.com/hangouts/foo";
#endif
void AddContentTypeHandler(content::WebPluginInfo* info,
const char* mime_type,
@ -304,15 +304,6 @@ TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
#endif // BUILDFLAG(ENABLE_NACL)
}
TEST_F(ChromeContentRendererClientTest, AllowPepperMediaStreamAPI) {
ChromeContentRendererClient test;
#if defined(OS_ANDROID)
EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL)));
#else
EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL)));
#endif
}
// SearchBouncer doesn't exist on Android.
#if !defined(OS_ANDROID)
TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {

@ -1465,14 +1465,6 @@ TEST_PPAPI_NACL(MAYBE_VideoDecoder)
TEST_PPAPI_NACL(VideoEncoder)
// VideoDestination doesn't work in content_browsertests.
TEST_PPAPI_OUT_OF_PROCESS(VideoDestination)
TEST_PPAPI_NACL(VideoDestination)
// VideoSource doesn't work in content_browsertests.
TEST_PPAPI_OUT_OF_PROCESS(VideoSource)
TEST_PPAPI_NACL(VideoSource)
// Printing doesn't work in content_browsertests.
TEST_PPAPI_OUT_OF_PROCESS(Printing)

@ -170,10 +170,6 @@ bool ContentRendererClient::IsOriginIsolatedPepperPlugin(
return false;
}
bool ContentRendererClient::AllowPepperMediaStreamAPI(const GURL& url) {
return false;
}
void ContentRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) {}

@ -272,9 +272,6 @@ class CONTENT_EXPORT ContentRendererClient {
// language.
virtual bool IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path);
// Returns true if the page at |url| can use Pepper MediaStream APIs.
virtual bool AllowPepperMediaStreamAPI(const GURL& url);
// Allows an embedder to provide a MediaStreamRendererFactory.
virtual std::unique_ptr<MediaStreamRendererFactory>
CreateMediaStreamRendererFactory();

@ -844,20 +844,12 @@ target(link_target_type, "renderer") {
if (enable_plugins) {
sources += [
"media/pepper/pepper_to_video_track_adapter.cc",
"media/pepper/pepper_to_video_track_adapter.h",
"media/pepper/video_track_to_pepper_adapter.cc",
"media/pepper/video_track_to_pepper_adapter.h",
"pepper/pepper_media_stream_audio_track_host.cc",
"pepper/pepper_media_stream_audio_track_host.h",
"pepper/pepper_media_stream_track_host_base.cc",
"pepper/pepper_media_stream_track_host_base.h",
"pepper/pepper_media_stream_video_track_host.cc",
"pepper/pepper_media_stream_video_track_host.h",
"pepper/pepper_video_destination_host.cc",
"pepper/pepper_video_destination_host.h",
"pepper/pepper_video_source_host.cc",
"pepper/pepper_video_source_host.h",
]
}

@ -1,250 +0,0 @@
// 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/pepper/pepper_to_video_track_adapter.h"
#include <string>
#include "base/base64.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "content/renderer/media/stream/media_stream_registry_interface.h"
#include "content/renderer/media/stream/media_stream_video_source.h"
#include "content/renderer/media/stream/media_stream_video_track.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/video_frame_pool.h"
#include "media/capture/video_capture_types.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_media_stream_registry.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "url/gurl.h"
namespace content {
// PpFrameWriter implements MediaStreamVideoSource and can therefore provide
// video frames to MediaStreamVideoTracks. It also implements
// FrameWriterInterface, which will be used by Pepper plugins (notably the
// Effects plugin) to inject the processed frame.
class PpFrameWriter : public MediaStreamVideoSource,
public FrameWriterInterface,
public base::SupportsWeakPtr<PpFrameWriter> {
public:
PpFrameWriter();
~PpFrameWriter() override;
// FrameWriterInterface implementation.
// This method will be called by the Pepper host from render thread.
void PutFrame(PPB_ImageData_Impl* image_data, int64_t time_stamp_ns) override;
protected:
// MediaStreamVideoSource implementation.
void StartSourceImpl(
const VideoCaptureDeliverFrameCB& frame_callback) override;
void StopSourceImpl() override;
private:
media::VideoFramePool frame_pool_;
class FrameWriterDelegate;
scoped_refptr<FrameWriterDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(PpFrameWriter);
};
class PpFrameWriter::FrameWriterDelegate
: public base::RefCountedThreadSafe<FrameWriterDelegate> {
public:
FrameWriterDelegate(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const VideoCaptureDeliverFrameCB& new_frame_callback);
void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame);
private:
friend class base::RefCountedThreadSafe<FrameWriterDelegate>;
virtual ~FrameWriterDelegate();
void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame);
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
VideoCaptureDeliverFrameCB new_frame_callback_;
};
PpFrameWriter::FrameWriterDelegate::FrameWriterDelegate(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const VideoCaptureDeliverFrameCB& new_frame_callback)
: io_task_runner_(io_task_runner), new_frame_callback_(new_frame_callback) {
}
PpFrameWriter::FrameWriterDelegate::~FrameWriterDelegate() {
}
void PpFrameWriter::FrameWriterDelegate::DeliverFrame(
const scoped_refptr<media::VideoFrame>& frame) {
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FrameWriterDelegate::DeliverFrameOnIO, this, frame));
}
void PpFrameWriter::FrameWriterDelegate::DeliverFrameOnIO(
const scoped_refptr<media::VideoFrame>& frame) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
// The local time when this frame is generated is unknown so give a null
// value to |estimated_capture_time|.
new_frame_callback_.Run(frame, base::TimeTicks());
}
PpFrameWriter::PpFrameWriter() {
DVLOG(3) << "PpFrameWriter ctor";
}
PpFrameWriter::~PpFrameWriter() {
DVLOG(3) << "PpFrameWriter dtor";
}
void PpFrameWriter::StartSourceImpl(
const VideoCaptureDeliverFrameCB& frame_callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!delegate_.get());
DVLOG(3) << "PpFrameWriter::StartSourceImpl()";
delegate_ = new FrameWriterDelegate(io_task_runner(), frame_callback);
OnStartDone(MEDIA_DEVICE_OK);
}
void PpFrameWriter::StopSourceImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
// Note: PutFrame must copy or process image_data directly in this function,
// because it may be overwritten as soon as we return from this function.
void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
int64_t time_stamp_ns) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
TRACE_EVENT0("media", "PpFrameWriter::PutFrame");
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;
}
SkBitmap bitmap(image_data->GetMappedBitmap());
if (bitmap.empty()) {
LOG(ERROR) << "PpFrameWriter::PutFrame - "
<< "The image_data's mapped bitmap failed.";
return;
}
const uint8_t* src_data = static_cast<uint8_t*>(bitmap.getPixels());
const int src_stride = static_cast<int>(bitmap.rowBytes());
const int width = bitmap.width();
const int height = bitmap.height();
// We only support PP_IMAGEDATAFORMAT_BGRA_PREMUL at the moment.
DCHECK(image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL);
const gfx::Size frame_size(width, height);
if (state() != MediaStreamVideoSource::STARTED)
return;
const base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
time_stamp_ns / base::Time::kNanosecondsPerMicrosecond);
scoped_refptr<media::VideoFrame> new_frame =
frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, frame_size,
gfx::Rect(frame_size), frame_size, timestamp);
libyuv::ARGBToI420(src_data,
src_stride,
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),
width,
height);
delegate_->DeliverFrame(new_frame);
}
// PpFrameWriterProxy is a helper class to make sure the user won't use
// PpFrameWriter after it is released (IOW its owner - WebMediaStreamSource -
// is released).
class PpFrameWriterProxy : public FrameWriterInterface {
public:
explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer)
: writer_(writer) {
DCHECK(writer_);
}
~PpFrameWriterProxy() override {}
void PutFrame(PPB_ImageData_Impl* image_data,
int64_t time_stamp_ns) override {
writer_->PutFrame(image_data, time_stamp_ns);
}
private:
base::WeakPtr<PpFrameWriter> writer_;
DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
};
bool PepperToVideoTrackAdapter::Open(MediaStreamRegistryInterface* registry,
const std::string& url,
FrameWriterInterface** frame_writer) {
DVLOG(3) << "PepperToVideoTrackAdapter::Open";
blink::WebMediaStream stream;
if (registry) {
stream = registry->GetMediaStream(url);
} else {
stream =
blink::WebMediaStreamRegistry::LookupMediaStreamDescriptor(GURL(url));
}
if (stream.IsNull()) {
LOG(ERROR) << "PepperToVideoTrackAdapter::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 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();
// Create a new webkit video track.
blink::WebMediaStreamSource webkit_source;
blink::WebMediaStreamSource::Type type =
blink::WebMediaStreamSource::kTypeVideo;
blink::WebString webkit_track_id = blink::WebString::FromUTF8(track_id);
webkit_source.Initialize(webkit_track_id, type, webkit_track_id,
false /* remote */);
webkit_source.SetExtraData(writer);
bool track_enabled = true;
stream.AddTrack(MediaStreamVideoTrack::CreateVideoTrack(
writer, MediaStreamVideoSource::ConstraintsCallback(), track_enabled));
*frame_writer = new PpFrameWriterProxy(writer->AsWeakPtr());
return true;
}
} // namespace content

@ -1,54 +0,0 @@
// 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.
#ifndef CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_
#define CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
namespace content {
class MediaStreamRegistryInterface;
class PPB_ImageData_Impl;
// Interface used by a Pepper plugin to output frames to a video track.
class CONTENT_EXPORT FrameWriterInterface {
public:
// The ownership of the |image_data| doesn't transfer. So the implementation
// of this interface should make a copy of the |image_data| before return.
virtual void PutFrame(PPB_ImageData_Impl* image_data,
int64_t time_stamp_ns) = 0;
virtual ~FrameWriterInterface() {}
};
// PepperToVideoTrackAdapter is a glue class between the content MediaStream and
// the effects pepper plugin host.
class CONTENT_EXPORT PepperToVideoTrackAdapter {
public:
// Instantiates and adds a new video track to the MediaStream specified by
// |url|. Returns a handler for delivering frames to the new video track as
// |frame_writer|.
// If |registry| is NULL the global blink::WebMediaStreamRegistry will be
// used to look up the media stream.
// The caller of the function takes the ownership of |frame_writer|.
// Returns true on success and false on failure.
static bool Open(MediaStreamRegistryInterface* registry,
const std::string& url,
FrameWriterInterface** frame_writer);
private:
DISALLOW_COPY_AND_ASSIGN(PepperToVideoTrackAdapter);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_

@ -1,111 +0,0 @@
// 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 <string>
#include "base/run_loop.h"
#include "content/child/child_process.h"
#include "content/public/test/mock_render_thread.h"
#include "content/renderer/media/pepper/pepper_to_video_track_adapter.h"
#include "content/renderer/media/stream/media_stream_video_track.h"
#include "content/renderer/media/stream/mock_media_stream_registry.h"
#include "content/renderer/media/stream/mock_media_stream_video_sink.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/test/ppapi_unittest.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
using ::testing::_;
namespace content {
ACTION_P(RunClosure, closure) {
closure.Run();
}
static const std::string kTestStreamUrl = "stream_url";
static const std::string kUnknownStreamUrl = "unknown_stream_url";
class PepperToVideoTrackAdapterTest : public PpapiUnittest {
public:
PepperToVideoTrackAdapterTest() : registry_(new MockMediaStreamRegistry()) {
registry_->Init(kTestStreamUrl);
}
void TearDown() override {
registry_.reset();
blink::WebHeap::CollectAllGarbageForTesting();
PpapiUnittest::TearDown();
}
protected:
// A ChildProcess is needed to fool the Tracks and Sources into believing they
// are on the right threads. The ScopedTaskEnvironment provided by
// PpapiUnittest prevents the ChildProcess from leaking a TaskScheduler.
const ChildProcess child_process_;
const MockRenderThread render_thread_;
std::unique_ptr<MockMediaStreamRegistry> registry_;
};
TEST_F(PepperToVideoTrackAdapterTest, Open) {
// |frame_writer| is a proxy and is owned by whoever call Open.
FrameWriterInterface* frame_writer = nullptr;
// Unknow url will return false.
EXPECT_FALSE(PepperToVideoTrackAdapter::Open(registry_.get(),
kUnknownStreamUrl, &frame_writer));
EXPECT_TRUE(PepperToVideoTrackAdapter::Open(registry_.get(),
kTestStreamUrl, &frame_writer));
delete frame_writer;
}
TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
FrameWriterInterface* frame_writer = nullptr;
EXPECT_TRUE(PepperToVideoTrackAdapter::Open(registry_.get(),
kTestStreamUrl, &frame_writer));
ASSERT_TRUE(frame_writer);
// Verify the video track has been added.
const blink::WebMediaStream test_stream = registry_->test_stream();
blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
test_stream.VideoTracks();
ASSERT_EQ(1u, video_tracks.size());
// Verify the native video track has been added.
MediaStreamVideoTrack* native_track =
MediaStreamVideoTrack::GetVideoTrack(video_tracks[0]);
ASSERT_TRUE(native_track != nullptr);
MockMediaStreamVideoSink sink;
native_track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
scoped_refptr<PPB_ImageData_Impl> image(new PPB_ImageData_Impl(
instance()->pp_instance(), PPB_ImageData_Impl::ForTest()));
image->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 640, 360, true);
{
base::RunLoop run_loop;
base::Closure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(sink, OnVideoFrame())
.WillOnce(RunClosure(std::move(quit_closure)));
frame_writer->PutFrame(image.get(), 10);
run_loop.Run();
// Run all pending tasks to let the the test clean up before the test ends.
// This is due to that
// FrameWriterDelegate::FrameWriterDelegate::DeliverFrame use
// PostTaskAndReply to the IO thread and expects the reply to process
// on the main render thread to clean up its resources. However, the
// QuitClosure above ends before that.
base::RunLoop().RunUntilIdle();
}
EXPECT_EQ(1, sink.number_of_frames());
native_track->RemoveSink(&sink);
// The |frame_writer| is a proxy and is owned by whoever call Open.
delete frame_writer;
}
} // namespace content

@ -1,140 +0,0 @@
// 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/pepper/video_track_to_pepper_adapter.h"
#include <string>
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/trace_event.h"
#include "content/public/renderer/media_stream_video_sink.h"
#include "content/renderer/media/stream/media_stream_registry_interface.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/video_capture_types.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_media_stream_registry.h"
#include "url/gurl.h"
namespace content {
// PpFrameReceiver implements MediaStreamVideoSink so that it can be attached
// to video track to receive captured frames.
// It can be attached to a FrameReaderInterface to output the received frame.
class PpFrameReceiver : public MediaStreamVideoSink {
public:
PpFrameReceiver(blink::WebMediaStreamTrack track)
: track_(track), reader_(nullptr), weak_factory_(this) {}
~PpFrameReceiver() override {}
void SetReader(FrameReaderInterface* reader) {
DCHECK((reader_ && !reader) || (!reader_ && reader))
<< " |reader| = " << reader << ", |reader_| = " << reader_;
if (reader) {
MediaStreamVideoSink::ConnectToTrack(
track_,
media::BindToCurrentLoop(base::Bind(&PpFrameReceiver::OnVideoFrame,
weak_factory_.GetWeakPtr())),
false);
} else {
MediaStreamVideoSink::DisconnectFromTrack();
weak_factory_.InvalidateWeakPtrs();
}
reader_ = reader;
}
void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
base::TimeTicks estimated_capture_time) {
TRACE_EVENT0("media", "PpFrameReceiver::OnVideoFrame");
if (reader_)
reader_->GotFrame(frame);
}
private:
const blink::WebMediaStreamTrack track_;
FrameReaderInterface* reader_;
base::WeakPtrFactory<PpFrameReceiver> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
};
VideoTrackToPepperAdapter::VideoTrackToPepperAdapter(
MediaStreamRegistryInterface* registry)
: registry_(registry) {}
VideoTrackToPepperAdapter::~VideoTrackToPepperAdapter() {
for (const auto& reader_and_receiver : reader_to_receiver_)
delete reader_and_receiver.second;
}
bool VideoTrackToPepperAdapter::Open(const std::string& url,
FrameReaderInterface* reader) {
DCHECK(thread_checker_.CalledOnValidThread());
const blink::WebMediaStreamTrack& track = GetFirstVideoTrack(url);
if (track.IsNull())
return false;
reader_to_receiver_[reader] = new SourceInfo(track, reader);
return true;
}
bool VideoTrackToPepperAdapter::Close(FrameReaderInterface* reader) {
DCHECK(thread_checker_. CalledOnValidThread());
SourceInfoMap::iterator it = reader_to_receiver_.find(reader);
if (it == reader_to_receiver_.end())
return false;
delete it->second;
reader_to_receiver_.erase(it);
return true;
}
blink::WebMediaStreamTrack VideoTrackToPepperAdapter::GetFirstVideoTrack(
const std::string& url) {
DCHECK(thread_checker_.CalledOnValidThread());
const blink::WebMediaStream stream =
registry_ ? registry_->GetMediaStream(url)
: blink::WebMediaStreamRegistry::LookupMediaStreamDescriptor(
GURL(url));
if (stream.IsNull()) {
LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
return blink::WebMediaStreamTrack();
}
// Get the first video track from the stream.
blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
stream.VideoTracks();
if (video_tracks.IsEmpty()) {
LOG(ERROR) << "GetFirstVideoSource - no video tracks. url: " << url;
return blink::WebMediaStreamTrack();
}
return video_tracks[0];
}
void VideoTrackToPepperAdapter::DeliverFrameForTesting(
FrameReaderInterface* reader,
const scoped_refptr<media::VideoFrame>& frame) {
SourceInfoMap::const_iterator it = reader_to_receiver_.find(reader);
if (it == reader_to_receiver_.end())
return;
PpFrameReceiver* receiver = it->second->receiver_.get();
receiver->OnVideoFrame(frame, base::TimeTicks());
}
VideoTrackToPepperAdapter::SourceInfo::SourceInfo(
const blink::WebMediaStreamTrack& blink_track,
FrameReaderInterface* reader)
: receiver_(new PpFrameReceiver(blink_track)) {
receiver_->SetReader(reader);
}
VideoTrackToPepperAdapter::SourceInfo::~SourceInfo() {
receiver_->SetReader(nullptr);
}
} // namespace content

@ -1,81 +0,0 @@
// 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.
#ifndef CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_
#define CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_
#include <map>
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
namespace content {
class MediaStreamRegistryInterface;
class PpFrameReceiver;
// Interface used by a Pepper plugin to get captured frames from a video track.
class CONTENT_EXPORT FrameReaderInterface {
public:
// Got a new captured frame.
virtual void GotFrame(const scoped_refptr<media::VideoFrame>& frame) = 0;
protected:
virtual ~FrameReaderInterface() {}
};
// VideoTrackToPepperAdapter is a glue class between MediaStreamVideoTrack and a
// Pepper plugin host.
class CONTENT_EXPORT VideoTrackToPepperAdapter {
public:
// |registry| is used to look up the media stream by url. If a NULL |registry|
// is given, the global blink::WebMediaStreamRegistry will be used.
explicit VideoTrackToPepperAdapter(MediaStreamRegistryInterface* registry);
virtual ~VideoTrackToPepperAdapter();
// Connects to the first video track in the MediaStream specified by |url| and
// the received frames will be delivered via |reader|.
// Returns true on success and false on failure.
bool Open(const std::string& url, FrameReaderInterface* reader);
// Closes |reader|'s connection with the video track, i.e. stops receiving
// frames from the video track.
// Returns true on success and false on failure.
bool Close(FrameReaderInterface* reader);
private:
friend class VideoTrackToPepperAdapterTest;
struct SourceInfo {
SourceInfo(const blink::WebMediaStreamTrack& blink_track,
FrameReaderInterface* reader);
~SourceInfo();
std::unique_ptr<PpFrameReceiver> receiver_;
};
typedef std::map<FrameReaderInterface*, SourceInfo*> SourceInfoMap;
blink::WebMediaStreamTrack GetFirstVideoTrack(const std::string& url);
// Deliver VideoFrame to the MediaStreamVideoSink associated with
// |reader|. For testing only.
void DeliverFrameForTesting(FrameReaderInterface* reader,
const scoped_refptr<media::VideoFrame>& frame);
MediaStreamRegistryInterface* const registry_;
SourceInfoMap reader_to_receiver_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(VideoTrackToPepperAdapter);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_

@ -1,76 +0,0 @@
// 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 <string>
#include "base/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/renderer/media/pepper/video_track_to_pepper_adapter.h"
#include "content/renderer/media/stream/mock_media_stream_registry.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_heap.h"
namespace content {
static const std::string kTestStreamUrl = "stream_url";
static const std::string kTestVideoTrackId = "video_track_id";
static const std::string kUnknownStreamUrl = "unknown_stream_url";
class VideoTrackToPepperAdapterTest : public ::testing::Test,
public FrameReaderInterface {
public:
VideoTrackToPepperAdapterTest() : registry_(new MockMediaStreamRegistry()) {
handler_.reset(new VideoTrackToPepperAdapter(registry_.get()));
registry_->Init(kTestStreamUrl);
registry_->AddVideoTrack(kTestVideoTrackId);
EXPECT_FALSE(handler_->GetFirstVideoTrack(kTestStreamUrl).IsNull());
}
MOCK_METHOD1(GotFrame, void(const scoped_refptr<media::VideoFrame>&));
void TearDown() override {
registry_.reset();
handler_.reset();
blink::WebHeap::CollectAllGarbageForTesting();
}
void DeliverFrameForTesting(const scoped_refptr<media::VideoFrame>& frame) {
handler_->DeliverFrameForTesting(this, frame);
}
protected:
// A ChildProcess is needed to fool the Tracks and Sources below into
// believing they are on the right threads. A ScopedTaskEnvironment must be
// instantiated before ChildProcess to prevent it from leaking a
// TaskScheduler.
const base::test::ScopedTaskEnvironment scoped_task_environment_;
const ChildProcess child_process_;
std::unique_ptr<VideoTrackToPepperAdapter> handler_;
std::unique_ptr<MockMediaStreamRegistry> registry_;
};
// Open |handler_| and send a VideoFrame to be received at the other side.
TEST_F(VideoTrackToPepperAdapterTest, OpenClose) {
// Unknow url will return false.
EXPECT_FALSE(handler_->Open(kUnknownStreamUrl, this));
EXPECT_TRUE(handler_->Open(kTestStreamUrl, this));
const base::TimeDelta ts = base::TimeDelta::FromMilliseconds(789012);
const scoped_refptr<media::VideoFrame> captured_frame =
media::VideoFrame::CreateBlackFrame(gfx::Size(640, 360));
captured_frame->set_timestamp(ts);
EXPECT_CALL(*this, GotFrame(captured_frame));
DeliverFrameForTesting(captured_frame);
EXPECT_FALSE(handler_->Close(nullptr));
EXPECT_TRUE(handler_->Close(this));
}
TEST_F(VideoTrackToPepperAdapterTest, OpenWithoutClose) {
EXPECT_TRUE(handler_->Open(kTestStreamUrl, this));
}
} // namespace content

@ -27,9 +27,7 @@
#include "content/renderer/pepper/pepper_url_loader_host.h"
#include "content/renderer/pepper/pepper_video_capture_host.h"
#include "content/renderer/pepper/pepper_video_decoder_host.h"
#include "content/renderer/pepper/pepper_video_destination_host.h"
#include "content/renderer/pepper/pepper_video_encoder_host.h"
#include "content/renderer/pepper/pepper_video_source_host.h"
#include "content/renderer/pepper/pepper_websocket_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
@ -55,18 +53,6 @@ namespace content {
namespace {
bool CanUseMediaStreamAPI(const RendererPpapiHost* host, PP_Instance instance) {
blink::WebPluginContainer* container =
host->GetContainerForInstance(instance);
if (!container)
return false;
GURL document_url = container->GetDocument().Url();
ContentRendererClient* content_renderer_client =
GetContentClient()->renderer();
return content_renderer_client->AllowPepperMediaStreamAPI(document_url);
}
static bool CanUseCameraDeviceAPI(const RendererPpapiHost* host,
PP_Instance instance) {
blink::WebPluginContainer* container =
@ -187,19 +173,6 @@ ContentRendererPepperHostFactory::CreateResourceHost(
case PpapiHostMsg_MediaStreamVideoTrack_Create::ID:
return std::make_unique<PepperMediaStreamVideoTrackHost>(host_, instance,
resource);
// These private MediaStream interfaces are exposed as if they were public
// so they can be used by NaCl plugins. However, they are available only
// for whitelisted apps.
case PpapiHostMsg_VideoDestination_Create::ID:
if (CanUseMediaStreamAPI(host_, instance))
return std::make_unique<PepperVideoDestinationHost>(host_, instance,
resource);
return nullptr;
case PpapiHostMsg_VideoSource_Create::ID:
if (CanUseMediaStreamAPI(host_, instance))
return std::make_unique<PepperVideoSourceHost>(host_, instance,
resource);
return nullptr;
}
// Dev interfaces.

@ -1,108 +0,0 @@
// 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/pepper/pepper_video_destination_host.h"
#include "base/time/time.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
using ppapi::host::HostMessageContext;
using ppapi::host::ReplyMessageContext;
namespace content {
PepperVideoDestinationHost::PepperVideoDestinationHost(RendererPpapiHost* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
#if DCHECK_IS_ON()
has_received_frame_(false),
#endif
weak_factory_(this) {}
PepperVideoDestinationHost::~PepperVideoDestinationHost() {}
int32_t PepperVideoDestinationHost::OnResourceMessageReceived(
const IPC::Message& msg,
HostMessageContext* context) {
PPAPI_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_Open,
OnHostMsgOpen)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_PutFrame,
OnHostMsgPutFrame)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDestination_Close,
OnHostMsgClose)
PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
int32_t PepperVideoDestinationHost::OnHostMsgOpen(
HostMessageContext* context,
const std::string& stream_url) {
GURL gurl(stream_url);
if (!gurl.is_valid())
return PP_ERROR_BADARGUMENT;
FrameWriterInterface* frame_writer = nullptr;
if (!PepperToVideoTrackAdapter::Open(nullptr /* registry */, gurl.spec(),
&frame_writer))
return PP_ERROR_FAILED;
frame_writer_.reset(frame_writer);
ReplyMessageContext reply_context = context->MakeReplyMessageContext();
reply_context.params.set_result(PP_OK);
host()->SendReply(reply_context, PpapiPluginMsg_VideoDestination_OpenReply());
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperVideoDestinationHost::OnHostMsgPutFrame(
HostMessageContext* context,
const ppapi::HostResource& image_data_resource,
PP_TimeTicks timestamp) {
ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> enter(
image_data_resource.host_resource(), true);
if (enter.failed())
return PP_ERROR_BADRESOURCE;
PPB_ImageData_Impl* image_data_impl =
static_cast<PPB_ImageData_Impl*>(enter.object());
if (!PPB_ImageData_Impl::IsImageDataFormatSupported(
image_data_impl->format()))
return PP_ERROR_BADARGUMENT;
if (!frame_writer_.get())
return PP_ERROR_FAILED;
// Convert PP_TimeTicks (a double, in seconds) to a video timestamp (int64_t,
// nanoseconds).
const int64_t timestamp_ns =
static_cast<int64_t>(timestamp * base::Time::kNanosecondsPerSecond);
// Check that timestamps are strictly increasing.
#if DCHECK_IS_ON()
if (has_received_frame_)
DCHECK_GT(timestamp_ns, previous_timestamp_ns_);
has_received_frame_ = true;
previous_timestamp_ns_ = timestamp_ns;
#endif
frame_writer_->PutFrame(image_data_impl, timestamp_ns);
return PP_OK;
}
int32_t PepperVideoDestinationHost::OnHostMsgClose(
HostMessageContext* context) {
frame_writer_.reset(nullptr);
return PP_OK;
}
} // namespace content

@ -1,59 +0,0 @@
// 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.
#ifndef CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
#include <stdint.h>
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/renderer/media/pepper/pepper_to_video_track_adapter.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/host/resource_host.h"
namespace content {
class RendererPpapiHost;
class CONTENT_EXPORT PepperVideoDestinationHost
: public ppapi::host::ResourceHost {
public:
PepperVideoDestinationHost(RendererPpapiHost* host,
PP_Instance instance,
PP_Resource resource);
~PepperVideoDestinationHost() override;
int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) override;
private:
int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
const std::string& stream_url);
int32_t OnHostMsgPutFrame(ppapi::host::HostMessageContext* context,
const ppapi::HostResource& image_data_resource,
PP_TimeTicks timestamp);
int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
std::unique_ptr<FrameWriterInterface> frame_writer_;
// Used for checking that timestamps are strictly increasing.
#if DCHECK_IS_ON()
bool has_received_frame_;
int64_t previous_timestamp_ns_;
#endif
base::WeakPtrFactory<PepperVideoDestinationHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperVideoDestinationHost);
};
} // namespace content
#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_

@ -1,322 +0,0 @@
// 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/pepper/pepper_video_source_host.h"
#include <string.h>
#include "base/bind.h"
#include "base/numerics/safe_conversions.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/media/pepper/video_track_to_pepper_adapter.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/video_util.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_image_data_proxy.h"
#include "ppapi/shared_impl/scoped_pp_resource.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/scale.h"
#include "third_party/skia/include/core/SkBitmap.h"
using ppapi::host::HostMessageContext;
using ppapi::host::ReplyMessageContext;
namespace content {
class PepperVideoSourceHost::FrameReceiver
: public FrameReaderInterface,
public base::RefCountedThreadSafe<FrameReceiver> {
public:
explicit FrameReceiver(const base::WeakPtr<PepperVideoSourceHost>& host);
// FrameReaderInterface implementation.
void GotFrame(const scoped_refptr<media::VideoFrame>& frame) override;
private:
friend class base::RefCountedThreadSafe<FrameReceiver>;
~FrameReceiver() override;
base::WeakPtr<PepperVideoSourceHost> host_;
// |thread_checker_| is bound to the main render thread.
base::ThreadChecker thread_checker_;
};
PepperVideoSourceHost::FrameReceiver::FrameReceiver(
const base::WeakPtr<PepperVideoSourceHost>& host)
: host_(host) {}
PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {}
void PepperVideoSourceHost::FrameReceiver::GotFrame(
const scoped_refptr<media::VideoFrame>& video_frame) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!host_)
return;
if (!(video_frame->format() == media::PIXEL_FORMAT_I420 ||
video_frame->format() == media::PIXEL_FORMAT_I420A)) {
NOTREACHED();
return;
}
scoped_refptr<media::VideoFrame> frame = video_frame;
// Drop alpha channel since we do not support it yet.
if (frame->format() == media::PIXEL_FORMAT_I420A)
frame = media::WrapAsI420VideoFrame(video_frame);
// Hold a reference to the new frame and release the previous.
host_->last_frame_ = frame;
if (host_->get_frame_pending_)
host_->SendGetFrameReply();
}
PepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
frame_source_(new VideoTrackToPepperAdapter(nullptr)),
get_frame_pending_(false),
weak_factory_(this) {
frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr());
memset(&shared_image_desc_, 0, sizeof(shared_image_desc_));
}
PepperVideoSourceHost::~PepperVideoSourceHost() { Close(); }
int32_t PepperVideoSourceHost::OnResourceMessageReceived(
const IPC::Message& msg,
HostMessageContext* context) {
PPAPI_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open,
OnHostMsgOpen)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame,
OnHostMsgGetFrame)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close,
OnHostMsgClose)
PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context,
const std::string& stream_url) {
GURL gurl(stream_url);
if (!gurl.is_valid())
return PP_ERROR_BADARGUMENT;
if (!frame_source_->Open(gurl.spec(), frame_receiver_.get()))
return PP_ERROR_BADARGUMENT;
stream_url_ = gurl.spec();
ReplyMessageContext reply_context = context->MakeReplyMessageContext();
reply_context.params.set_result(PP_OK);
host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply());
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperVideoSourceHost::OnHostMsgGetFrame(HostMessageContext* context) {
if (!frame_source_.get())
return PP_ERROR_FAILED;
if (get_frame_pending_)
return PP_ERROR_INPROGRESS;
reply_context_ = context->MakeReplyMessageContext();
get_frame_pending_ = true;
// If a frame is ready, try to convert it and send the reply.
if (last_frame_.get())
SendGetFrameReply();
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) {
Close();
return PP_OK;
}
void PepperVideoSourceHost::SendGetFrameReply() {
DCHECK(get_frame_pending_);
get_frame_pending_ = false;
DCHECK(last_frame_.get());
const gfx::Size dst_size = last_frame_->natural_size();
// Note: We try to reuse the shared memory for the previous frame here. This
// means that the previous frame may be overwritten and is no longer valid
// after calling this function again.
base::SharedMemoryHandle image_handle;
uint32_t byte_count;
if (shared_image_.get() && dst_size.width() == shared_image_->width() &&
dst_size.height() == shared_image_->height()) {
// We have already allocated the correct size in shared memory. We need to
// duplicate the handle for IPC however, which will close down the
// duplicated handle when it's done.
base::SharedMemory* local_shm;
if (shared_image_->GetSharedMemory(&local_shm, &byte_count) != PP_OK) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
ppapi::proxy::HostDispatcher* dispatcher =
ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
if (!dispatcher) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
image_handle =
dispatcher->ShareSharedMemoryHandleWithRemote(local_shm->handle());
} else {
// We need to allocate new shared memory.
shared_image_ = nullptr; // Release any previous image.
ppapi::ScopedPPResource resource(
ppapi::ScopedPPResource::PassRef(),
ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
pp_instance(),
ppapi::PPB_ImageData_Shared::SIMPLE,
PP_IMAGEDATAFORMAT_BGRA_PREMUL,
PP_MakeSize(dst_size.width(), dst_size.height()),
false /* init_to_zero */,
&shared_image_desc_,
&image_handle,
&byte_count));
if (!resource) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
enter_resource(resource, false);
if (enter_resource.failed()) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
shared_image_ = static_cast<PPB_ImageData_Impl*>(enter_resource.object());
if (!shared_image_.get()) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
DCHECK(!shared_image_->IsMapped()); // New memory should not be mapped.
if (!shared_image_->Map() || shared_image_->GetMappedBitmap().empty()) {
shared_image_ = nullptr;
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
}
SkBitmap bitmap(shared_image_->GetMappedBitmap());
if (bitmap.empty()) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap.getPixels());
if (!bitmap_pixels) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
// Calculate the portion of the |last_frame_| that should be copied into
// |bitmap|. If |last_frame_| is lazily scaled, then
// last_frame_->visible_rect()._size() != last_frame_.natural_size().
scoped_refptr<media::VideoFrame> frame;
if (dst_size == last_frame_->visible_rect().size()) {
// No scaling is needed, convert directly from last_frame_.
frame = last_frame_;
// Frame resolution doesn't change frequently, so don't keep any unnecessary
// buffers around.
scaled_frame_ = nullptr;
} else {
// We need to create an intermediate scaled frame. Make sure we have
// allocated one of correct size.
if (!scaled_frame_.get() || scaled_frame_->coded_size() != dst_size) {
scaled_frame_ = media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_I420, dst_size, gfx::Rect(dst_size), dst_size,
last_frame_->timestamp());
if (!scaled_frame_.get()) {
LOG(ERROR) << "Failed to allocate a media::VideoFrame";
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
}
scaled_frame_->set_timestamp(last_frame_->timestamp());
libyuv::I420Scale(last_frame_->visible_data(media::VideoFrame::kYPlane),
last_frame_->stride(media::VideoFrame::kYPlane),
last_frame_->visible_data(media::VideoFrame::kUPlane),
last_frame_->stride(media::VideoFrame::kUPlane),
last_frame_->visible_data(media::VideoFrame::kVPlane),
last_frame_->stride(media::VideoFrame::kVPlane),
last_frame_->visible_rect().width(),
last_frame_->visible_rect().height(),
scaled_frame_->data(media::VideoFrame::kYPlane),
scaled_frame_->stride(media::VideoFrame::kYPlane),
scaled_frame_->data(media::VideoFrame::kUPlane),
scaled_frame_->stride(media::VideoFrame::kUPlane),
scaled_frame_->data(media::VideoFrame::kVPlane),
scaled_frame_->stride(media::VideoFrame::kVPlane),
dst_size.width(),
dst_size.height(),
libyuv::kFilterBilinear);
frame = scaled_frame_;
}
last_frame_ = nullptr;
libyuv::I420ToARGB(frame->visible_data(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kYPlane),
frame->visible_data(media::VideoFrame::kUPlane),
frame->stride(media::VideoFrame::kUPlane),
frame->visible_data(media::VideoFrame::kVPlane),
frame->stride(media::VideoFrame::kVPlane),
bitmap_pixels,
bitmap.rowBytes(),
dst_size.width(),
dst_size.height());
ppapi::HostResource host_resource;
host_resource.SetHostResource(pp_instance(), shared_image_->GetReference());
// Convert a video timestamp to a PP_TimeTicks (a double, in seconds).
const PP_TimeTicks timestamp = frame->timestamp().InSecondsF();
ppapi::proxy::SerializedHandle serialized_handle;
serialized_handle.set_shmem(image_handle, byte_count);
reply_context_.params.AppendHandle(std::move(serialized_handle));
host()->SendReply(reply_context_,
PpapiPluginMsg_VideoSource_GetFrameReply(
host_resource, shared_image_desc_, timestamp));
reply_context_ = ppapi::host::ReplyMessageContext();
}
void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) {
reply_context_.params.set_result(error);
host()->SendReply(
reply_context_,
PpapiPluginMsg_VideoSource_GetFrameReply(
ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */));
reply_context_ = ppapi::host::ReplyMessageContext();
}
void PepperVideoSourceHost::Close() {
if (frame_source_.get() && !stream_url_.empty())
frame_source_->Close(frame_receiver_.get());
frame_source_.reset(nullptr);
stream_url_.clear();
shared_image_ = nullptr;
}
} // namespace content

@ -1,90 +0,0 @@
// 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.
#ifndef CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
#include <stdint.h>
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/c/ppb_image_data.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
struct PP_ImageDataDesc;
namespace media {
class VideoFrame;
} // namespace media
namespace content {
class PPB_ImageData_Impl;
class RendererPpapiHost;
class VideoTrackToPepperAdapter;
class CONTENT_EXPORT PepperVideoSourceHost : public ppapi::host::ResourceHost {
public:
PepperVideoSourceHost(RendererPpapiHost* host,
PP_Instance instance,
PP_Resource resource);
~PepperVideoSourceHost() override;
int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) override;
private:
// Helper object to receive frames on a video worker thread and pass them on
// to us.
class FrameReceiver;
int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
const std::string& stream_url);
int32_t OnHostMsgGetFrame(ppapi::host::HostMessageContext* context);
int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
// Sends the reply to a GetFrame message from the plugin. A reply is always
// sent and last_frame_, reply_context_, and get_frame_pending_ are all reset.
void SendGetFrameReply();
// Sends the reply to a GetFrame message from the plugin in case of an error.
void SendGetFrameErrorReply(int32_t error);
void Close();
ppapi::host::ReplyMessageContext reply_context_;
std::unique_ptr<VideoTrackToPepperAdapter> frame_source_;
scoped_refptr<FrameReceiver> frame_receiver_;
std::string stream_url_;
scoped_refptr<media::VideoFrame> last_frame_;
// An internal frame buffer to avoid reallocations. It is only allocated if
// scaling is needed.
scoped_refptr<media::VideoFrame> scaled_frame_;
bool get_frame_pending_;
// We use only one ImageData resource in order to avoid allocating
// shared memory repeatedly. We send the same one each time the plugin
// requests a frame. For this to work, the plugin must finish using
// the ImageData it receives prior to calling GetFrame, and not access
// the ImageData until it gets its next callback to GetFrame.
scoped_refptr<PPB_ImageData_Impl> shared_image_;
PP_ImageDataDesc shared_image_desc_;
base::WeakPtrFactory<PepperVideoSourceHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperVideoSourceHost);
};
} // namespace content
#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_

@ -127,8 +127,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/trusted/ppb_broker_trusted.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"

@ -331,18 +331,10 @@ PP_Resource ResourceCreationImpl::CreateVideoDecoderDev(
return PPB_VideoDecoder_Impl::Create(instance, graphics3d_id, profile);
}
PP_Resource ResourceCreationImpl::CreateVideoDestination(PP_Instance instance) {
return 0; // Not supported in-process.
}
PP_Resource ResourceCreationImpl::CreateVideoEncoder(PP_Instance instance) {
return 0; // Not supported in-process.
}
PP_Resource ResourceCreationImpl::CreateVideoSource(PP_Instance instance) {
return 0; // Not supported in-process.
}
PP_Resource ResourceCreationImpl::CreateVpnProvider(PP_Instance instance) {
return 0; // Not supported in-process.
}

@ -128,9 +128,7 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI {
PP_Resource CreateVideoDecoderDev(PP_Instance instance,
PP_Resource graphics3d_id,
PP_VideoDecoder_Profile profile) override;
PP_Resource CreateVideoDestination(PP_Instance instance) override;
PP_Resource CreateVideoEncoder(PP_Instance instance) override;
PP_Resource CreateVideoSource(PP_Instance instance) override;
PP_Resource CreateVpnProvider(PP_Instance instance) override;
PP_Resource CreateWheelInputEvent(PP_Instance instance,
PP_TimeTicks time_stamp,

@ -1980,8 +1980,6 @@ test("content_unittests") {
"../browser/renderer_host/pepper/pepper_printing_host_unittest.cc",
"../browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc",
"../browser/renderer_host/pepper/quota_reservation_unittest.cc",
"../renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc",
"../renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc",
"../renderer/pepper/event_conversion_unittest.cc",
"../renderer/pepper/host_var_tracker_unittest.cc",
"../renderer/pepper/mock_resource.h",

@ -131,12 +131,8 @@ test_common_source_files = [
"tests/test_var_resource.h",
"tests/test_video_decoder.cc",
"tests/test_video_decoder.h",
"tests/test_video_destination.cc",
"tests/test_video_destination.h",
"tests/test_video_encoder.cc",
"tests/test_video_encoder.h",
"tests/test_video_source.cc",
"tests/test_video_source.h",
"tests/test_view.cc",
"tests/test_view.h",
"tests/test_websocket.cc",

@ -1,95 +0,0 @@
/* 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.
*/
/**
* This file defines the <code>PPB_VideoDestination_Private</code> interface
* for a video destination resource, which sends video frames to a MediaStream
* video track in the browser.
*/
label Chrome {
M28 = 0.1
};
/**
* The <code>PPB_VideoDestination_Private</code> interface contains pointers to
* several functions for creating video destination resources and using them to
* send video frames to a MediaStream video track in the browser.
*/
interface PPB_VideoDestination_Private {
/**
* Creates a video destination resource.
*
* @param[in] instance A <code>PP_Instance</code> identifying an instance of
* a module.
*
* @return A <code>PP_Resource</code> with a nonzero ID on success or zero on
* failure. Failure means the instance was invalid.
*/
PP_Resource Create([in] PP_Instance instance);
/**
* Determines if a resource is a video destination resource.
*
* @param[in] resource The <code>PP_Resource</code> to test.
*
* @return A <code>PP_Bool</code> with <code>PP_TRUE</code> if the given
* resource is a video destination resource or <code>PP_FALSE</code>
* otherwise.
*/
PP_Bool IsVideoDestination([in] PP_Resource resource);
/**
* Opens a video destination for putting frames.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination resource.
* @param[in] stream_url A <code>PP_Var</code> string holding a URL
* identifying a MediaStream.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of Open().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
* destination.
* Returns PP_ERROR_INPROGRESS if destination is already open.
* Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
* some other browser error.
*/
int32_t Open([in] PP_Resource destination,
[in] PP_Var stream_url,
[in] PP_CompletionCallback callback);
/**
* Puts a frame to the video destination.
*
* After this call, you should take care to release your references to the
* image embedded in the video frame. If you paint to the image after
* PutFame(), there is the possibility of artifacts because the browser may
* still be copying the frame to the stream.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination resource.
* @param[in] frame A <code>PP_VideoFrame_Private</code> holding the video
* frame to send to the destination.
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
* destination.
* Returns PP_ERROR_FAILED if destination is not open, if the video frame has
* an invalid image data resource, or if some other browser error occurs.
*/
int32_t PutFrame([in] PP_Resource destination,
[in] PP_VideoFrame_Private frame);
/**
* Closes the video destination.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination.
*/
void Close([in] PP_Resource destination);
};

@ -1,93 +0,0 @@
/* 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.
*/
/**
* This file defines the <code>PPB_VideoSource_Private</code> interface for a
* video source resource, which receives video frames from a MediaStream video
* track in the browser.
*/
label Chrome {
M28 = 0.1
};
/**
* The <code>PPB_VideoSource_Private</code> interface contains pointers to
* several functions for creating video source resources and using them to
* receive video frames from a MediaStream video track in the browser.
*/
interface PPB_VideoSource_Private {
/**
* Creates a video source resource.
*
* @param[in] instance A <code>PP_Instance</code> identifying an instance of
* a module.
*
* @return A <code>PP_Resource</code> with a nonzero ID on success or zero on
* failure. Failure means the instance was invalid.
*/
PP_Resource Create([in] PP_Instance instance);
/**
* Determines if a resource is a video source resource.
*
* @param[in] resource The <code>PP_Resource</code> to test.
*
* @return A <code>PP_Bool</code> with <code>PP_TRUE</code> if the given
* resource is a video source resource or <code>PP_FALSE</code> otherwise.
*/
PP_Bool IsVideoSource([in] PP_Resource resource);
/**
* Opens a video source for getting frames.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
* @param[in] stream_url A <code>PP_Var</code> string holding a URL
* identifying a MediaStream.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of Open().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
* Returns PP_ERROR_INPROGRESS if source is already open.
* Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
* some other browser error.
*/
int32_t Open([in] PP_Resource source,
[in] PP_Var stream_url,
[in] PP_CompletionCallback callback);
/**
* Gets a frame from the video source. The returned image data is only valid
* until the next call to GetFrame.
* The image data resource inside the returned frame will have its reference
* count incremented by one and must be managed by the plugin.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
* @param[out] frame A <code>PP_VideoFrame_Private</code> to hold a video
* frame from the source.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of GetNextFrame().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
* Returns PP_ERROR_FAILED if the source is not open, or if some other
* browser error occurs.
*/
int32_t GetFrame([in] PP_Resource source,
[out] PP_VideoFrame_Private frame,
[in] PP_CompletionCallback callback);
/**
* Closes the video source.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
*/
void Close([in] PP_Resource source);
};

@ -143,8 +143,6 @@ source_set("c") {
"private/ppb_testing_private.h",
"private/ppb_udp_socket_private.h",
"private/ppb_uma_private.h",
"private/ppb_video_destination_private.h",
"private/ppb_video_source_private.h",
"private/ppb_x509_certificate_private.h",
"private/ppp_find_private.h",
"private/ppp_flash_browser_operations.h",

@ -1,122 +0,0 @@
/* 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.
*/
/* From private/ppb_video_destination_private.idl,
* modified Thu Apr 25 11:51:30 2013.
*/
#ifndef PPAPI_C_PRIVATE_PPB_VIDEO_DESTINATION_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_VIDEO_DESTINATION_PRIVATE_H_
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#define PPB_VIDEODESTINATION_PRIVATE_INTERFACE_0_1 \
"PPB_VideoDestination_Private;0.1"
#define PPB_VIDEODESTINATION_PRIVATE_INTERFACE \
PPB_VIDEODESTINATION_PRIVATE_INTERFACE_0_1
/**
* @file
* This file defines the <code>PPB_VideoDestination_Private</code> interface
* for a video destination resource, which sends video frames to a MediaStream
* video track in the browser.
*/
/**
* @addtogroup Interfaces
* @{
*/
/**
* The <code>PPB_VideoDestination_Private</code> interface contains pointers to
* several functions for creating video destination resources and using them to
* send video frames to a MediaStream video track in the browser.
*/
struct PPB_VideoDestination_Private_0_1 {
/**
* Creates a video destination resource.
*
* @param[in] instance A <code>PP_Instance</code> identifying an instance of
* a module.
*
* @return A <code>PP_Resource</code> with a nonzero ID on success or zero on
* failure. Failure means the instance was invalid.
*/
PP_Resource (*Create)(PP_Instance instance);
/**
* Determines if a resource is a video destination resource.
*
* @param[in] resource The <code>PP_Resource</code> to test.
*
* @return A <code>PP_Bool</code> with <code>PP_TRUE</code> if the given
* resource is a video destination resource or <code>PP_FALSE</code>
* otherwise.
*/
PP_Bool (*IsVideoDestination)(PP_Resource resource);
/**
* Opens a video destination for putting frames.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination resource.
* @param[in] stream_url A <code>PP_Var</code> string holding a URL
* identifying a MediaStream.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of Open().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
* destination.
* Returns PP_ERROR_INPROGRESS if destination is already open.
* Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
* some other browser error.
*/
int32_t (*Open)(PP_Resource destination,
struct PP_Var stream_url,
struct PP_CompletionCallback callback);
/**
* Puts a frame to the video destination.
*
* After this call, you should take care to release your references to the
* image embedded in the video frame. If you paint to the image after
* PutFame(), there is the possibility of artifacts because the browser may
* still be copying the frame to the stream.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination resource.
* @param[in] frame A <code>PP_VideoFrame_Private</code> holding the video
* frame to send to the destination.
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
* destination.
* Returns PP_ERROR_FAILED if destination is not open, if the video frame has
* an invalid image data resource, or if some other browser error occurs.
*/
int32_t (*PutFrame)(PP_Resource destination,
const struct PP_VideoFrame_Private* frame);
/**
* Closes the video destination.
*
* @param[in] destination A <code>PP_Resource</code> corresponding to a video
* destination.
*/
void (*Close)(PP_Resource destination);
};
typedef struct PPB_VideoDestination_Private_0_1 PPB_VideoDestination_Private;
/**
* @}
*/
#endif /* PPAPI_C_PRIVATE_PPB_VIDEO_DESTINATION_PRIVATE_H_ */

@ -1,118 +0,0 @@
/* 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.
*/
/* From private/ppb_video_source_private.idl,
* modified Mon Oct 27 16:13:24 2014.
*/
#ifndef PPAPI_C_PRIVATE_PPB_VIDEO_SOURCE_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_VIDEO_SOURCE_PRIVATE_H_
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#define PPB_VIDEOSOURCE_PRIVATE_INTERFACE_0_1 "PPB_VideoSource_Private;0.1"
#define PPB_VIDEOSOURCE_PRIVATE_INTERFACE PPB_VIDEOSOURCE_PRIVATE_INTERFACE_0_1
/**
* @file
* This file defines the <code>PPB_VideoSource_Private</code> interface for a
* video source resource, which receives video frames from a MediaStream video
* track in the browser.
*/
/**
* @addtogroup Interfaces
* @{
*/
/**
* The <code>PPB_VideoSource_Private</code> interface contains pointers to
* several functions for creating video source resources and using them to
* receive video frames from a MediaStream video track in the browser.
*/
struct PPB_VideoSource_Private_0_1 {
/**
* Creates a video source resource.
*
* @param[in] instance A <code>PP_Instance</code> identifying an instance of
* a module.
*
* @return A <code>PP_Resource</code> with a nonzero ID on success or zero on
* failure. Failure means the instance was invalid.
*/
PP_Resource (*Create)(PP_Instance instance);
/**
* Determines if a resource is a video source resource.
*
* @param[in] resource The <code>PP_Resource</code> to test.
*
* @return A <code>PP_Bool</code> with <code>PP_TRUE</code> if the given
* resource is a video source resource or <code>PP_FALSE</code> otherwise.
*/
PP_Bool (*IsVideoSource)(PP_Resource resource);
/**
* Opens a video source for getting frames.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
* @param[in] stream_url A <code>PP_Var</code> string holding a URL
* identifying a MediaStream.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of Open().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
* Returns PP_ERROR_INPROGRESS if source is already open.
* Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
* some other browser error.
*/
int32_t (*Open)(PP_Resource source,
struct PP_Var stream_url,
struct PP_CompletionCallback callback);
/**
* Gets a frame from the video source. The returned image data is only valid
* until the next call to GetFrame.
* The image data resource inside the returned frame will have its reference
* count incremented by one and must be managed by the plugin.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
* @param[out] frame A <code>PP_VideoFrame_Private</code> to hold a video
* frame from the source.
* @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
* completion of GetNextFrame().
*
* @return An int32_t containing a result code from <code>pp_errors.h</code>.
* Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
* Returns PP_ERROR_FAILED if the source is not open, or if some other
* browser error occurs.
*/
int32_t (*GetFrame)(PP_Resource source,
struct PP_VideoFrame_Private* frame,
struct PP_CompletionCallback callback);
/**
* Closes the video source.
*
* @param[in] source A <code>PP_Resource</code> corresponding to a video
* source resource.
*/
void (*Close)(PP_Resource source);
};
typedef struct PPB_VideoSource_Private_0_1 PPB_VideoSource_Private;
/**
* @}
*/
#endif /* PPAPI_C_PRIVATE_PPB_VIDEO_SOURCE_PRIVATE_H_ */

@ -250,12 +250,8 @@ source_set("objects") {
"private/uma_private.h",
"private/var_private.cc",
"private/var_private.h",
"private/video_destination_private.cc",
"private/video_destination_private.h",
"private/video_frame_private.cc",
"private/video_frame_private.h",
"private/video_source_private.cc",
"private/video_source_private.h",
"private/x509_certificate_private.cc",
"private/x509_certificate_private.h",

@ -1,76 +0,0 @@
// 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 "ppapi/cpp/private/video_destination_private.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/var.h"
namespace pp {
namespace {
template <> const char* interface_name<PPB_VideoDestination_Private_0_1>() {
return PPB_VIDEODESTINATION_PRIVATE_INTERFACE_0_1;
}
} // namespace
VideoDestination_Private::VideoDestination_Private() {
}
VideoDestination_Private::VideoDestination_Private(
const InstanceHandle& instance) {
if (!has_interface<PPB_VideoDestination_Private_0_1>())
return;
PassRefFromConstructor(
get_interface<PPB_VideoDestination_Private_0_1>()->Create(
instance.pp_instance()));
}
VideoDestination_Private::VideoDestination_Private(
const VideoDestination_Private& other)
: Resource(other) {
}
VideoDestination_Private::VideoDestination_Private(PassRef,
PP_Resource resource)
: Resource(PASS_REF, resource) {
}
int32_t VideoDestination_Private::Open(const Var& stream_url,
const CompletionCallback& cc) {
if (has_interface<PPB_VideoDestination_Private_0_1>()) {
int32_t result =
get_interface<PPB_VideoDestination_Private_0_1>()->Open(
pp_resource(),
stream_url.pp_var(),
cc.pp_completion_callback());
return result;
}
return cc.MayForce(PP_ERROR_NOINTERFACE);
}
int32_t VideoDestination_Private::PutFrame(
const VideoFrame_Private& frame) {
if (has_interface<PPB_VideoDestination_Private_0_1>()) {
return get_interface<PPB_VideoDestination_Private_0_1>()->PutFrame(
pp_resource(),
&frame.pp_video_frame());
}
return PP_ERROR_NOINTERFACE;
}
void VideoDestination_Private::Close() {
if (has_interface<PPB_VideoDestination_Private_0_1>()) {
get_interface<PPB_VideoDestination_Private_0_1>()->Close(pp_resource());
}
}
} // namespace pp

@ -1,89 +0,0 @@
// 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.
#ifndef PPAPI_CPP_PRIVATE_VIDEO_DESTINATION_PRIVATE_H_
#define PPAPI_CPP_PRIVATE_VIDEO_DESTINATION_PRIVATE_H_
#include <stdint.h>
#include <string>
#include "ppapi/c/pp_time.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/resource.h"
/// @file
/// This file defines the <code>PPB_VideoDestination_Private</code> interface
/// for a video destination resource, which sends video frames to a MediaStream
/// video track in the browser.
namespace pp {
class InstanceHandle;
class VideoFrame_Private;
/// The <code>VideoDestination_Private</code> class contains methods for
/// creating video destination resources and using them to send video frames to
/// a MediaStream video track in the browser.
class VideoDestination_Private : public Resource {
public:
/// Default constructor for creating a <code>VideoDestination_Private</code>
/// object.
VideoDestination_Private();
/// Constructor for creating a <code>VideoDestination_Private</code> for an
/// instance.
explicit VideoDestination_Private(const InstanceHandle& instance);
/// The copy constructor for <code>VideoDestination_Private</code>.
///
/// @param[in] other A reference to a <code>VideoDestination_Private</code>.
VideoDestination_Private(const VideoDestination_Private& other);
/// A constructor used when you have received a PP_Resource as a return
/// value that has had its reference count incremented for you.
///
/// @param[in] resource A PP_Resource corresponding to a video destination.
VideoDestination_Private(PassRef, PP_Resource resource);
/// Opens a video destination for putting frames.
///
/// @param[in] stream_url A <code>Var</code> string holding a URL identifying
/// a MediaStream.
/// @param[in] callback A <code>CompletionCallback</code> to be
/// called upon completion of Open().
///
/// @return An int32_t containing a result code from <code>pp_errors.h</code>.
/// Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
/// destination.
/// Returns PP_ERROR_INPROGRESS if destination is already open.
/// Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
/// some other browser error.
int32_t Open(const Var& stream_url, const CompletionCallback& cc);
/// Puts a frame to the video destination.
///
/// After this call, you should take care to release your references to the
/// image embedded in the video frame. If you paint to the image after
/// PutFrame(), there is the possibility of artifacts because the browser may
/// still be copying the frame to the stream.
///
/// @param[in] frame A <code>VideoFrame_Private</code> holding the video
/// frame to send to the destination.
///
/// @return An int32_t containing a result code from <code>pp_errors.h</code>.
/// Returns PP_ERROR_BADRESOURCE if destination isn't a valid video
/// destination.
/// Returns PP_ERROR_FAILED if destination is not open, if the video frame has
/// an invalid image data resource, or if some other browser error occurs.
int32_t PutFrame(const VideoFrame_Private& frame);
/// Closes the video destination.
void Close();
};
} // namespace pp
#endif // PPAPI_CPP_PRIVATE_VIDEO_DESTINATION_PRIVATE_H_

@ -1,71 +0,0 @@
// 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 "ppapi/cpp/private/video_source_private.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/var.h"
namespace pp {
namespace {
template <> const char* interface_name<PPB_VideoSource_Private_0_1>() {
return PPB_VIDEOSOURCE_PRIVATE_INTERFACE_0_1;
}
} // namespace
VideoSource_Private::VideoSource_Private() {
}
VideoSource_Private::VideoSource_Private(const InstanceHandle& instance) {
if (!has_interface<PPB_VideoSource_Private_0_1>())
return;
PassRefFromConstructor(get_interface<PPB_VideoSource_Private_0_1>()->Create(
instance.pp_instance()));
}
VideoSource_Private::VideoSource_Private(const VideoSource_Private& other)
: Resource(other) {
}
VideoSource_Private::VideoSource_Private(PassRef, PP_Resource resource)
: Resource(PASS_REF, resource) {
}
int32_t VideoSource_Private::Open(const Var& stream_url,
const CompletionCallback& cc) {
if (has_interface<PPB_VideoSource_Private_0_1>()) {
int32_t result =
get_interface<PPB_VideoSource_Private_0_1>()->Open(
pp_resource(),
stream_url.pp_var(), cc.pp_completion_callback());
return result;
}
return cc.MayForce(PP_ERROR_NOINTERFACE);
}
int32_t VideoSource_Private::GetFrame(
const CompletionCallbackWithOutput<VideoFrame_Private>& cc) {
if (has_interface<PPB_VideoSource_Private_0_1>()) {
return get_interface<PPB_VideoSource_Private_0_1>()->GetFrame(
pp_resource(),
cc.output(), cc.pp_completion_callback());
}
return cc.MayForce(PP_ERROR_NOINTERFACE);
}
void VideoSource_Private::Close() {
if (has_interface<PPB_VideoSource_Private_0_1>()) {
get_interface<PPB_VideoSource_Private_0_1>()->Close(pp_resource());
}
}
} // namespace pp

@ -1,87 +0,0 @@
// 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.
#ifndef PPAPI_CPP_PRIVATE_VIDEO_SOURCE_PRIVATE_H_
#define PPAPI_CPP_PRIVATE_VIDEO_SOURCE_PRIVATE_H_
#include <stdint.h>
#include <string>
#include "ppapi/c/pp_time.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/resource.h"
/// @file
/// This file defines the <code>PPB_VideoSource_Private</code> interface for a
/// video source resource, which receives video frames from a MediaStream video
/// track in the browser.
namespace pp {
class InstanceHandle;
class VideoFrame_Private;
/// The <code>VideoSource_Private</code> class contains methods for creating
/// video source resources and using them to receive video frames from a
/// MediaStream video track in the browser.
class VideoSource_Private : public Resource {
public:
/// Default constructor for creating a <code>VideoSource_Private</code>
/// object.
VideoSource_Private();
/// Constructor for creating a <code>VideoSource_Private</code> for an
/// instance.
explicit VideoSource_Private(const InstanceHandle& instance);
/// The copy constructor for <code>VideoSource_Private</code>.
///
/// @param[in] other A reference to a <code>VideoSource_Private</code>.
VideoSource_Private(const VideoSource_Private& other);
/// A constructor used when you have received a PP_Resource as a return
/// value that has had its reference count incremented for you.
///
/// @param[in] resource A PP_Resource corresponding to a video source.
VideoSource_Private(PassRef, PP_Resource resource);
/// Opens a video source for getting frames.
///
/// @param[in] stream_url A <code>Var</code> string holding a URL identifying
/// a MediaStream.
/// @param[in] callback A <code>CompletionCallback</code> to be called upon
/// completion of Open().
///
/// @return An int32_t containing a result code from <code>pp_errors.h</code>.
/// Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
/// Returns PP_ERROR_INPROGRESS if source is already open.
/// Returns PP_ERROR_FAILED if the MediaStream doesn't exist or if there is
/// some other browser error.
int32_t Open(const Var& stream_url,
const CompletionCallback& cc);
/// Gets a frame from the video source. The returned frame is only valid
/// until the next call to GetFrame.
///
/// @param[out] frame A <code>VideoFrame_Private</code> to hold a video
/// frame from the source.
/// @param[in] callback A <code>CompletionCallbackWithOutput</code> to be
/// called upon completion of ReceiveFrame().
///
/// @return An int32_t containing a result code from <code>pp_errors.h</code>.
/// Returns PP_ERROR_BADRESOURCE if source isn't a valid video source.
/// Returns PP_ERROR_FAILED if the source is not open, or if some other
/// browser error occurs.
int32_t GetFrame(
const CompletionCallbackWithOutput<VideoFrame_Private>& cc);
/// Closes the video source.
void Close();
};
} // namespace pp
#endif // PPAPI_CPP_PRIVATE_VIDEO_SOURCE_PRIVATE_H_

@ -32,7 +32,6 @@ group("examples") {
"//ppapi/examples/url_loader",
"//ppapi/examples/video_capture",
"//ppapi/examples/video_decode",
"//ppapi/examples/video_effects",
"//ppapi/examples/video_encode",
]
}

@ -1,15 +0,0 @@
# Copyright 2015 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.
import("//ppapi/examples/ppapi_example.gni")
ppapi_example("video_effects") {
output_name = "video_effects"
sources = [
"video_effects.cc",
]
deps = [
"//ppapi/cpp",
]
}

@ -1,180 +0,0 @@
// 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 <stdint.h>
#include <string.h>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/message_loop.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/private/video_destination_private.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/private/video_source_private.h"
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"
// When compiling natively on Windows, PostMessage can be #define-d to
// something else.
#ifdef PostMessage
#undef PostMessage
#endif
namespace {
// Helper functions
std::vector<std::string> SplitStringBySpace(const std::string& str) {
std::istringstream buf(str);
std::istream_iterator<std::string> begin(buf), end;
std::vector<std::string> tokens(begin, end);
return tokens;
}
// This object is the global object representing this plugin library as long
// as it is loaded.
class VEDemoModule : public pp::Module {
public:
VEDemoModule() : pp::Module() {}
virtual ~VEDemoModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance);
};
class VEDemoInstance : public pp::Instance {
public:
VEDemoInstance(PP_Instance instance, pp::Module* module);
virtual ~VEDemoInstance();
// pp::Instance implementation (see PPP_Instance).
virtual void HandleMessage(const pp::Var& message_data);
private:
void DestinationOpenDone(int32_t result, const std::string& src_url);
void SourceOpenDone(int32_t result);
void GetFrameDone(int32_t result, pp::VideoFrame_Private video_frame);
void KickoffEffect(int32_t result);
pp::VideoSource_Private video_source_;
pp::VideoDestination_Private video_destination_;
bool effect_on_;
pp::CompletionCallbackFactory<VEDemoInstance> factory_;
pp::MessageLoop message_loop_;
};
VEDemoInstance::VEDemoInstance(PP_Instance instance, pp::Module* module)
: pp::Instance(instance),
video_source_(this),
video_destination_(this),
effect_on_(false),
message_loop_(pp::MessageLoop::GetCurrent()) {
factory_.Initialize(this);
}
VEDemoInstance::~VEDemoInstance() {
video_source_.Close();
video_destination_.Close();
}
void VEDemoInstance::HandleMessage(const pp::Var& message_data) {
if (message_data.is_string()) {
std::vector<std::string> messages;
messages = SplitStringBySpace(message_data.AsString());
if (messages.empty()) {
PostMessage(pp::Var("Ignored empty message."));
return;
}
if (messages[0] == "registerStream") {
if (messages.size() < 3) {
PostMessage(pp::Var("Got 'registerStream' with incorrect parameters."));
return;
}
// Open destination stream for write.
video_destination_.Open(
messages[2],
factory_.NewCallback(&VEDemoInstance::DestinationOpenDone,
messages[1]));
} else if (messages[0] == "effectOn") {
effect_on_ = true;
PostMessage(pp::Var("Effect ON."));
} else if (messages[0] == "effectOff") {
effect_on_ = false;
PostMessage(pp::Var("Effect OFF."));
}
}
}
void VEDemoInstance::DestinationOpenDone(int32_t result,
const std::string& src_url) {
if (result != PP_OK) {
PostMessage(pp::Var("Failed to open destination stream."));
return;
}
// Open source stream for read.
video_source_.Open(src_url,
factory_.NewCallback(&VEDemoInstance::SourceOpenDone));
}
void VEDemoInstance::SourceOpenDone(int32_t result) {
if (result != PP_OK) {
PostMessage(pp::Var("Failed to open source stream."));
return;
}
// Done with the stream register.
PostMessage(pp::Var("DoneRegistering"));
// Kick off the processing loop.
message_loop_.PostWork(factory_.NewCallback(&VEDemoInstance::KickoffEffect));
}
void VEDemoInstance::GetFrameDone(int32_t result,
pp::VideoFrame_Private video_frame) {
if (result != PP_OK) {
PostMessage(pp::Var("Failed to get frame."));
return;
}
// Apply the effect to the received frame.
if (effect_on_) {
pp::ImageData image_data = video_frame.image_data();
pp::Size size = image_data.size();
std::vector<uint8_t> tmp_row(image_data.stride());
uint8_t* image = static_cast<uint8_t*>(image_data.data());
for (int i = 0; i < size.height() / 2; ++i) {
uint8_t* top = image + i * image_data.stride();
uint8_t* bottom = image + (size.height() - 1 - i) * image_data.stride();
memcpy(&tmp_row[0], top, image_data.stride());
memcpy(top, bottom, image_data.stride());
memcpy(bottom, &tmp_row[0], image_data.stride());
}
}
// Put frame back to destination stream
video_destination_.PutFrame(video_frame);
// Trigger for the next frame.
message_loop_.PostWork(factory_.NewCallback(&VEDemoInstance::KickoffEffect));
}
void VEDemoInstance::KickoffEffect(int32_t /* result */) {
// Get the frame from the source stream.
video_source_.GetFrame(
factory_.NewCallbackWithOutput<pp::VideoFrame_Private>(
&VEDemoInstance::GetFrameDone));
}
pp::Instance* VEDemoModule::CreateInstance(PP_Instance instance) {
return new VEDemoInstance(instance, this);
}
} // anonymous namespace
namespace pp {
// Factory function for your specialization of the Module object.
Module* CreateModule() {
return new VEDemoModule();
}
} // namespace pp

@ -1,205 +0,0 @@
<!DOCTYPE html>
<html>
<!--
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.
-->
<head>
<title>Video Effects Demo</title>
<style>
video {
border:5px solid black;
width:480px;
height:360px;
}
button {
font: 18px sans-serif;
padding: 8px;
}
textarea {
font-family: monospace;
margin: 2px;
width:480px;
height:640px;
}
</style>
</head>
<body>
<table>
<tr>
<td><video id="vidlocal" autoplay></video></td>
<td><video id="vidprocessedlocal" autoplay></video></td>
<td><video id="vidremote" autoplay></video></td>
</tr>
<tr>
<td>Local Media Stream</td>
<td>Local Media Stream After Effect</td>
<td>Remote Media Stream</td>
</tr>
<tr>
</table>
<br>
<button id="startButton" onclick="start()">Start</button>
<button id="toggleEffectButton" onclick="toggleEffect()">Enable Effect</button>
<button id="callButton" onclick="call()">Call</button>
<button id="hangupButton" onclick="hangup()">Hang Up</button>
<br>
<embed id="plugin" type="application/x-ppapi-example-video-effects"
width="320" height="240"/>
<script>
var getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
var attachMediaStream = function(element, stream) {
element.srcObject = stream;
};
var startButton = document.getElementById('startButton');
var toggleEffectButton = document.getElementById('toggleEffectButton');
var callButton = document.getElementById('callButton');
var hangupButton = document.getElementById('hangupButton');
callButton.disabled = true;
hangupButton.disabled = true;
toggleEffectButton.disabled = true;
var pc1 = null;
var pc2 = null;
var localstream = null;
var processedLocalstream = null;
var effectsPlugin = null;
var effectsEnabled = false;
function trace(text) {
// This function is used for logging.
if (text[text.length - 1] == '\n') {
text = text.substring(0, text.length - 1);
}
console.log((performance.now() / 1000).toFixed(3) + ": " + text);
}
function gotStream(stream){
trace("Received local stream");
// Call the polyfill wrapper to attach the media stream to this element.
attachMediaStream(vidlocal, stream);
localstream = stream;
callButton.disabled = false;
initEffect();
}
function start() {
trace("Requesting local stream");
startButton.disabled = true;
// Call into getUserMedia via the polyfill (adapter.js).
getUserMedia({audio:false, video:true},
gotStream, function() {});
}
function onRegisterStreamDone() {
vidprocessedlocal.srcObject = processedLocalstream;
toggleEffectButton.disabled = false;
}
function HandleMessage(message_event) {
if (message_event.data) {
if (message_event.data == 'DoneRegistering') {
onRegisterStreamDone();
} else {
trace(message_event.data);
}
}
}
function initEffect() {
var url = URL.createObjectURL(localstream);
processedLocalstream = new MediaStream([]);
var processedStreamUrl = URL.createObjectURL(processedLocalstream);
effectsPlugin.postMessage(
'registerStream' + ' ' + url + ' ' + processedStreamUrl);
}
function toggleEffect() {
effectsEnabled = !effectsEnabled;
if (effectsEnabled) {
toggleEffectButton.innerHTML = 'Disable Effect';
effectsPlugin.postMessage('effectOn');
} else {
toggleEffectButton.innerHTML = 'Enable Effect';
effectsPlugin.postMessage('effectOff');
}
}
function call() {
callButton.disabled = true;
hangupButton.disabled = false;
trace("Starting call");
var servers = null;
pc1 = new RTCPeerConnection(servers);
trace("Created local peer connection object pc1");
pc1.onicecandidate = iceCallback1;
pc2 = new RTCPeerConnection(servers);
trace("Created remote peer connection object pc2");
pc2.onicecandidate = iceCallback2;
pc2.onaddstream = gotRemoteStream;
pc1.addStream(processedLocalstream);
trace("Adding Local Stream to peer connection");
pc1.createOffer(gotDescription1);
}
function gotDescription1(desc){
pc1.setLocalDescription(desc);
trace("Offer from pc1 \n" + desc.sdp);
pc2.setRemoteDescription(desc);
// Since the "remote" side has no media stream we need
// to pass in the right constraints in order for it to
// accept the incoming offer of audio and video.
var sdpConstraints = {'mandatory': {
'OfferToReceiveAudio':true,
'OfferToReceiveVideo':true }};
pc2.createAnswer(gotDescription2, null, sdpConstraints);
}
function gotDescription2(desc){
pc2.setLocalDescription(desc);
trace("Answer from pc2 \n" + desc.sdp);
pc1.setRemoteDescription(desc);
}
function hangup() {
trace("Ending call");
pc1.close();
pc2.close();
pc1 = null;
pc2 = null;
hangupButton.disabled = true;
callButton.disabled = false;
}
function gotRemoteStream(e){
vidremote.srcObject = e.stream;
trace("Received remote stream");
}
function iceCallback1(event){
if (event.candidate) {
pc2.addIceCandidate(new RTCIceCandidate(event.candidate));
trace("Local ICE candidate: \n" + event.candidate.candidate);
}
}
function iceCallback2(event){
if (event.candidate) {
pc1.addIceCandidate(new RTCIceCandidate(event.candidate));
trace("Remote ICE candidate: \n " + event.candidate.candidate);
}
}
function InitializePlugin() {
effectsPlugin = document.getElementById('plugin');
effectsPlugin.addEventListener('message', HandleMessage, false);
}
document.addEventListener('DOMContentLoaded', InitializePlugin, false);
</script>
</body>
</html>

@ -71,8 +71,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/private/ppp_instance_private.h"
@ -195,8 +193,6 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UMA_Private_0_3;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Instance_Private_0_1;
/* END Declarations for all Wrapper Infos. */
@ -4434,64 +4430,6 @@ static int32_t Pnacl_M35_PPB_UMA_Private_IsCrashReportingEnabled(PP_Instance ins
/* End wrapper methods for PPB_UMA_Private_0_3 */
/* Begin wrapper methods for PPB_VideoDestination_Private_0_1 */
static PP_Resource Pnacl_M28_PPB_VideoDestination_Private_Create(PP_Instance instance) {
const struct PPB_VideoDestination_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1.real_iface;
return iface->Create(instance);
}
static PP_Bool Pnacl_M28_PPB_VideoDestination_Private_IsVideoDestination(PP_Resource resource) {
const struct PPB_VideoDestination_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1.real_iface;
return iface->IsVideoDestination(resource);
}
static int32_t Pnacl_M28_PPB_VideoDestination_Private_Open(PP_Resource destination, struct PP_Var* stream_url, struct PP_CompletionCallback* callback) {
const struct PPB_VideoDestination_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1.real_iface;
return iface->Open(destination, *stream_url, *callback);
}
static int32_t Pnacl_M28_PPB_VideoDestination_Private_PutFrame(PP_Resource destination, const struct PP_VideoFrame_Private* frame) {
const struct PPB_VideoDestination_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1.real_iface;
return iface->PutFrame(destination, frame);
}
static void Pnacl_M28_PPB_VideoDestination_Private_Close(PP_Resource destination) {
const struct PPB_VideoDestination_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1.real_iface;
iface->Close(destination);
}
/* End wrapper methods for PPB_VideoDestination_Private_0_1 */
/* Begin wrapper methods for PPB_VideoSource_Private_0_1 */
static PP_Resource Pnacl_M28_PPB_VideoSource_Private_Create(PP_Instance instance) {
const struct PPB_VideoSource_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1.real_iface;
return iface->Create(instance);
}
static PP_Bool Pnacl_M28_PPB_VideoSource_Private_IsVideoSource(PP_Resource resource) {
const struct PPB_VideoSource_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1.real_iface;
return iface->IsVideoSource(resource);
}
static int32_t Pnacl_M28_PPB_VideoSource_Private_Open(PP_Resource source, struct PP_Var* stream_url, struct PP_CompletionCallback* callback) {
const struct PPB_VideoSource_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1.real_iface;
return iface->Open(source, *stream_url, *callback);
}
static int32_t Pnacl_M28_PPB_VideoSource_Private_GetFrame(PP_Resource source, struct PP_VideoFrame_Private* frame, struct PP_CompletionCallback* callback) {
const struct PPB_VideoSource_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1.real_iface;
return iface->GetFrame(source, frame, *callback);
}
static void Pnacl_M28_PPB_VideoSource_Private_Close(PP_Resource source) {
const struct PPB_VideoSource_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1.real_iface;
iface->Close(source);
}
/* End wrapper methods for PPB_VideoSource_Private_0_1 */
/* Begin wrapper methods for PPB_X509Certificate_Private_0_1 */
static PP_Resource Pnacl_M19_PPB_X509Certificate_Private_Create(PP_Instance instance) {
@ -5709,22 +5647,6 @@ static const struct PPB_UMA_Private_0_3 Pnacl_Wrappers_PPB_UMA_Private_0_3 = {
.IsCrashReportingEnabled = (int32_t (*)(PP_Instance instance, struct PP_CompletionCallback callback))&Pnacl_M35_PPB_UMA_Private_IsCrashReportingEnabled
};
static const struct PPB_VideoDestination_Private_0_1 Pnacl_Wrappers_PPB_VideoDestination_Private_0_1 = {
.Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M28_PPB_VideoDestination_Private_Create,
.IsVideoDestination = (PP_Bool (*)(PP_Resource resource))&Pnacl_M28_PPB_VideoDestination_Private_IsVideoDestination,
.Open = (int32_t (*)(PP_Resource destination, struct PP_Var stream_url, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_VideoDestination_Private_Open,
.PutFrame = (int32_t (*)(PP_Resource destination, const struct PP_VideoFrame_Private* frame))&Pnacl_M28_PPB_VideoDestination_Private_PutFrame,
.Close = (void (*)(PP_Resource destination))&Pnacl_M28_PPB_VideoDestination_Private_Close
};
static const struct PPB_VideoSource_Private_0_1 Pnacl_Wrappers_PPB_VideoSource_Private_0_1 = {
.Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M28_PPB_VideoSource_Private_Create,
.IsVideoSource = (PP_Bool (*)(PP_Resource resource))&Pnacl_M28_PPB_VideoSource_Private_IsVideoSource,
.Open = (int32_t (*)(PP_Resource source, struct PP_Var stream_url, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_VideoSource_Private_Open,
.GetFrame = (int32_t (*)(PP_Resource source, struct PP_VideoFrame_Private* frame, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_VideoSource_Private_GetFrame,
.Close = (void (*)(PP_Resource source))&Pnacl_M28_PPB_VideoSource_Private_Close
};
static const struct PPB_X509Certificate_Private_0_1 Pnacl_Wrappers_PPB_X509Certificate_Private_0_1 = {
.Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M19_PPB_X509Certificate_Private_Create,
.IsX509CertificatePrivate = (PP_Bool (*)(PP_Resource resource))&Pnacl_M19_PPB_X509Certificate_Private_IsX509CertificatePrivate,
@ -6376,18 +6298,6 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UMA_Private_0_3 = {
.real_iface = NULL
};
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1 = {
.iface_macro = PPB_VIDEODESTINATION_PRIVATE_INTERFACE_0_1,
.wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_VideoDestination_Private_0_1,
.real_iface = NULL
};
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1 = {
.iface_macro = PPB_VIDEOSOURCE_PRIVATE_INTERFACE_0_1,
.wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_VideoSource_Private_0_1,
.real_iface = NULL
};
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1 = {
.iface_macro = PPB_X509CERTIFICATE_PRIVATE_INTERFACE_0_1,
.wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_X509Certificate_Private_0_1,
@ -6505,8 +6415,6 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3,
&Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4,
&Pnacl_WrapperInfo_PPB_UMA_Private_0_3,
&Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1,
&Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1,
&Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1,
NULL
};

@ -183,14 +183,10 @@ component("proxy") {
"var_serialization_rules.h",
"video_decoder_resource.cc",
"video_decoder_resource.h",
"video_destination_resource.cc",
"video_destination_resource.h",
"video_encoder_resource.cc",
"video_encoder_resource.h",
"video_frame_resource.cc",
"video_frame_resource.h",
"video_source_resource.cc",
"video_source_resource.h",
"vpn_provider_resource.cc",
"vpn_provider_resource.h",
"websocket_resource.cc",

@ -98,8 +98,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/trusted/ppb_broker_trusted.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"

@ -1923,30 +1923,6 @@ IPC_SYNC_MESSAGE_CONTROL2_2(PpapiHostMsg_SharedMemory_CreateSharedMemory,
int /* host_handle_id */,
ppapi::proxy::SerializedHandle /* plugin_handle */)
// MediaStream -----------------------------------------------------------------
// VideoDestination Private.
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoDestination_Create)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_VideoDestination_Open,
std::string /* stream_url */)
IPC_MESSAGE_CONTROL0(PpapiPluginMsg_VideoDestination_OpenReply)
IPC_MESSAGE_CONTROL2(PpapiHostMsg_VideoDestination_PutFrame,
ppapi::HostResource /* image_data */,
PP_TimeTicks /* timestamp */)
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoDestination_Close)
// VideoSource Private.
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoSource_Create)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_VideoSource_Open,
std::string /* stream_url */)
IPC_MESSAGE_CONTROL0(PpapiPluginMsg_VideoSource_OpenReply)
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoSource_GetFrame)
IPC_MESSAGE_CONTROL3(PpapiPluginMsg_VideoSource_GetFrameReply,
ppapi::HostResource /* resource_id */,
PP_ImageDataDesc /* image_data_desc */,
PP_TimeTicks /* timestamp */)
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VideoSource_Close)
// VpnProvider ----------------------------------------------------------------
IPC_MESSAGE_CONTROL0(PpapiHostMsg_VpnProvider_Create)

@ -50,9 +50,7 @@
#include "ppapi/proxy/url_response_info_resource.h"
#include "ppapi/proxy/video_capture_resource.h"
#include "ppapi/proxy/video_decoder_resource.h"
#include "ppapi/proxy/video_destination_resource.h"
#include "ppapi/proxy/video_encoder_resource.h"
#include "ppapi/proxy/video_source_resource.h"
#include "ppapi/proxy/vpn_provider_resource.h"
#include "ppapi/proxy/websocket_resource.h"
#include "ppapi/shared_impl/api_id.h"
@ -388,21 +386,10 @@ PP_Resource ResourceCreationProxy::CreateVideoDecoder(PP_Instance instance) {
return (new VideoDecoderResource(GetConnection(), instance))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateVideoDestination(
PP_Instance instance) {
return (new VideoDestinationResource(GetConnection(),
instance))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateVideoEncoder(PP_Instance instance) {
return (new VideoEncoderResource(GetConnection(), instance))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateVideoSource(
PP_Instance instance) {
return (new VideoSourceResource(GetConnection(), instance))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateVpnProvider(PP_Instance instance) {
return (new VpnProviderResource(GetConnection(), instance))->GetReference();
}

@ -154,9 +154,7 @@ class ResourceCreationProxy : public InterfaceProxy,
PP_Resource CreateUDPSocket(PP_Instance instance) override;
PP_Resource CreateUDPSocketPrivate(PP_Instance instance) override;
PP_Resource CreateVideoDecoder(PP_Instance instance) override;
PP_Resource CreateVideoDestination(PP_Instance instance) override;
PP_Resource CreateVideoEncoder(PP_Instance instance) override;
PP_Resource CreateVideoSource(PP_Instance instance) override;
PP_Resource CreateVpnProvider(PP_Instance instance) override;
PP_Resource CreateWebSocket(PP_Instance instance) override;
PP_Resource CreateX509CertificatePrivate(PP_Instance instance) override;

@ -1,102 +0,0 @@
// 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 "ppapi/proxy/video_destination_resource.h"
#include "base/bind.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_VideoDestination_Private_API;
namespace ppapi {
namespace proxy {
VideoDestinationResource::VideoDestinationResource(
Connection connection,
PP_Instance instance)
: PluginResource(connection, instance),
is_open_(false) {
SendCreate(RENDERER, PpapiHostMsg_VideoDestination_Create());
}
VideoDestinationResource::~VideoDestinationResource() {
}
PPB_VideoDestination_Private_API*
VideoDestinationResource::AsPPB_VideoDestination_Private_API() {
return this;
}
int32_t VideoDestinationResource::Open(
const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) {
if (TrackedCallback::IsPending(open_callback_))
return PP_ERROR_INPROGRESS;
open_callback_ = callback;
scoped_refptr<StringVar> stream_url_var = StringVar::FromPPVar(stream_url);
const uint32_t kMaxStreamIdSizeInBytes = 16384;
if (!stream_url_var.get() ||
stream_url_var->value().size() > kMaxStreamIdSizeInBytes)
return PP_ERROR_BADARGUMENT;
Call<PpapiPluginMsg_VideoDestination_OpenReply>(RENDERER,
PpapiHostMsg_VideoDestination_Open(stream_url_var->value()),
base::Bind(&VideoDestinationResource::OnPluginMsgOpenComplete, this));
return PP_OK_COMPLETIONPENDING;
}
int32_t VideoDestinationResource::PutFrame(
const PP_VideoFrame_Private& frame) {
if (!is_open_)
return PP_ERROR_FAILED;
thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image(
frame.image_data, true);
if (enter_image.failed())
return PP_ERROR_BADRESOURCE;
// Check that the PP_Instance matches.
Resource* image_object =
PpapiGlobals::Get()->GetResourceTracker()->GetResource(frame.image_data);
if (!image_object || pp_instance() != image_object->pp_instance()) {
Log(PP_LOGLEVEL_ERROR,
"VideoDestinationPrivateResource.PutFrame: Bad image resource.");
return PP_ERROR_BADRESOURCE;
}
Post(RENDERER,
PpapiHostMsg_VideoDestination_PutFrame(image_object->host_resource(),
frame.timestamp));
return PP_OK;
}
void VideoDestinationResource::Close() {
Post(RENDERER, PpapiHostMsg_VideoDestination_Close());
if (TrackedCallback::IsPending(open_callback_))
open_callback_->PostAbort();
}
void VideoDestinationResource::OnPluginMsgOpenComplete(
const ResourceMessageReplyParams& params) {
if (TrackedCallback::IsPending(open_callback_)) {
int32_t result = params.result();
if (result == PP_OK)
is_open_ = true;
open_callback_->Run(result);
}
}
} // namespace proxy
} // namespace ppapi

@ -1,59 +0,0 @@
// 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.
#ifndef PPAPI_PROXY_VIDEO_DESTINATION_RESOURCE_H_
#define PPAPI_PROXY_VIDEO_DESTINATION_RESOURCE_H_
#include <stdint.h>
#include <string>
#include "base/macros.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/proxy/connection.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/thunk/ppb_video_destination_private_api.h"
struct PP_VideoFrame_Private;
namespace ppapi {
class TrackedCallback;
namespace proxy {
class PPAPI_PROXY_EXPORT VideoDestinationResource
: public PluginResource,
public thunk::PPB_VideoDestination_Private_API {
public:
VideoDestinationResource(Connection connection,
PP_Instance instance);
~VideoDestinationResource() override;
// Resource overrides.
thunk::PPB_VideoDestination_Private_API* AsPPB_VideoDestination_Private_API()
override;
// PPB_VideoDestination_Private_API implementation.
int32_t Open(
const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) override;
int32_t PutFrame(const PP_VideoFrame_Private& frame) override;
void Close() override;
private:
void OnPluginMsgOpenComplete(
const ResourceMessageReplyParams& params);
scoped_refptr<TrackedCallback> open_callback_;
bool is_open_;
DISALLOW_COPY_AND_ASSIGN(VideoDestinationResource);
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_VIDEO_DESTINATION_RESOURCE_H_

@ -1,120 +0,0 @@
// 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 "ppapi/proxy/video_source_resource.h"
#include "base/bind.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_image_data_proxy.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_VideoSource_Private_API;
namespace ppapi {
namespace proxy {
VideoSourceResource::VideoSourceResource(
Connection connection,
PP_Instance instance)
: PluginResource(connection, instance),
is_open_(false) {
SendCreate(RENDERER, PpapiHostMsg_VideoSource_Create());
}
VideoSourceResource::~VideoSourceResource() {
}
PPB_VideoSource_Private_API*
VideoSourceResource::AsPPB_VideoSource_Private_API() {
return this;
}
int32_t VideoSourceResource::Open(
const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) {
if (TrackedCallback::IsPending(open_callback_))
return PP_ERROR_INPROGRESS;
open_callback_ = callback;
scoped_refptr<StringVar> stream_url_var = StringVar::FromPPVar(stream_url);
const uint32_t kMaxStreamIdSizeInBytes = 16384;
if (!stream_url_var.get() ||
stream_url_var->value().size() > kMaxStreamIdSizeInBytes)
return PP_ERROR_BADARGUMENT;
Call<PpapiPluginMsg_VideoSource_OpenReply>(RENDERER,
PpapiHostMsg_VideoSource_Open(stream_url_var->value()),
base::Bind(&VideoSourceResource::OnPluginMsgOpenComplete, this));
return PP_OK_COMPLETIONPENDING;
}
int32_t VideoSourceResource::GetFrame(
PP_VideoFrame_Private* frame,
scoped_refptr<TrackedCallback> callback) {
if (!is_open_)
return PP_ERROR_FAILED;
if (TrackedCallback::IsPending(get_frame_callback_))
return PP_ERROR_INPROGRESS;
get_frame_callback_ = callback;
Call<PpapiPluginMsg_VideoSource_GetFrameReply>(RENDERER,
PpapiHostMsg_VideoSource_GetFrame(),
base::Bind(&VideoSourceResource::OnPluginMsgGetFrameComplete, this,
frame));
return PP_OK_COMPLETIONPENDING;
}
void VideoSourceResource::Close() {
Post(RENDERER, PpapiHostMsg_VideoSource_Close());
if (TrackedCallback::IsPending(open_callback_))
open_callback_->PostAbort();
if (TrackedCallback::IsPending(get_frame_callback_))
get_frame_callback_->PostAbort();
}
void VideoSourceResource::OnPluginMsgOpenComplete(
const ResourceMessageReplyParams& reply_params) {
if (TrackedCallback::IsPending(open_callback_)) {
int32_t result = reply_params.result();
if (result == PP_OK)
is_open_ = true;
open_callback_->Run(result);
}
}
void VideoSourceResource::OnPluginMsgGetFrameComplete(
PP_VideoFrame_Private* frame,
const ResourceMessageReplyParams& reply_params,
const HostResource& image_data,
const PP_ImageDataDesc& image_desc,
PP_TimeTicks timestamp) {
// The callback may have been aborted by Close().
if (TrackedCallback::IsPending(get_frame_callback_)) {
int32_t result = reply_params.result();
if (result == PP_OK &&
PPB_ImageData_Shared::IsImageDataDescValid(image_desc)) {
frame->timestamp = timestamp;
base::SharedMemoryHandle handle;
if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &handle))
frame->image_data = 0;
frame->image_data =
(new SimpleImageData(
image_data, image_desc, handle))->GetReference();
}
get_frame_callback_->Run(result);
}
}
} // namespace proxy
} // namespace ppapi

@ -1,69 +0,0 @@
// 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.
#ifndef PPAPI_PROXY_VIDEO_SOURCE_RESOURCE_H_
#define PPAPI_PROXY_VIDEO_SOURCE_RESOURCE_H_
#include <stdint.h>
#include <string>
#include "base/macros.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/proxy/connection.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/thunk/ppb_video_source_private_api.h"
struct PP_ImageDataDesc;
struct PP_VideoFrame_Private;
namespace ppapi {
class TrackedCallback;
namespace proxy {
class PPAPI_PROXY_EXPORT VideoSourceResource
: public PluginResource,
public thunk::PPB_VideoSource_Private_API {
public:
VideoSourceResource(Connection connection,
PP_Instance instance);
~VideoSourceResource() override;
// Resource overrides.
thunk::PPB_VideoSource_Private_API* AsPPB_VideoSource_Private_API() override;
// PPB_VideoSource_Private_API implementation.
int32_t Open(
const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) override;
int32_t GetFrame(
PP_VideoFrame_Private* frame,
scoped_refptr<TrackedCallback> callback) override;
void Close() override;
private:
void OnPluginMsgOpenComplete(
const ResourceMessageReplyParams& reply_params);
void OnPluginMsgGetFrameComplete(
PP_VideoFrame_Private* frame,
const ResourceMessageReplyParams& reply_params,
const HostResource& image_data,
const PP_ImageDataDesc& image_desc_data,
PP_TimeTicks timestamp);
scoped_refptr<TrackedCallback> open_callback_;
scoped_refptr<TrackedCallback> get_frame_callback_;
bool is_open_;
DISALLOW_COPY_AND_ASSIGN(VideoSourceResource);
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_VIDEO_SOURCE_RESOURCE_H_

@ -82,11 +82,9 @@
F(PPB_VideoCapture_API) \
F(PPB_VideoDecoder_API) \
F(PPB_VideoDecoder_Dev_API) \
F(PPB_VideoDestination_Private_API) \
F(PPB_VideoEncoder_API) \
F(PPB_VideoFrame_API) \
F(PPB_VideoLayer_API) \
F(PPB_VideoSource_Private_API) \
F(PPB_View_API) \
F(PPB_VpnProvider_API) \
F(PPB_WebSocket_API) \

@ -117,8 +117,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/private/ppp_find_private.h"
#include "ppapi/c/private/ppp_instance_private.h"

@ -52,14 +52,11 @@
#include "ppapi/cpp/private/flash_font_file.h"
#include "ppapi/cpp/private/flash_fullscreen.h"
#include "ppapi/cpp/private/instance_private.h"
#include "ppapi/cpp/private/instance_private.h"
#include "ppapi/cpp/private/net_address_private.h"
#include "ppapi/cpp/private/tcp_socket_private.h"
#include "ppapi/cpp/private/udp_socket_private.h"
#include "ppapi/cpp/private/var_private.h"
#include "ppapi/cpp/private/video_destination_private.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/private/video_source_private.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/resource.h"
#include "ppapi/cpp/size.h"

@ -1,126 +0,0 @@
// 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.
//
// Tests PPB_VideoDestination_Private interface.
#include "ppapi/tests/test_video_destination.h"
#include <algorithm>
#include <limits>
#include <string>
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/private/video_destination_private.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
REGISTER_TEST_CASE(VideoDestination);
namespace {
const PP_Resource kInvalidResource = 0;
const PP_Instance kInvalidInstance = 0;
}
TestVideoDestination::TestVideoDestination(TestingInstance* instance)
: TestCase(instance),
ppb_video_destination_private_interface_(NULL),
ppb_core_interface_(NULL),
event_(instance_->pp_instance()) {
}
bool TestVideoDestination::Init() {
ppb_video_destination_private_interface_ =
static_cast<const PPB_VideoDestination_Private*>(
pp::Module::Get()->GetBrowserInterface(
PPB_VIDEODESTINATION_PRIVATE_INTERFACE));
if (!ppb_video_destination_private_interface_)
instance_->AppendError(
"PPB_VideoDestination_Private interface not available");
ppb_core_interface_ = static_cast<const PPB_Core*>(
pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
if (!ppb_core_interface_)
instance_->AppendError("PPB_Core interface not available");
return
ppb_video_destination_private_interface_ &&
ppb_core_interface_;
}
TestVideoDestination::~TestVideoDestination() {
}
void TestVideoDestination::RunTests(const std::string& filter) {
RUN_TEST(Create, filter);
RUN_TEST(PutFrame, filter);
}
void TestVideoDestination::HandleMessage(const pp::Var& message_data) {
if (message_data.AsString().find("blob:") == 0) {
stream_url_ = message_data.AsString();
event_.Signal();
}
}
std::string TestVideoDestination::TestCreate() {
PP_Resource video_destination;
// Creating a destination from an invalid instance returns an invalid
// resource.
video_destination =
ppb_video_destination_private_interface_->Create(kInvalidInstance);
ASSERT_EQ(kInvalidResource, video_destination);
ASSERT_FALSE(
ppb_video_destination_private_interface_->IsVideoDestination(
video_destination));
// Creating a destination from a valid instance returns a valid resource.
video_destination =
ppb_video_destination_private_interface_->Create(
instance_->pp_instance());
ASSERT_NE(kInvalidResource, video_destination);
ASSERT_TRUE(
ppb_video_destination_private_interface_->IsVideoDestination(
video_destination));
ppb_core_interface_->ReleaseResource(video_destination);
// Once released, the resource shouldn't be a video destination.
ASSERT_FALSE(
ppb_video_destination_private_interface_->IsVideoDestination(
video_destination));
PASS();
}
std::string TestVideoDestination::TestPutFrame() {
std::string js_code;
js_code += "var test_stream = new MediaStream([]);"
"var url = URL.createObjectURL(test_stream);"
"var plugin = document.getElementById('plugin');"
"plugin.postMessage(url);";
instance_->EvalScript(js_code);
event_.Wait();
pp::VideoDestination_Private video_destination(instance_);
TestCompletionCallback cc1(instance_->pp_instance(), false);
cc1.WaitForResult(video_destination.Open(stream_url_, cc1.GetCallback()));
ASSERT_EQ(PP_OK, cc1.result());
pp::ImageData image_data(instance_,
PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(640, 480),
false /* init_to_zero */);
pp::VideoFrame_Private video_frame(image_data,
0.0 /* timestamp */);
ASSERT_EQ(PP_OK, video_destination.PutFrame(video_frame));
video_destination.Close();
PASS();
}

@ -1,36 +0,0 @@
// 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.
#ifndef PAPPI_TESTS_TEST_VIDEO_DESTINATION_H_
#define PAPPI_TESTS_TEST_VIDEO_DESTINATION_H_
#include <string>
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/tests/test_case.h"
class TestVideoDestination : public TestCase {
public:
explicit TestVideoDestination(TestingInstance* instance);
virtual ~TestVideoDestination();
private:
// TestCase implementation.
virtual bool Init();
virtual void RunTests(const std::string& filter);
// Overrides.
virtual void HandleMessage(const pp::Var& message_data);
std::string TestCreate();
std::string TestPutFrame();
const PPB_VideoDestination_Private* ppb_video_destination_private_interface_;
const PPB_Core* ppb_core_interface_;
NestedEvent event_;
std::string stream_url_;
};
#endif // PAPPI_TESTS_TEST_VIDEO_DESTINATION_H_

@ -1,121 +0,0 @@
// 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.
//
// Tests PPB_VideoSource_Private interface.
#include "ppapi/tests/test_video_source.h"
#include <string.h>
#include <algorithm>
#include <limits>
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/private/video_frame_private.h"
#include "ppapi/cpp/private/video_source_private.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
REGISTER_TEST_CASE(VideoSource);
namespace {
const PP_Resource kInvalidResource = 0;
const PP_Instance kInvalidInstance = 0;
}
TestVideoSource::TestVideoSource(TestingInstance* instance)
: TestCase(instance),
ppb_video_source_private_interface_(NULL),
ppb_core_interface_(NULL),
event_(instance_->pp_instance()) {
}
bool TestVideoSource::Init() {
ppb_video_source_private_interface_ =
static_cast<const PPB_VideoSource_Private*>(
pp::Module::Get()->GetBrowserInterface(
PPB_VIDEOSOURCE_PRIVATE_INTERFACE));
if (!ppb_video_source_private_interface_)
instance_->AppendError("PPB_VideoSource_Private interface not available");
ppb_core_interface_ = static_cast<const PPB_Core*>(
pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
if (!ppb_core_interface_)
instance_->AppendError("PPB_Core interface not available");
return ppb_video_source_private_interface_ && ppb_core_interface_;
}
TestVideoSource::~TestVideoSource() {
}
void TestVideoSource::RunTests(const std::string& filter) {
RUN_TEST(Create, filter);
RUN_TEST(GetFrame, filter);
}
void TestVideoSource::HandleMessage(const pp::Var& message_data) {
if (message_data.AsString().find("blob:") == 0) {
stream_url_ = message_data.AsString();
event_.Signal();
}
}
std::string TestVideoSource::TestCreate() {
PP_Resource video_source;
// Creating a source from an invalid instance returns an invalid resource.
video_source = ppb_video_source_private_interface_->Create(kInvalidInstance);
ASSERT_EQ(kInvalidResource, video_source);
ASSERT_FALSE(
ppb_video_source_private_interface_->IsVideoSource(video_source));
// Creating a source from a valid instance returns a valid resource.
video_source =
ppb_video_source_private_interface_->Create(instance_->pp_instance());
ASSERT_NE(kInvalidResource, video_source);
ASSERT_TRUE(
ppb_video_source_private_interface_->IsVideoSource(video_source));
ppb_core_interface_->ReleaseResource(video_source);
// Once released, the resource shouldn't be a video source.
ASSERT_FALSE(
ppb_video_source_private_interface_->IsVideoSource(video_source));
PASS();
}
std::string TestVideoSource::TestGetFrame() {
std::string js_code;
js_code += "var test_stream;"
"function gotStream(stream){"
" test_stream = stream;"
" var url = URL.createObjectURL(test_stream);"
" var plugin = document.getElementById('plugin');"
" plugin.postMessage(url);"
"}"
"navigator.webkitGetUserMedia("
"{audio:false, video:true}, gotStream, function() {});";
instance_->EvalScript(js_code);
event_.Wait();
pp::VideoSource_Private video_source(instance_);
TestCompletionCallback cc1(instance_->pp_instance(), false);
cc1.WaitForResult(video_source.Open(stream_url_, cc1.GetCallback()));
ASSERT_EQ(PP_OK, cc1.result());
TestCompletionCallbackWithOutput<pp::VideoFrame_Private> cc2(
instance_->pp_instance(), false);
cc2.WaitForResult(video_source.GetFrame(cc2.GetCallback()));
ASSERT_EQ(PP_OK, cc2.result());
const pp::VideoFrame_Private video_frame = cc2.output();
ASSERT_FALSE(video_frame.image_data().is_null());
video_source.Close();
PASS();
}

@ -1,36 +0,0 @@
// 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.
#ifndef PAPPI_TESTS_TEST_VIDEO_SOURCE_H_
#define PAPPI_TESTS_TEST_VIDEO_SOURCE_H_
#include <string>
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/tests/test_case.h"
class TestVideoSource : public TestCase {
public:
explicit TestVideoSource(TestingInstance* instance);
virtual ~TestVideoSource();
private:
// TestCase implementation.
virtual bool Init();
virtual void RunTests(const std::string& filter);
// Overrides.
virtual void HandleMessage(const pp::Var& message_data);
std::string TestCreate();
std::string TestGetFrame();
const PPB_VideoSource_Private* ppb_video_source_private_interface_;
const PPB_Core* ppb_core_interface_;
NestedEvent event_;
std::string stream_url_;
};
#endif // PAPPI_TESTS_TEST_VIDEO_SOURCE_H_

@ -137,14 +137,10 @@ source_set("thunk") {
"ppb_video_decoder_api.h",
"ppb_video_decoder_dev_api.h",
"ppb_video_decoder_thunk.cc",
"ppb_video_destination_private_api.h",
"ppb_video_destination_private_thunk.cc",
"ppb_video_encoder_api.h",
"ppb_video_encoder_thunk.cc",
"ppb_video_frame_api.h",
"ppb_video_frame_thunk.cc",
"ppb_video_source_private_api.h",
"ppb_video_source_private_thunk.cc",
"ppb_view_api.h",
"ppb_view_dev_thunk.cc",
"ppb_view_thunk.cc",

@ -48,11 +48,6 @@ PROXIED_IFACE(PPB_FILEIO_PRIVATE_INTERFACE_0_1,
PROXIED_IFACE(PPB_ISOLATEDFILESYSTEM_PRIVATE_INTERFACE_0_2,
PPB_IsolatedFileSystem_Private_0_2)
PROXIED_IFACE(PPB_VIDEODESTINATION_PRIVATE_INTERFACE_0_1,
PPB_VideoDestination_Private_0_1)
PROXIED_IFACE(PPB_VIDEOSOURCE_PRIVATE_INTERFACE_0_1,
PPB_VideoSource_Private_0_1)
PROXIED_IFACE(PPB_UMA_PRIVATE_INTERFACE_0_3,
PPB_UMA_Private_0_3)

@ -1,34 +0,0 @@
// 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.
#ifndef PPAPI_THUNK_PPB_VIDEO_DESTINATION_PRIVATE_API_H_
#define PPAPI_THUNK_PPB_VIDEO_DESTINATION_PRIVATE_API_H_
#include <stdint.h>
#include "base/memory/ref_counted.h"
#include "ppapi/thunk/ppapi_thunk_export.h"
struct PP_VideoFrame_Private;
namespace ppapi {
class TrackedCallback;
namespace thunk {
class PPAPI_THUNK_EXPORT PPB_VideoDestination_Private_API {
public:
virtual ~PPB_VideoDestination_Private_API() {}
virtual int32_t Open(const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) = 0;
virtual int32_t PutFrame(const PP_VideoFrame_Private& frame) = 0;
virtual void Close() = 0;
};
} // namespace thunk
} // namespace ppapi
#endif // PPAPI_THUNK_PPB_VIDEO_DESTINATION_PRIVATE_API_H_

@ -1,76 +0,0 @@
// 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 <stdint.h>
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#include "ppapi/c/private/ppb_video_destination_private.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_instance_api.h"
#include "ppapi/thunk/ppb_video_destination_private_api.h"
#include "ppapi/thunk/resource_creation_api.h"
#include "ppapi/thunk/thunk.h"
namespace ppapi {
namespace thunk {
namespace {
PP_Resource Create(PP_Instance instance) {
EnterResourceCreation enter(instance);
if (enter.failed())
return 0;
return enter.functions()->CreateVideoDestination(instance);
}
PP_Bool IsVideoDestination(PP_Resource resource) {
EnterResource<PPB_VideoDestination_Private_API> enter(resource, false);
return PP_FromBool(enter.succeeded());
}
int32_t Open(PP_Resource destination,
PP_Var stream_url,
PP_CompletionCallback callback) {
EnterResource<PPB_VideoDestination_Private_API> enter(destination,
callback, true);
if (enter.failed())
return enter.retval();
return enter.SetResult(enter.object()->Open(stream_url, enter.callback()));
}
int32_t PutFrame(PP_Resource destination,
const PP_VideoFrame_Private* frame) {
EnterResource<PPB_VideoDestination_Private_API> enter(destination, true);
if (enter.failed())
return enter.retval();
return enter.object()->PutFrame(*frame);
}
void Close(PP_Resource destination) {
EnterResource<PPB_VideoDestination_Private_API> enter(destination, true);
if (enter.succeeded())
enter.object()->Close();
}
const PPB_VideoDestination_Private_0_1
g_ppb_video_destination_private_thunk_0_1 = {
&Create,
&IsVideoDestination,
&Open,
&PutFrame,
&Close
};
} // namespace
const PPB_VideoDestination_Private_0_1*
GetPPB_VideoDestination_Private_0_1_Thunk() {
return &g_ppb_video_destination_private_thunk_0_1;
}
} // namespace thunk
} // namespace ppapi

@ -1,35 +0,0 @@
// 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.
#ifndef PPAPI_THUNK_PPB_VIDEO_SOURCE_PRIVATE_API_H_
#define PPAPI_THUNK_PPB_VIDEO_SOURCE_PRIVATE_API_H_
#include <stdint.h>
#include "base/memory/ref_counted.h"
#include "ppapi/thunk/ppapi_thunk_export.h"
struct PP_VideoFrame_Private;
namespace ppapi {
class TrackedCallback;
namespace thunk {
class PPAPI_THUNK_EXPORT PPB_VideoSource_Private_API {
public:
virtual ~PPB_VideoSource_Private_API() {}
virtual int32_t Open(const PP_Var& stream_url,
scoped_refptr<TrackedCallback> callback) = 0;
virtual int32_t GetFrame(PP_VideoFrame_Private* frame,
scoped_refptr<TrackedCallback> callback) = 0;
virtual void Close() = 0;
};
} // namespace thunk
} // namespace ppapi
#endif // PPAPI_THUNK_PPB_VIDEO_SOURCE_PRIVATE_API_H_

@ -1,73 +0,0 @@
// 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 <stdint.h>
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/pp_video_frame_private.h"
#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_video_source_private_api.h"
#include "ppapi/thunk/resource_creation_api.h"
#include "ppapi/thunk/thunk.h"
namespace ppapi {
namespace thunk {
namespace {
PP_Resource Create(PP_Instance instance) {
EnterResourceCreation enter(instance);
if (enter.failed())
return 0;
return enter.functions()->CreateVideoSource(instance);
}
PP_Bool IsVideoSource(PP_Resource resource) {
EnterResource<PPB_VideoSource_Private_API> enter(resource, false);
return PP_FromBool(enter.succeeded());
}
int32_t Open(PP_Resource source,
PP_Var stream_url,
PP_CompletionCallback callback) {
EnterResource<PPB_VideoSource_Private_API> enter(source, callback, true);
if (enter.failed())
return enter.retval();
return enter.SetResult(enter.object()->Open(stream_url, enter.callback()));
}
int32_t GetFrame(PP_Resource source,
PP_VideoFrame_Private* frame,
PP_CompletionCallback callback) {
EnterResource<PPB_VideoSource_Private_API> enter(source, callback, true);
if (enter.failed())
return enter.retval();
return enter.SetResult(enter.object()->GetFrame(frame, enter.callback()));
}
void Close(PP_Resource source) {
EnterResource<PPB_VideoSource_Private_API> enter(source, true);
if (enter.succeeded())
enter.object()->Close();
}
const PPB_VideoSource_Private_0_1 g_ppb_video_source_private_thunk_0_1 = {
&Create,
&IsVideoSource,
&Open,
&GetFrame,
&Close
};
} // namespace
const PPB_VideoSource_Private_0_1* GetPPB_VideoSource_Private_0_1_Thunk() {
return &g_ppb_video_source_private_thunk_0_1;
}
} // namespace thunk
} // namespace ppapi

@ -179,9 +179,7 @@ class ResourceCreationAPI {
virtual PP_Resource CreateUDPSocket(PP_Instance instace) = 0;
virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instace) = 0;
virtual PP_Resource CreateVideoDecoder(PP_Instance instance) = 0;
virtual PP_Resource CreateVideoDestination(PP_Instance instance) = 0;
virtual PP_Resource CreateVideoEncoder(PP_Instance instance) = 0;
virtual PP_Resource CreateVideoSource(PP_Instance instance) = 0;
virtual PP_Resource CreateVpnProvider(PP_Instance instance) = 0;
virtual PP_Resource CreateWebSocket(PP_Instance instance) = 0;
virtual PP_Resource CreateX509CertificatePrivate(PP_Instance instance) = 0;