diff options
author | ronghuawu@chromium.org <ronghuawu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 23:36:52 +0000 |
---|---|---|
committer | ronghuawu@chromium.org <ronghuawu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 23:36:52 +0000 |
commit | 5294ec9616595ec4691018e34ce47dd9734ed64d (patch) | |
tree | 01017b7a2ef6ca277aaf37e356cf0d83d3371152 | |
parent | eb7350d046524fbe069e1e320f49546693475a3f (diff) | |
download | chromium_src-5294ec9616595ec4691018e34ce47dd9734ed64d.zip chromium_src-5294ec9616595ec4691018e34ce47dd9734ed64d.tar.gz chromium_src-5294ec9616595ec4691018e34ce47dd9734ed64d.tar.bz2 |
[PPAPI] Add media stream video track output API
Implemented the pepper host for the output mode.
R=bbudge@chromium.org, dmichael@chromium.org, jschuh@chromium.org, yzshen@chromium.org
Review URL: https://codereview.chromium.org/145263008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268318 0039d316-1c4b-4281-b951-d872f2087c98
32 files changed, 695 insertions, 54 deletions
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc index 87ade57..399bdb2 100644 --- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc +++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc @@ -13,6 +13,7 @@ #include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_file_system_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" +#include "content/renderer/pepper/pepper_media_stream_video_track_host.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_truetype_font_host.h" #include "content/renderer/pepper/pepper_url_loader_host.h" @@ -126,6 +127,9 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( return scoped_ptr<ResourceHost>( new PepperWebSocketHost(host_, instance, params.pp_resource())); #if defined(ENABLE_WEBRTC) + case PpapiHostMsg_MediaStreamVideoTrack_Create::ID: + return scoped_ptr<ResourceHost>(new PepperMediaStreamVideoTrackHost( + host_, instance, params.pp_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. diff --git a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc index f7ca253..f45f601 100644 --- a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc +++ b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc @@ -75,7 +75,7 @@ void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffersOnMainThread( int32_t number_of_buffers, int32_t buffer_size) { DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); - bool result = host_->InitBuffers(number_of_buffers, buffer_size); + bool result = host_->InitBuffers(number_of_buffers, buffer_size, kRead); // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. CHECK(result); base::AutoLock lock(lock_); diff --git a/content/renderer/pepper/pepper_media_stream_track_host_base.cc b/content/renderer/pepper/pepper_media_stream_track_host_base.cc index f21790a..4a22c49 100644 --- a/content/renderer/pepper/pepper_media_stream_track_host_base.cc +++ b/content/renderer/pepper/pepper_media_stream_track_host_base.cc @@ -30,7 +30,8 @@ PepperMediaStreamTrackHostBase::PepperMediaStreamTrackHostBase( PepperMediaStreamTrackHostBase::~PepperMediaStreamTrackHostBase() {} bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers, - int32_t buffer_size) { + int32_t buffer_size, + TrackType track_type) { DCHECK_GT(number_of_buffers, 0); DCHECK_GT(buffer_size, static_cast<int32_t>(sizeof(ppapi::MediaStreamBuffer::Header))); @@ -62,10 +63,12 @@ bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers, #endif SerializedHandle handle(host_->ShareHandleWithRemote(platform_file, false), size); + bool readonly = (track_type == kRead); host()->SendUnsolicitedReplyWithHandles( pp_resource(), PpapiPluginMsg_MediaStreamTrack_InitBuffers(number_of_buffers, - buffer_size), + buffer_size, + readonly), std::vector<SerializedHandle>(1, handle)); return true; } @@ -78,6 +81,13 @@ void PepperMediaStreamTrackHostBase::SendEnqueueBufferMessageToPlugin( pp_resource(), PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer(index)); } +void PepperMediaStreamTrackHostBase::SendEnqueueBuffersMessageToPlugin( + const std::vector<int32_t>& indices) { + DCHECK_GE(indices.size(), 0U); + host()->SendUnsolicitedReply(pp_resource(), + PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers(indices)); +} + int32_t PepperMediaStreamTrackHostBase::OnResourceMessageReceived( const IPC::Message& msg, HostMessageContext* context) { diff --git a/content/renderer/pepper/pepper_media_stream_track_host_base.h b/content/renderer/pepper/pepper_media_stream_track_host_base.h index 76eb41a..37ebd61 100644 --- a/content/renderer/pepper/pepper_media_stream_track_host_base.h +++ b/content/renderer/pepper/pepper_media_stream_track_host_base.h @@ -23,7 +23,13 @@ class PepperMediaStreamTrackHostBase PP_Resource resource); virtual ~PepperMediaStreamTrackHostBase(); - bool InitBuffers(int32_t number_of_buffers, int32_t buffer_size); + enum TrackType { + kRead, + kWrite + }; + bool InitBuffers(int32_t number_of_buffers, + int32_t buffer_size, + TrackType track_type); ppapi::MediaStreamBufferManager* buffer_manager() { return &buffer_manager_; } @@ -33,18 +39,26 @@ class PepperMediaStreamTrackHostBase // Also see |MediaStreamBufferManager|. void SendEnqueueBufferMessageToPlugin(int32_t index); + // Sends a set of buffer indices to the corresponding + // MediaStreamTrackResourceBase via an IPC message. + // The resource adds the buffer indices into its + // |frame_buffer_| for reading or writing. Also see |MediaStreamFrameBuffer|. + void SendEnqueueBuffersMessageToPlugin(const std::vector<int32_t>& indices); + // ResourceMessageHandler overrides: virtual int32_t OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) OVERRIDE; + // Message handlers: + virtual int32_t OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index); + private: // Subclasses must implement this method to clean up when the track is closed. virtual void OnClose() = 0; // Message handlers: - int32_t OnHostMsgEnqueueBuffer(ppapi::host::HostMessageContext* context, - int32_t index); int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context); RendererPpapiHost* host_; diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/content/renderer/pepper/pepper_media_stream_video_track_host.cc index 12385666..854ed90 100644 --- a/content/renderer/pepper/pepper_media_stream_video_track_host.cc +++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc @@ -4,14 +4,24 @@ #include "content/renderer/pepper/pepper_media_stream_video_track_host.h" +#include "base/base64.h" #include "base/logging.h" +#include "base/rand_util.h" +#include "base/strings/utf_string_conversions.h" +#include "content/renderer/media/media_stream_video_track.h" #include "media/base/yuv_convert.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_media_stream_video_track.h" #include "ppapi/c/ppb_video_frame.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/host_message_context.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/media_stream_buffer.h" + +// IS_ALIGNED is also defined in +// third_party/libjingle/overrides/talk/base/basictypes.h +// TODO(ronghuawu): Avoid undef. +#undef IS_ALIGNED #include "third_party/libyuv/include/libyuv.h" using media::VideoFrame; @@ -25,6 +35,23 @@ const int32_t kMaxNumberOfBuffers = 8; // Filter mode for scaling frames. const libyuv::FilterMode kFilterMode = libyuv::kFilterBox; +const char kPepperVideoSourceName[] = "PepperVideoSourceName"; + +// Default config for output mode. +const int kDefaultOutputFrameRate = 30; + +media::VideoPixelFormat ToPixelFormat(PP_VideoFrame_Format format) { + switch (format) { + case PP_VIDEOFRAME_FORMAT_YV12: + return media::PIXEL_FORMAT_YV12; + case PP_VIDEOFRAME_FORMAT_I420: + return media::PIXEL_FORMAT_I420; + default: + DVLOG(1) << "Unsupported pixel format " << format; + return media::PIXEL_FORMAT_UNKNOWN; + } +} + PP_VideoFrame_Format ToPpapiFormat(VideoFrame::Format format) { switch (format) { case VideoFrame::YV12: @@ -160,10 +187,32 @@ PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( number_of_buffers_(kDefaultNumberOfBuffers), source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), - frame_data_size_(0) { + frame_data_size_(0), + type_(kRead), + output_started_(false) { DCHECK(!track_.isNull()); } +PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : PepperMediaStreamTrackHostBase(host, instance, resource), + connected_(false), + number_of_buffers_(kDefaultNumberOfBuffers), + source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + frame_data_size_(0), + type_(kWrite), + output_started_(false) { + InitBlinkTrack(); + DCHECK(!track_.isNull()); +} + +bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { + return true; +} + PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { OnClose(); } @@ -187,8 +236,26 @@ void PepperMediaStreamVideoTrackHost::InitBuffers() { int32_t buffer_size = sizeof(ppapi::MediaStreamBuffer::Video) + frame_data_size_; bool result = PepperMediaStreamTrackHostBase::InitBuffers(number_of_buffers_, - buffer_size); + buffer_size, + type_); CHECK(result); + + if (type_ == kWrite) { + for (int32_t i = 0; i < buffer_manager()->number_of_buffers(); ++i) { + ppapi::MediaStreamBuffer::Video* buffer = + &(buffer_manager()->GetBufferPointer(i)->video); + buffer->header.size = buffer_manager()->buffer_size(); + buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO; + buffer->format = format; + buffer->size.width = size.width(); + buffer->size.height = size.height(); + buffer->data_size = frame_data_size_; + } + + // Make all the frames avaiable to the plugin. + std::vector<int32_t> indices = buffer_manager()->DequeueBuffers(); + SendEnqueueBuffersMessageToPlugin(indices); + } } void PepperMediaStreamVideoTrackHost::OnClose() { @@ -198,6 +265,64 @@ void PepperMediaStreamVideoTrackHost::OnClose() { } } +int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index) { + if (type_ == kRead) { + return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, + index); + } else { + return SendFrameToTrack(index); + } +} + +int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) { + DCHECK_EQ(type_, kWrite); + + if (output_started_) { + // Sends the frame to blink video track. + ppapi::MediaStreamBuffer::Video* pp_frame = + &(buffer_manager()->GetBufferPointer(index)->video); + + int32 y_stride = plugin_frame_size_.width(); + int32 uv_stride = (plugin_frame_size_.width() + 1) / 2; + uint8* y_data = static_cast<uint8*>(pp_frame->data); + // Default to I420 + uint8* u_data = y_data + plugin_frame_size_.GetArea(); + uint8* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4); + if (plugin_frame_format_ == PP_VIDEOFRAME_FORMAT_YV12) { + // Swap u and v for YV12. + uint8* tmp = u_data; + u_data = v_data; + v_data = tmp; + } + + int64 ts_ms = static_cast<int64>(pp_frame->timestamp * + base::Time::kMillisecondsPerSecond); + scoped_refptr<VideoFrame> frame = media::VideoFrame::WrapExternalYuvData( + FromPpapiFormat(plugin_frame_format_), + plugin_frame_size_, + gfx::Rect(plugin_frame_size_), + plugin_frame_size_, + y_stride, + uv_stride, + uv_stride, + y_data, + u_data, + v_data, + base::TimeDelta::FromMilliseconds(ts_ms), + base::Closure()); + + DeliverVideoFrame(frame, media::VideoCaptureFormat( + plugin_frame_size_, + kDefaultOutputFrameRate, + ToPixelFormat(plugin_frame_format_))); + } + + // Makes the frame available again for plugin. + SendEnqueueBufferMessageToPlugin(index); + return PP_OK; +} + void PepperMediaStreamVideoTrackHost::OnVideoFrame( const scoped_refptr<VideoFrame>& frame) { DCHECK(frame); @@ -235,9 +360,34 @@ void PepperMediaStreamVideoTrackHost::OnVideoFrame( buffer->size.height = size.height(); buffer->data_size = frame_data_size_; ConvertFromMediaVideoFrame(frame, format, size, buffer->data); + SendEnqueueBufferMessageToPlugin(index); } +void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats( + int max_requested_width, int max_requested_height) { + if (type_ != kWrite) { + DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode."; + return; + } + + media::VideoCaptureFormats formats; + formats.push_back( + media::VideoCaptureFormat(plugin_frame_size_, + kDefaultOutputFrameRate, + ToPixelFormat(plugin_frame_format_))); + OnSupportedFormats(formats); +} + +void PepperMediaStreamVideoTrackHost::StartSourceImpl( + const media::VideoCaptureParams& params) { + output_started_ = true; +} + +void PepperMediaStreamVideoTrackHost::StopSourceImpl() { + output_started_ = false; +} + void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { if (!connected_) { MediaStreamVideoSink::AddToVideoTrack(this, track_); @@ -286,11 +436,39 @@ int32_t PepperMediaStreamVideoTrackHost::OnHostMsgConfigure( // new settings. Otherwise, we will initialize buffer when we receive // the first frame, because plugin can only provide part of attributes // which are not enough to initialize buffers. - if (changed && !source_frame_size_.IsEmpty()) + if (changed && (type_ == kWrite || !source_frame_size_.IsEmpty())) InitBuffers(); - context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply(); + // TODO(ronghuawu): Ask the owner of DOMMediaStreamTrackToResource why + // source id instead of track id is used there. + const std::string id = track_.source().id().utf8(); + context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply(id); return PP_OK; } +void PepperMediaStreamVideoTrackHost::InitBlinkTrack() { + std::string source_id; + base::Base64Encode(base::RandBytesAsString(64), &source_id); + blink::WebMediaStreamSource webkit_source; + webkit_source.initialize(base::UTF8ToUTF16(source_id), + blink::WebMediaStreamSource::TypeVideo, + base::UTF8ToUTF16(kPepperVideoSourceName)); + webkit_source.setExtraData(this); + + const bool enabled = true; + blink::WebMediaConstraints constraints; + constraints.initialize(); + track_ = MediaStreamVideoTrack::CreateVideoTrack( + this, constraints, + base::Bind( + &PepperMediaStreamVideoTrackHost::OnTrackStarted, + base::Unretained(this)), + enabled); +} + +void PepperMediaStreamVideoTrackHost::OnTrackStarted( + MediaStreamSource* source, bool success) { + DVLOG(3) << "OnTrackStarted result: " << success; +} + } // namespace content diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.h b/content/renderer/pepper/pepper_media_stream_video_track_host.h index 521b7ab..0b8218d 100644 --- a/content/renderer/pepper/pepper_media_stream_video_track_host.h +++ b/content/renderer/pepper/pepper_media_stream_video_track_host.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "content/public/renderer/media_stream_video_sink.h" +#include "content/renderer/media/media_stream_video_source.h" #include "content/renderer/pepper/pepper_media_stream_track_host_base.h" #include "media/base/video_frame.h" #include "ppapi/c/ppb_video_frame.h" @@ -17,25 +18,54 @@ namespace content { class PepperMediaStreamVideoTrackHost : public PepperMediaStreamTrackHostBase, - public MediaStreamVideoSink { + public MediaStreamVideoSink, + public MediaStreamVideoSource { public: + // Input mode constructor. + // In input mode, this class passes video frames from |track| to the + // associated pepper plugin. PepperMediaStreamVideoTrackHost(RendererPpapiHost* host, PP_Instance instance, PP_Resource resource, const blink::WebMediaStreamTrack& track); + // Output mode constructor. + // In output mode, this class passes video frames from the associated + // pepper plugin to a newly created blink::WebMediaStreamTrack. + PepperMediaStreamVideoTrackHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + + virtual bool IsMediaStreamVideoTrackHost() OVERRIDE; + + blink::WebMediaStreamTrack track() { return track_; } + private: + virtual ~PepperMediaStreamVideoTrackHost(); void InitBuffers(); // PepperMediaStreamTrackHostBase overrides: virtual void OnClose() OVERRIDE; + virtual int32_t OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index) OVERRIDE; + + // Sends frame with |index| to |track_|. + int32_t SendFrameToTrack(int32_t index); // MediaStreamVideoSink overrides: virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame) OVERRIDE; + // MediaStreamVideoSource overrides: + virtual void GetCurrentSupportedFormats(int max_requested_width, + int max_requested_height) OVERRIDE; + virtual void StartSourceImpl( + const media::VideoCaptureParams& params) OVERRIDE; + + virtual void StopSourceImpl() OVERRIDE; + // ResourceHost overrides: virtual void DidConnectPendingHostToResource() OVERRIDE; @@ -49,6 +79,9 @@ class PepperMediaStreamVideoTrackHost : public PepperMediaStreamTrackHostBase, ppapi::host::HostMessageContext* context, const ppapi::MediaStreamVideoTrackShared::Attributes& attributes); + void InitBlinkTrack(); + void OnTrackStarted(MediaStreamSource* source, bool success); + blink::WebMediaStreamTrack track_; // True if it has been added to |blink::WebMediaStreamTrack| as a sink. @@ -72,6 +105,11 @@ class PepperMediaStreamVideoTrackHost : public PepperMediaStreamTrackHostBase, // The size of frame pixels in bytes. uint32_t frame_data_size_; + // TODO(ronghuawu): Remove |type_| and split PepperMediaStreamVideoTrackHost + // into 2 classes for read and write. + TrackType type_; + bool output_started_; + DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamVideoTrackHost); }; diff --git a/content/renderer/pepper/resource_converter.cc b/content/renderer/pepper/resource_converter.cc index 5fef938..62164cf 100644 --- a/content/renderer/pepper/resource_converter.cc +++ b/content/renderer/pepper/resource_converter.cc @@ -18,6 +18,7 @@ #include "ppapi/shared_impl/scoped_pp_var.h" #include "third_party/WebKit/public/platform/WebFileSystem.h" #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/WebKit/public/web/WebDOMFileSystem.h" #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -144,6 +145,16 @@ bool ResourceHostToDOMFileSystem( return true; } +bool ResourceHostToDOMMediaStreamVideoTrack( + content::PepperMediaStreamVideoTrackHost* host, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* dom_video_track) { + // TODO(ronghuawu): Implement this once crbug/352219 is resolved. + // blink::WebMediaStreamTrack track = host->track(); + // *dom_video_track = track.toV8Value(); + return false; +} + bool DOMMediaStreamTrackToResource( PP_Instance instance, RendererPpapiHost* host, @@ -299,6 +310,11 @@ bool ResourceConverterImpl::ToV8Value(const PP_Var& var, static_cast<content::PepperFileSystemHost*>(resource_host), context, result); + } else if (resource_host->IsMediaStreamVideoTrackHost()) { + return ResourceHostToDOMMediaStreamVideoTrack( + static_cast<content::PepperMediaStreamVideoTrackHost*>(resource_host), + context, + result); } else { LOG(ERROR) << "The type of resource #" << resource_id << " cannot be converted to a JavaScript object."; diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc index 1a698b1..cd282e6 100644 --- a/content/renderer/pepper/resource_creation_impl.cc +++ b/content/renderer/pepper/resource_creation_impl.cc @@ -195,6 +195,11 @@ PP_Resource ResourceCreationImpl::CreateKeyboardInputEvent_1_2( code); } +PP_Resource ResourceCreationImpl::CreateMediaStreamVideoTrack( + PP_Instance instance) { + return 0; // Not supported in-process. +} + PP_Resource ResourceCreationImpl::CreateMouseInputEvent( PP_Instance instance, PP_InputEvent_Type type, @@ -233,14 +238,6 @@ PP_Resource ResourceCreationImpl::CreateNetAddressFromNetAddressPrivate( return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateTouchInputEvent(PP_Instance instance, - PP_InputEvent_Type type, - PP_TimeTicks time_stamp, - uint32_t modifiers) { - return PPB_InputEvent_Shared::CreateTouchInputEvent( - ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers); -} - PP_Resource ResourceCreationImpl::CreateNetworkMonitor(PP_Instance instance) { return 0; // Not supported in-process. } @@ -281,6 +278,14 @@ PP_Resource ResourceCreationImpl::CreateTCPSocketPrivate(PP_Instance instance) { return 0; // Not supported in-process. } +PP_Resource ResourceCreationImpl::CreateTouchInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers) { + return PPB_InputEvent_Shared::CreateTouchInputEvent( + ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers); +} + PP_Resource ResourceCreationImpl::CreateUDPSocket(PP_Instance instance) { return 0; // Not supported in-process. } diff --git a/content/renderer/pepper/resource_creation_impl.h b/content/renderer/pepper/resource_creation_impl.h index 55a0d7c..6bf268d 100644 --- a/content/renderer/pepper/resource_creation_impl.h +++ b/content/renderer/pepper/resource_creation_impl.h @@ -86,6 +86,8 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { uint32_t key_code, PP_Var character_text, PP_Var code) OVERRIDE; + virtual PP_Resource CreateMediaStreamVideoTrack( + PP_Instance instance) OVERRIDE; virtual PP_Resource CreateMouseInputEvent( PP_Instance instance, PP_InputEvent_Type type, @@ -104,10 +106,6 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { virtual PP_Resource CreateNetAddressFromNetAddressPrivate( PP_Instance instance, const PP_NetAddress_Private& private_addr) OVERRIDE; - virtual PP_Resource CreateTouchInputEvent(PP_Instance instance, - PP_InputEvent_Type type, - PP_TimeTicks time_stamp, - uint32_t modifiers) OVERRIDE; virtual PP_Resource CreateNetworkMonitor(PP_Instance instance) OVERRIDE; virtual PP_Resource CreatePlatformVerificationPrivate(PP_Instance instance) OVERRIDE; @@ -121,6 +119,10 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { virtual PP_Resource CreateTCPSocket1_0(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateTCPSocket(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateTouchInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers) OVERRIDE; virtual PP_Resource CreateUDPSocket(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE; diff --git a/mojo/examples/pepper_container_app/resource_creation_impl.cc b/mojo/examples/pepper_container_app/resource_creation_impl.cc index cfb0679..8867b2c 100644 --- a/mojo/examples/pepper_container_app/resource_creation_impl.cc +++ b/mojo/examples/pepper_container_app/resource_creation_impl.cc @@ -211,6 +211,12 @@ PP_Resource ResourceCreationImpl::CreateImageDataSimple( return 0; } +PP_Resource ResourceCreationImpl::CreateMediaStreamVideoTrack( + PP_Instance instance) { + NOTIMPLEMENTED(); + return 0; +} + PP_Resource ResourceCreationImpl::CreateNetAddressFromIPv4Address( PP_Instance instance, const PP_NetAddress_IPv4* ipv4_addr) { diff --git a/mojo/examples/pepper_container_app/resource_creation_impl.h b/mojo/examples/pepper_container_app/resource_creation_impl.h index de1760e..925507a 100644 --- a/mojo/examples/pepper_container_app/resource_creation_impl.h +++ b/mojo/examples/pepper_container_app/resource_creation_impl.h @@ -111,6 +111,8 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { PP_ImageDataFormat format, const PP_Size* size, PP_Bool init_to_zero) OVERRIDE; + virtual PP_Resource CreateMediaStreamVideoTrack( + PP_Instance instance) OVERRIDE; virtual PP_Resource CreateNetAddressFromIPv4Address( PP_Instance instance, const PP_NetAddress_IPv4* ipv4_addr) OVERRIDE; diff --git a/ppapi/api/ppb_media_stream_video_track.idl b/ppapi/api/ppb_media_stream_video_track.idl index 91e95026..2cf8530 100644 --- a/ppapi/api/ppb_media_stream_video_track.idl +++ b/ppapi/api/ppb_media_stream_video_track.idl @@ -12,7 +12,8 @@ label Chrome { [channel=dev] M34 = 0.1, - M35 = 0.1 + M35 = 0.1, + [channel=dev] M36 = 1.0 }; /** @@ -74,6 +75,19 @@ enum PP_MediaStreamVideoTrack_Attrib { [version=0.1] interface PPB_MediaStreamVideoTrack { /** + * Creates a PPB_MediaStreamVideoTrack resource for video output. Call this + * when you will be creating frames and putting them to the track. + * + * @param[in] instance A <code>PP_Instance</code> identifying one instance of + * a module. + * + * @return A <code>PP_Resource</code> corresponding to a + * PPB_MediaStreamVideoTrack resource if successful, 0 if failed. + */ + [version=1.0] + PP_Resource Create([in] PP_Instance instance); + + /** * Determines if a resource is a MediaStream video track resource. * * @param[in] resource The <code>PP_Resource</code> to test. @@ -211,5 +225,23 @@ interface PPB_MediaStreamVideoTrack { * MediaStream video track resource. */ void Close([in] PP_Resource video_track); + + /** + * Gets a free frame for output. The frame is allocated by + * <code>Configure()</code>. The caller should fill it with frame data, and + * then use |PutFrame()| to send the frame back. + */ + [version=1.0] + int32_t GetEmptyFrame([in] PP_Resource video_track, + [out] PP_Resource frame, + [in] PP_CompletionCallback callback); + + /** + * Sends a frame returned by |GetEmptyFrame()| to the output track. + * After this function, the |frame| should not be used anymore and the + * caller should release the reference that it holds. + */ + [version=1.0] + int32_t PutFrame([in] PP_Resource video_track, [in] PP_Resource frame); }; diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h index 61be3d0..ae27731 100644 --- a/ppapi/c/pp_macros.h +++ b/ppapi/c/pp_macros.h @@ -3,13 +3,13 @@ * found in the LICENSE file. */ -/* From pp_macros.idl modified Wed Feb 26 15:01:03 2014. */ +/* From pp_macros.idl modified Thu Jan 23 14:14:38 2014. */ #ifndef PPAPI_C_PP_MACROS_H_ #define PPAPI_C_PP_MACROS_H_ -#define PPAPI_RELEASE 35 +#define PPAPI_RELEASE 36 /** * @file diff --git a/ppapi/c/ppb_media_stream_video_track.h b/ppapi/c/ppb_media_stream_video_track.h index 1580041..31c7a80 100644 --- a/ppapi/c/ppb_media_stream_video_track.h +++ b/ppapi/c/ppb_media_stream_video_track.h @@ -3,19 +3,22 @@ * found in the LICENSE file. */ -/* From ppb_media_stream_video_track.idl modified Fri Mar 28 10:13:52 2014. */ +/* From ppb_media_stream_video_track.idl modified Mon Apr 7 15:25:56 2014. */ #ifndef PPAPI_C_PPB_MEDIA_STREAM_VIDEO_TRACK_H_ #define PPAPI_C_PPB_MEDIA_STREAM_VIDEO_TRACK_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_var.h" #define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1 "PPB_MediaStreamVideoTrack;0.1" +#define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0 \ + "PPB_MediaStreamVideoTrack;1.0" /* dev */ #define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE \ PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1 @@ -89,7 +92,18 @@ typedef enum { * @addtogroup Interfaces * @{ */ -struct PPB_MediaStreamVideoTrack_0_1 { +struct PPB_MediaStreamVideoTrack_1_0 { /* dev */ + /** + * Creates a PPB_MediaStreamVideoTrack resource for video output. Call this + * when you will be creating frames and putting them to the track. + * + * @param[in] instance A <code>PP_Instance</code> identifying one instance of + * a module. + * + * @return A <code>PP_Resource</code> corresponding to a + * PPB_MediaStreamVideoTrack resource if successful, 0 if failed. + */ + PP_Resource (*Create)(PP_Instance instance); /** * Determines if a resource is a MediaStream video track resource. * @@ -219,6 +233,37 @@ struct PPB_MediaStreamVideoTrack_0_1 { * MediaStream video track resource. */ void (*Close)(PP_Resource video_track); + /** + * Gets a free frame for output. The frame is allocated by + * <code>Configure()</code>. The caller should fill it with frame data, and + * then use |PutFrame()| to send the frame back. + */ + int32_t (*GetEmptyFrame)(PP_Resource video_track, + PP_Resource* frame, + struct PP_CompletionCallback callback); + /** + * Sends a frame returned by |GetEmptyFrame()| to the output track. + * After this function, the |frame| should not be used anymore and the + * caller should release the reference that it holds. + */ + int32_t (*PutFrame)(PP_Resource video_track, PP_Resource frame); +}; + +struct PPB_MediaStreamVideoTrack_0_1 { + PP_Bool (*IsMediaStreamVideoTrack)(PP_Resource resource); + int32_t (*Configure)(PP_Resource video_track, + const int32_t attrib_list[], + struct PP_CompletionCallback callback); + int32_t (*GetAttrib)(PP_Resource video_track, + PP_MediaStreamVideoTrack_Attrib attrib, + int32_t* value); + struct PP_Var (*GetId)(PP_Resource video_track); + PP_Bool (*HasEnded)(PP_Resource video_track); + int32_t (*GetFrame)(PP_Resource video_track, + PP_Resource* frame, + struct PP_CompletionCallback callback); + int32_t (*RecycleFrame)(PP_Resource video_track, PP_Resource frame); + void (*Close)(PP_Resource video_track); }; typedef struct PPB_MediaStreamVideoTrack_0_1 PPB_MediaStreamVideoTrack; diff --git a/ppapi/cpp/media_stream_video_track.cc b/ppapi/cpp/media_stream_video_track.cc index 38065a3..47ff140 100644 --- a/ppapi/cpp/media_stream_video_track.cc +++ b/ppapi/cpp/media_stream_video_track.cc @@ -15,6 +15,10 @@ namespace pp { namespace { +template <> const char* interface_name<PPB_MediaStreamVideoTrack_1_0>() { + return PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0; +} + template <> const char* interface_name<PPB_MediaStreamVideoTrack_0_1>() { return PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1; } @@ -33,6 +37,16 @@ MediaStreamVideoTrack::MediaStreamVideoTrack(const Resource& resource) PP_DCHECK(IsMediaStreamVideoTrack(resource)); } +MediaStreamVideoTrack::MediaStreamVideoTrack(const InstanceHandle& instance) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + PassRefFromConstructor( + get_interface<PPB_MediaStreamVideoTrack_1_0>()->Create( + instance.pp_instance())); + return; + } + PP_DCHECK(false); +} + MediaStreamVideoTrack::MediaStreamVideoTrack(PassRef, PP_Resource resource) : Resource(PASS_REF, resource) { } @@ -43,7 +57,10 @@ MediaStreamVideoTrack::~MediaStreamVideoTrack() { int32_t MediaStreamVideoTrack::Configure( const int32_t attributes[], const CompletionCallback& callback) { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->Configure( + pp_resource(), attributes, callback.pp_completion_callback()); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return get_interface<PPB_MediaStreamVideoTrack_0_1>()->Configure( pp_resource(), attributes, callback.pp_completion_callback()); } @@ -52,7 +69,10 @@ int32_t MediaStreamVideoTrack::Configure( int32_t MediaStreamVideoTrack::GetAttrib(PP_MediaStreamVideoTrack_Attrib attrib, int32_t* value) { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetAttrib( + pp_resource(), attrib, value); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetAttrib( pp_resource(), attrib, value); } @@ -60,7 +80,12 @@ int32_t MediaStreamVideoTrack::GetAttrib(PP_MediaStreamVideoTrack_Attrib attrib, } std::string MediaStreamVideoTrack::GetId() const { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + pp::Var id(PASS_REF, get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetId( + pp_resource())); + if (id.is_string()) + return id.AsString(); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { pp::Var id(PASS_REF, get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetId( pp_resource())); if (id.is_string()) @@ -70,7 +95,10 @@ std::string MediaStreamVideoTrack::GetId() const { } bool MediaStreamVideoTrack::HasEnded() const { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_1_0>()->HasEnded( + pp_resource())); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_0_1>()->HasEnded( pp_resource())); } @@ -79,7 +107,10 @@ bool MediaStreamVideoTrack::HasEnded() const { int32_t MediaStreamVideoTrack::GetFrame( const CompletionCallbackWithOutput<VideoFrame>& callback) { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetFrame( + pp_resource(), callback.output(), callback.pp_completion_callback()); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetFrame( pp_resource(), callback.output(), callback.pp_completion_callback()); } @@ -87,7 +118,10 @@ int32_t MediaStreamVideoTrack::GetFrame( } int32_t MediaStreamVideoTrack::RecycleFrame(const VideoFrame& frame) { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->RecycleFrame( + pp_resource(), frame.pp_resource()); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return get_interface<PPB_MediaStreamVideoTrack_0_1>()->RecycleFrame( pp_resource(), frame.pp_resource()); } @@ -95,12 +129,35 @@ int32_t MediaStreamVideoTrack::RecycleFrame(const VideoFrame& frame) { } void MediaStreamVideoTrack::Close() { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) + get_interface<PPB_MediaStreamVideoTrack_1_0>()->Close(pp_resource()); + else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) get_interface<PPB_MediaStreamVideoTrack_0_1>()->Close(pp_resource()); + +} + +int32_t MediaStreamVideoTrack::GetEmptyFrame( + const CompletionCallbackWithOutput<VideoFrame>& callback) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetEmptyFrame( + pp_resource(), callback.output(), callback.pp_completion_callback()); + } + return callback.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t MediaStreamVideoTrack::PutFrame(const VideoFrame& frame) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return get_interface<PPB_MediaStreamVideoTrack_1_0>()->PutFrame( + pp_resource(), frame.pp_resource()); + } + return PP_ERROR_NOINTERFACE; } bool MediaStreamVideoTrack::IsMediaStreamVideoTrack(const Resource& resource) { - if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { + if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) { + return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_1_0>()-> + IsMediaStreamVideoTrack(resource.pp_resource())); + } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) { return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_0_1>()-> IsMediaStreamVideoTrack(resource.pp_resource())); } diff --git a/ppapi/cpp/media_stream_video_track.h b/ppapi/cpp/media_stream_video_track.h index 6975986..5d03745 100644 --- a/ppapi/cpp/media_stream_video_track.h +++ b/ppapi/cpp/media_stream_video_track.h @@ -41,6 +41,10 @@ class MediaStreamVideoTrack : public Resource { /// @param[in] resource A <code>PPB_MediaStreamVideoTrack</code> resource. explicit MediaStreamVideoTrack(const Resource& resource); + /// Constructs a <code>MediaStreamVideoTrack</code> that outputs given frames + /// to a new video track, which will be consumed by Javascript. + explicit MediaStreamVideoTrack(const InstanceHandle& instance); + /// A constructor used when you have received a <code>PP_Resource</code> as a /// return value that has had 1 ref added for you. /// @@ -134,6 +138,17 @@ class MediaStreamVideoTrack : public Resource { /// After calling <code>Close()</code>, no new frames will be received. void Close(); + // Gets a free frame for output. The frame is allocated by + // <code>Configure()</code>. The caller should fill it with frame data, and + // then use |PutFrame()| to send the frame back. + int32_t GetEmptyFrame( + const CompletionCallbackWithOutput<VideoFrame>& callback); + + // Sends a frame returned by |GetEmptyFrame()| to the output track. + // After this function, the |frame| should not be used anymore and the + // caller should release the reference that it holds. + int32_t PutFrame(const VideoFrame& frame); + /// Checks whether a <code>Resource</code> is a MediaStream video track, /// to test whether it is appropriate for use with the /// <code>MediaStreamVideoTrack</code> constructor. diff --git a/ppapi/host/resource_host.cc b/ppapi/host/resource_host.cc index 4e12260..b453398 100644 --- a/ppapi/host/resource_host.cc +++ b/ppapi/host/resource_host.cc @@ -56,6 +56,10 @@ bool ResourceHost::IsFileSystemHost() { return false; } +bool ResourceHost::IsMediaStreamVideoTrackHost() { + return false; +} + bool ResourceHost::IsGraphics2DHost() { return false; } diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h index 37ccbed..a9518ee 100644 --- a/ppapi/host/resource_host.h +++ b/ppapi/host/resource_host.h @@ -59,6 +59,7 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler { virtual bool IsFileRefHost(); virtual bool IsFileSystemHost(); virtual bool IsGraphics2DHost(); + virtual bool IsMediaStreamVideoTrackHost(); protected: // Adds a ResourceMessageFilter to handle resource messages. Incoming diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 4713148..a94e0df 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -115,6 +115,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TouchInputEvent_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_IMEInputEvent_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamAudioTrack_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_0_1; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MessageLoop_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Messaging_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MouseLock_1_0; @@ -1075,6 +1076,65 @@ static void Pnacl_M35_PPB_MediaStreamVideoTrack_Close(PP_Resource video_track) { /* End wrapper methods for PPB_MediaStreamVideoTrack_0_1 */ +/* Begin wrapper methods for PPB_MediaStreamVideoTrack_1_0 */ + +static PP_Resource Pnacl_M36_PPB_MediaStreamVideoTrack_Create(PP_Instance instance) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->Create(instance); +} + +static PP_Bool Pnacl_M36_PPB_MediaStreamVideoTrack_IsMediaStreamVideoTrack(PP_Resource resource) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->IsMediaStreamVideoTrack(resource); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_Configure(PP_Resource video_track, const int32_t attrib_list[], struct PP_CompletionCallback* callback) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->Configure(video_track, attrib_list, *callback); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetAttrib(PP_Resource video_track, PP_MediaStreamVideoTrack_Attrib attrib, int32_t* value) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->GetAttrib(video_track, attrib, value); +} + +static void Pnacl_M36_PPB_MediaStreamVideoTrack_GetId(struct PP_Var* _struct_result, PP_Resource video_track) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + *_struct_result = iface->GetId(video_track); +} + +static PP_Bool Pnacl_M36_PPB_MediaStreamVideoTrack_HasEnded(PP_Resource video_track) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->HasEnded(video_track); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetFrame(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback* callback) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->GetFrame(video_track, frame, *callback); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_RecycleFrame(PP_Resource video_track, PP_Resource frame) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->RecycleFrame(video_track, frame); +} + +static void Pnacl_M36_PPB_MediaStreamVideoTrack_Close(PP_Resource video_track) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + iface->Close(video_track); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetEmptyFrame(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback* callback) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->GetEmptyFrame(video_track, frame, *callback); +} + +static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_PutFrame(PP_Resource video_track, PP_Resource frame) { + const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface; + return iface->PutFrame(video_track, frame); +} + +/* End wrapper methods for PPB_MediaStreamVideoTrack_1_0 */ + /* Begin wrapper methods for PPB_MessageLoop_1_0 */ static PP_Resource Pnacl_M25_PPB_MessageLoop_Create(PP_Instance instance) { @@ -4375,6 +4435,20 @@ static const struct PPB_MediaStreamVideoTrack_0_1 Pnacl_Wrappers_PPB_MediaStream .Close = (void (*)(PP_Resource video_track))&Pnacl_M35_PPB_MediaStreamVideoTrack_Close }; +static const struct PPB_MediaStreamVideoTrack_1_0 Pnacl_Wrappers_PPB_MediaStreamVideoTrack_1_0 = { + .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M36_PPB_MediaStreamVideoTrack_Create, + .IsMediaStreamVideoTrack = (PP_Bool (*)(PP_Resource resource))&Pnacl_M36_PPB_MediaStreamVideoTrack_IsMediaStreamVideoTrack, + .Configure = (int32_t (*)(PP_Resource video_track, const int32_t attrib_list[], struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_Configure, + .GetAttrib = (int32_t (*)(PP_Resource video_track, PP_MediaStreamVideoTrack_Attrib attrib, int32_t* value))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetAttrib, + .GetId = (struct PP_Var (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetId, + .HasEnded = (PP_Bool (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_HasEnded, + .GetFrame = (int32_t (*)(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetFrame, + .RecycleFrame = (int32_t (*)(PP_Resource video_track, PP_Resource frame))&Pnacl_M36_PPB_MediaStreamVideoTrack_RecycleFrame, + .Close = (void (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_Close, + .GetEmptyFrame = (int32_t (*)(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetEmptyFrame, + .PutFrame = (int32_t (*)(PP_Resource video_track, PP_Resource frame))&Pnacl_M36_PPB_MediaStreamVideoTrack_PutFrame +}; + static const struct PPB_MessageLoop_1_0 Pnacl_Wrappers_PPB_MessageLoop_1_0 = { .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M25_PPB_MessageLoop_Create, .GetForMainThread = (PP_Resource (*)(void))&Pnacl_M25_PPB_MessageLoop_GetForMainThread, @@ -5367,6 +5441,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_0_1 .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0 = { + .iface_macro = PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0, + .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_MediaStreamVideoTrack_1_0, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MessageLoop_1_0 = { .iface_macro = PPB_MESSAGELOOP_INTERFACE_1_0, .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_MessageLoop_1_0, @@ -5870,6 +5950,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_IMEInputEvent_1_0, &Pnacl_WrapperInfo_PPB_MediaStreamAudioTrack_0_1, &Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_0_1, + &Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0, &Pnacl_WrapperInfo_PPB_MessageLoop_1_0, &Pnacl_WrapperInfo_PPB_Messaging_1_0, &Pnacl_WrapperInfo_PPB_MouseLock_1_0, diff --git a/ppapi/proxy/media_stream_track_resource_base.cc b/ppapi/proxy/media_stream_track_resource_base.cc index d259036..4431da3 100644 --- a/ppapi/proxy/media_stream_track_resource_base.cc +++ b/ppapi/proxy/media_stream_track_resource_base.cc @@ -22,6 +22,14 @@ MediaStreamTrackResourceBase::MediaStreamTrackResourceBase( AttachToPendingHost(RENDERER, pending_renderer_id); } +MediaStreamTrackResourceBase::MediaStreamTrackResourceBase( + Connection connection, + PP_Instance instance) + : PluginResource(connection, instance), + buffer_manager_(this), + has_ended_(false) { +} + MediaStreamTrackResourceBase::~MediaStreamTrackResourceBase() { } @@ -40,6 +48,9 @@ void MediaStreamTrackResourceBase::OnReplyReceived( PpapiPluginMsg_MediaStreamTrack_InitBuffers, OnPluginMsgInitBuffers) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer, OnPluginMsgEnqueueBuffer) + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( + PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers, + OnPluginMsgEnqueueBuffers) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED( PluginResource::OnReplyReceived(params, msg)) IPC_END_MESSAGE_MAP() @@ -55,11 +66,13 @@ void MediaStreamTrackResourceBase::CloseInternal() { void MediaStreamTrackResourceBase::OnPluginMsgInitBuffers( const ResourceMessageReplyParams& params, int32_t number_of_buffers, - int32_t buffer_size) { + int32_t buffer_size, + bool readonly) { base::SharedMemoryHandle shm_handle = base::SharedMemory::NULLHandle(); params.TakeSharedMemoryHandleAtIndex(0, &shm_handle); buffer_manager_.SetBuffers(number_of_buffers, buffer_size, - scoped_ptr<base::SharedMemory>(new base::SharedMemory(shm_handle, true)), + scoped_ptr<base::SharedMemory>(new base::SharedMemory(shm_handle, + readonly)), false); } @@ -69,5 +82,12 @@ void MediaStreamTrackResourceBase::OnPluginMsgEnqueueBuffer( buffer_manager_.EnqueueBuffer(index); } +void MediaStreamTrackResourceBase::OnPluginMsgEnqueueBuffers( + const ResourceMessageReplyParams& params, + const std::vector<int32_t>& indices) { + for (size_t i = 0; i < indices.size(); ++i) + buffer_manager_.EnqueueBuffer(indices[i]); +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/media_stream_track_resource_base.h b/ppapi/proxy/media_stream_track_resource_base.h index b5438ce..087d4a95 100644 --- a/ppapi/proxy/media_stream_track_resource_base.h +++ b/ppapi/proxy/media_stream_track_resource_base.h @@ -21,10 +21,14 @@ class PPAPI_PROXY_EXPORT MediaStreamTrackResourceBase int pending_renderer_id, const std::string& id); + MediaStreamTrackResourceBase(Connection connection, PP_Instance instance); + virtual ~MediaStreamTrackResourceBase(); std::string id() const { return id_; } + void set_id(const std::string& id) { id_ = id; } + bool has_ended() const { return has_ended_; } MediaStreamBufferManager* buffer_manager() { return &buffer_manager_; } @@ -45,9 +49,12 @@ class PPAPI_PROXY_EXPORT MediaStreamTrackResourceBase // Message handlers: void OnPluginMsgInitBuffers(const ResourceMessageReplyParams& params, int32_t number_of_buffers, - int32_t buffer_size); + int32_t buffer_size, + bool readonly); void OnPluginMsgEnqueueBuffer(const ResourceMessageReplyParams& params, int32_t index); + void OnPluginMsgEnqueueBuffers(const ResourceMessageReplyParams& params, + const std::vector<int32_t>& indices); MediaStreamBufferManager buffer_manager_; diff --git a/ppapi/proxy/media_stream_video_track_resource.cc b/ppapi/proxy/media_stream_video_track_resource.cc index aaa5b52..fc602311 100644 --- a/ppapi/proxy/media_stream_video_track_resource.cc +++ b/ppapi/proxy/media_stream_video_track_resource.cc @@ -24,6 +24,14 @@ MediaStreamVideoTrackResource::MediaStreamVideoTrackResource( get_frame_output_(NULL) { } +MediaStreamVideoTrackResource::MediaStreamVideoTrackResource( + Connection connection, + PP_Instance instance) + : MediaStreamTrackResourceBase(connection, instance), + get_frame_output_(NULL) { + SendCreate(RENDERER, PpapiHostMsg_MediaStreamVideoTrack_Create()); +} + MediaStreamVideoTrackResource::~MediaStreamVideoTrackResource() { Close(); } @@ -150,6 +158,17 @@ void MediaStreamVideoTrackResource::Close() { MediaStreamTrackResourceBase::CloseInternal(); } +int32_t MediaStreamVideoTrackResource::GetEmptyFrame( + PP_Resource* frame, scoped_refptr<TrackedCallback> callback) { + return GetFrame(frame, callback); +} + +int32_t MediaStreamVideoTrackResource::PutFrame(PP_Resource frame) { + // TODO(ronghuawu): Consider to rename RecycleFrame to PutFrame and use + // one set of GetFrame and PutFrame for both input and output. + return RecycleFrame(frame); +} + void MediaStreamVideoTrackResource::OnNewBufferEnqueued() { if (!TrackedCallback::IsPending(get_frame_callback_)) return; @@ -189,7 +208,13 @@ void MediaStreamVideoTrackResource::ReleaseFrames() { } void MediaStreamVideoTrackResource::OnPluginMsgConfigureReply( - const ResourceMessageReplyParams& params) { + const ResourceMessageReplyParams& params, + const std::string& track_id) { + if (id().empty()) { + set_id(track_id); + } else { + DCHECK_EQ(id(), track_id); + } if (TrackedCallback::IsPending(configure_callback_)) { scoped_refptr<TrackedCallback> callback; callback.swap(configure_callback_); diff --git a/ppapi/proxy/media_stream_video_track_resource.h b/ppapi/proxy/media_stream_video_track_resource.h index d1b3bb5..1e9927f 100644 --- a/ppapi/proxy/media_stream_video_track_resource.h +++ b/ppapi/proxy/media_stream_video_track_resource.h @@ -26,6 +26,8 @@ class PPAPI_PROXY_EXPORT MediaStreamVideoTrackResource int pending_renderer_id, const std::string& id); + MediaStreamVideoTrackResource(Connection connection, PP_Instance instance); + virtual ~MediaStreamVideoTrackResource(); // Resource overrides: @@ -43,6 +45,9 @@ class PPAPI_PROXY_EXPORT MediaStreamVideoTrackResource scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual int32_t RecycleFrame(PP_Resource frame) OVERRIDE; virtual void Close() OVERRIDE; + virtual int32_t GetEmptyFrame( + PP_Resource* frame, scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t PutFrame(PP_Resource frame) OVERRIDE; // MediaStreamBufferManager::Delegate overrides: virtual void OnNewBufferEnqueued() OVERRIDE; @@ -53,7 +58,8 @@ class PPAPI_PROXY_EXPORT MediaStreamVideoTrackResource void ReleaseFrames(); // IPC message handlers. - void OnPluginMsgConfigureReply(const ResourceMessageReplyParams& params); + void OnPluginMsgConfigureReply(const ResourceMessageReplyParams& params, + const std::string& track_id); // Allocated frame resources by |GetFrame()|. typedef std::map<PP_Resource, scoped_refptr<VideoFrameResource> > FrameMap; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 5fe5e968..95ac3d9 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1438,20 +1438,25 @@ IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost, std::string /* track_id */) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost, std::string /* track_id */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_MediaStreamVideoTrack_Create) IPC_MESSAGE_CONTROL1( PpapiHostMsg_MediaStreamVideoTrack_Configure, ppapi::MediaStreamVideoTrackShared::Attributes /* attributes */) -IPC_MESSAGE_CONTROL0(PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply, + std::string /* track_id */) // Message for init buffers. It also takes a shared memory handle which is put // in the outer ResourceReplyMessage. -IPC_MESSAGE_CONTROL2(PpapiPluginMsg_MediaStreamTrack_InitBuffers, +IPC_MESSAGE_CONTROL3(PpapiPluginMsg_MediaStreamTrack_InitBuffers, int32_t /* number_of_buffers */, - int32_t /* buffer_size */) + int32_t /* buffer_size */, + bool /* readonly */) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer, int32_t /* index */); IPC_MESSAGE_CONTROL1(PpapiHostMsg_MediaStreamTrack_EnqueueBuffer, int32_t /* index */); +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers, + std::vector<int32_t> /* indices */); IPC_MESSAGE_CONTROL0(PpapiHostMsg_MediaStreamTrack_Close) // NetworkMonitor. diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index a4dbeec..0289e99 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -18,6 +18,7 @@ #include "ppapi/proxy/graphics_2d_resource.h" #include "ppapi/proxy/host_resolver_private_resource.h" #include "ppapi/proxy/host_resolver_resource.h" +#include "ppapi/proxy/media_stream_video_track_resource.h" #include "ppapi/proxy/net_address_resource.h" #include "ppapi/proxy/network_monitor_resource.h" #include "ppapi/proxy/output_protection_resource.h" @@ -290,6 +291,12 @@ PP_Resource ResourceCreationProxy::CreateImageDataSimple( format, *size, init_to_zero); } +PP_Resource ResourceCreationProxy::CreateMediaStreamVideoTrack( + PP_Instance instance) { + return (new MediaStreamVideoTrackResource(GetConnection(), + instance))->GetReference(); +} + PP_Resource ResourceCreationProxy::CreateNetAddressFromIPv4Address( PP_Instance instance, const PP_NetAddress_IPv4* ipv4_addr) { diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 4719c4a..49314fd 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -129,6 +129,8 @@ class ResourceCreationProxy : public InterfaceProxy, PP_ImageDataFormat format, const PP_Size* size, PP_Bool init_to_zero) OVERRIDE; + virtual PP_Resource CreateMediaStreamVideoTrack( + PP_Instance instance) OVERRIDE; virtual PP_Resource CreateNetAddressFromIPv4Address( PP_Instance instance, const PP_NetAddress_IPv4* ipv4_addr) OVERRIDE; diff --git a/ppapi/shared_impl/media_stream_buffer_manager.cc b/ppapi/shared_impl/media_stream_buffer_manager.cc index d6c4b0d..29bc153 100644 --- a/ppapi/shared_impl/media_stream_buffer_manager.cc +++ b/ppapi/shared_impl/media_stream_buffer_manager.cc @@ -59,6 +59,12 @@ int32_t MediaStreamBufferManager::DequeueBuffer() { return buffer; } +std::vector<int32_t> MediaStreamBufferManager::DequeueBuffers() { + std::vector<int32_t> buffers(buffer_queue_.begin(), buffer_queue_.end()); + buffer_queue_.clear(); + return buffers; +} + void MediaStreamBufferManager::EnqueueBuffer(int32_t index) { CHECK_GE(index, 0) << "Invalid buffer index"; CHECK_LT(index, number_of_buffers_) << "Invalid buffer index"; @@ -66,10 +72,9 @@ void MediaStreamBufferManager::EnqueueBuffer(int32_t index) { delegate_->OnNewBufferEnqueued(); } -MediaStreamBuffer* MediaStreamBufferManager::GetBufferPointer( - int32_t index) { - CHECK_GE(index, 0) << "Invalid buffer index"; - CHECK_LT(index, number_of_buffers_) << "Invalid buffer index"; +MediaStreamBuffer* MediaStreamBufferManager::GetBufferPointer(int32_t index) { + if (index < 0 || index >= number_of_buffers_) + return NULL; return buffers_[index]; } diff --git a/ppapi/shared_impl/media_stream_buffer_manager.h b/ppapi/shared_impl/media_stream_buffer_manager.h index 240be5d..eafd10c 100644 --- a/ppapi/shared_impl/media_stream_buffer_manager.h +++ b/ppapi/shared_impl/media_stream_buffer_manager.h @@ -62,6 +62,9 @@ class PPAPI_SHARED_EXPORT MediaStreamBufferManager { // Dequeues a buffer from |buffer_queue_|. int32_t DequeueBuffer(); + // Dequeues all the buffers from |buffer_queue_|. + std::vector<int32_t> DequeueBuffers(); + // Puts a buffer into |buffer_queue_|. void EnqueueBuffer(int32_t index); diff --git a/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc b/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc index 8370567..9374875 100644 --- a/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc +++ b/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc @@ -79,11 +79,9 @@ TEST(MediaStreamBufferManager, General) { EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer()); EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer()); - // Test crash for passing invalid index to GetBufferPointer() - EXPECT_DEATH(manager.GetBufferPointer(-1), - ".*Check failed: index >= 0.*"); - EXPECT_DEATH(manager.GetBufferPointer(kNumberOfBuffers), - ".*Check failed: index < number_of_buffers_.*"); + // Returns NULL for invalid index to GetBufferPointer() + EXPECT_EQ(NULL, manager.GetBufferPointer(-1)); + EXPECT_EQ(NULL, manager.GetBufferPointer(kNumberOfBuffers)); // Test crash for passing invalid index to EnqueueBuffer(). EXPECT_DEATH(manager.EnqueueBuffer(-1), diff --git a/ppapi/thunk/ppb_media_stream_video_track_api.h b/ppapi/thunk/ppb_media_stream_video_track_api.h index 9f18eaf..6cee06a 100644 --- a/ppapi/thunk/ppb_media_stream_video_track_api.h +++ b/ppapi/thunk/ppb_media_stream_video_track_api.h @@ -23,6 +23,10 @@ class PPAPI_THUNK_EXPORT PPB_MediaStreamVideoTrack_API { scoped_refptr<ppapi::TrackedCallback> callback) = 0; virtual int32_t RecycleFrame(PP_Resource frame) = 0; virtual void Close() = 0; + virtual int32_t GetEmptyFrame( + PP_Resource* frame, + scoped_refptr<ppapi::TrackedCallback> callback) = 0; + virtual int32_t PutFrame(PP_Resource frame) = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_media_stream_video_track_thunk.cc b/ppapi/thunk/ppb_media_stream_video_track_thunk.cc index c39ee1c..8a26a41 100644 --- a/ppapi/thunk/ppb_media_stream_video_track_thunk.cc +++ b/ppapi/thunk/ppb_media_stream_video_track_thunk.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// From ppb_media_stream_video_track.idl modified Tue Mar 25 18:18:10 2014. +// From ppb_media_stream_video_track.idl modified Mon Mar 31 14:40:45 2014. #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" @@ -17,6 +17,14 @@ namespace thunk { namespace { +PP_Resource Create(PP_Instance instance) { + VLOG(4) << "PPB_MediaStreamVideoTrack::Create()"; + EnterResourceCreation enter(instance); + if (enter.failed()) + return 0; + return enter.functions()->CreateMediaStreamVideoTrack(instance); +} + PP_Bool IsMediaStreamVideoTrack(PP_Resource resource) { VLOG(4) << "PPB_MediaStreamVideoTrack::IsMediaStreamVideoTrack()"; EnterResource<PPB_MediaStreamVideoTrack_API> enter(resource, false); @@ -90,6 +98,27 @@ void Close(PP_Resource video_track) { enter.object()->Close(); } +int32_t GetEmptyFrame(PP_Resource video_track, + PP_Resource* frame, + struct PP_CompletionCallback callback) { + VLOG(4) << "PPB_MediaStreamVideoTrack::GetEmptyFrame()"; + EnterResource<PPB_MediaStreamVideoTrack_API> enter(video_track, + callback, + true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult(enter.object()->GetEmptyFrame(frame, + enter.callback())); +} + +int32_t PutFrame(PP_Resource video_track, PP_Resource frame) { + VLOG(4) << "PPB_MediaStreamVideoTrack::PutFrame()"; + EnterResource<PPB_MediaStreamVideoTrack_API> enter(video_track, true); + if (enter.failed()) + return enter.retval(); + return enter.object()->PutFrame(frame); +} + const PPB_MediaStreamVideoTrack_0_1 g_ppb_mediastreamvideotrack_thunk_0_1 = { &IsMediaStreamVideoTrack, &Configure, @@ -101,6 +130,20 @@ const PPB_MediaStreamVideoTrack_0_1 g_ppb_mediastreamvideotrack_thunk_0_1 = { &Close }; +const PPB_MediaStreamVideoTrack_1_0 g_ppb_mediastreamvideotrack_thunk_1_0 = { + &Create, + &IsMediaStreamVideoTrack, + &Configure, + &GetAttrib, + &GetId, + &HasEnded, + &GetFrame, + &RecycleFrame, + &Close, + &GetEmptyFrame, + &PutFrame +}; + } // namespace PPAPI_THUNK_EXPORT const PPB_MediaStreamVideoTrack_0_1* @@ -108,5 +151,10 @@ PPAPI_THUNK_EXPORT const PPB_MediaStreamVideoTrack_0_1* return &g_ppb_mediastreamvideotrack_thunk_0_1; } +PPAPI_THUNK_EXPORT const PPB_MediaStreamVideoTrack_1_0* + GetPPB_MediaStreamVideoTrack_1_0_Thunk() { + return &g_ppb_mediastreamvideotrack_thunk_1_0; +} + } // namespace thunk } // namespace ppapi diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 0c3dd42..f06b7d4 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -141,6 +141,7 @@ class ResourceCreationAPI { PP_ImageDataFormat format, const PP_Size* size, PP_Bool init_to_zero) = 0; + virtual PP_Resource CreateMediaStreamVideoTrack(PP_Instance instance) = 0; virtual PP_Resource CreateNetAddressFromIPv4Address( PP_Instance instance, const PP_NetAddress_IPv4* ipv4_addr) = 0; |