summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy
diff options
context:
space:
mode:
authorpenghuang@chromium.org <penghuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 02:50:23 +0000
committerpenghuang@chromium.org <penghuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 02:50:23 +0000
commit2b7a6d39afde5917e8ccb341afdccb0a931b2636 (patch)
tree1074e567377cd34157c0755582d68143fbf040e8 /ppapi/proxy
parent8fa42fb71833ddd618b2d9c41b1ccf1a269f7e86 (diff)
downloadchromium_src-2b7a6d39afde5917e8ccb341afdccb0a931b2636.zip
chromium_src-2b7a6d39afde5917e8ccb341afdccb0a931b2636.tar.gz
chromium_src-2b7a6d39afde5917e8ccb341afdccb0a931b2636.tar.bz2
[PPAPI] Pepper MediaStream API audio track implementation and example.
TBR=jamesr@chromium.org BUG=330851 Review URL: https://codereview.chromium.org/140783004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249245 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r--ppapi/proxy/audio_frame_resource.cc111
-rw-r--r--ppapi/proxy/audio_frame_resource.h54
-rw-r--r--ppapi/proxy/media_stream_audio_track_resource.cc148
-rw-r--r--ppapi/proxy/media_stream_audio_track_resource.h70
-rw-r--r--ppapi/proxy/media_stream_video_track_resource.cc18
-rw-r--r--ppapi/proxy/plugin_var_tracker.cc19
-rw-r--r--ppapi/proxy/ppapi_messages.h6
7 files changed, 418 insertions, 8 deletions
diff --git a/ppapi/proxy/audio_frame_resource.cc b/ppapi/proxy/audio_frame_resource.cc
new file mode 100644
index 0000000..4954857
--- /dev/null
+++ b/ppapi/proxy/audio_frame_resource.cc
@@ -0,0 +1,111 @@
+// Copyright 2014 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/audio_frame_resource.h"
+
+#include "base/logging.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+namespace proxy {
+
+AudioFrameResource::AudioFrameResource(PP_Instance instance,
+ int32_t index,
+ MediaStreamFrame* frame)
+ : Resource(OBJECT_IS_PROXY, instance),
+ index_(index),
+ frame_(frame) {
+ DCHECK_EQ(frame_->header.type, MediaStreamFrame::TYPE_AUDIO);
+}
+
+AudioFrameResource::~AudioFrameResource() {
+ CHECK(!frame_) << "An unused (or unrecycled) frame is destroyed.";
+}
+
+thunk::PPB_AudioFrame_API* AudioFrameResource::AsPPB_AudioFrame_API() {
+ return this;
+}
+
+PP_TimeDelta AudioFrameResource::GetTimestamp() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return 0.0;
+ }
+ return frame_->audio.timestamp;
+}
+
+void AudioFrameResource::SetTimestamp(PP_TimeDelta timestamp) {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return;
+ }
+ frame_->audio.timestamp = timestamp;
+}
+
+PP_AudioFrame_SampleRate AudioFrameResource::GetSampleRate() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return PP_AUDIOFRAME_SAMPLERATE_UNKNOWN;
+ }
+ return frame_->audio.sample_rate;
+}
+
+PP_AudioFrame_SampleSize AudioFrameResource::GetSampleSize() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return PP_AUDIOFRAME_SAMPLESIZE_UNKNOWN;
+ }
+ return PP_AUDIOFRAME_SAMPLESIZE_16_BITS;
+}
+
+uint32_t AudioFrameResource::GetNumberOfChannels() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return 0;
+ }
+ return frame_->audio.number_of_channels;
+}
+
+uint32_t AudioFrameResource::GetNumberOfSamples() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return 0;
+ }
+ return frame_->audio.number_of_samples;
+}
+
+void* AudioFrameResource::GetDataBuffer() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return NULL;
+ }
+ return frame_->audio.data;
+}
+
+uint32_t AudioFrameResource::GetDataBufferSize() {
+ if (!frame_) {
+ VLOG(1) << "Frame is invalid";
+ return 0;
+ }
+ return frame_->audio.data_size;
+}
+
+MediaStreamFrame* AudioFrameResource::GetFrameBuffer() {
+ return frame_;
+}
+
+int32_t AudioFrameResource::GetFrameBufferIndex() {
+ return index_;
+}
+
+void AudioFrameResource::Invalidate() {
+ DCHECK(frame_);
+ DCHECK_GE(index_, 0);
+ frame_ = NULL;
+ index_ = -1;
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/audio_frame_resource.h b/ppapi/proxy/audio_frame_resource.h
new file mode 100644
index 0000000..a463bba
--- /dev/null
+++ b/ppapi/proxy/audio_frame_resource.h
@@ -0,0 +1,54 @@
+// Copyright 2014 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_AUDIO_FRAME_RESOURCE_H_
+#define PPAPI_PROXY_AUDIO_FRAME_RESOURCE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/shared_impl/media_stream_frame.h"
+#include "ppapi/shared_impl/resource.h"
+#include "ppapi/thunk/ppb_audio_frame_api.h"
+
+namespace ppapi {
+namespace proxy {
+
+class PPAPI_PROXY_EXPORT AudioFrameResource : public Resource,
+ public thunk::PPB_AudioFrame_API {
+ public:
+ AudioFrameResource(PP_Instance instance,
+ int32_t index,
+ MediaStreamFrame* frame);
+
+ virtual ~AudioFrameResource();
+
+ // PluginResource overrides:
+ virtual thunk::PPB_AudioFrame_API* AsPPB_AudioFrame_API() OVERRIDE;
+
+ // PPB_AudioFrame_API overrides:
+ virtual PP_TimeDelta GetTimestamp() OVERRIDE;
+ virtual void SetTimestamp(PP_TimeDelta timestamp) OVERRIDE;
+ virtual PP_AudioFrame_SampleRate GetSampleRate() OVERRIDE;
+ virtual PP_AudioFrame_SampleSize GetSampleSize() OVERRIDE;
+ virtual uint32_t GetNumberOfChannels() OVERRIDE;
+ virtual uint32_t GetNumberOfSamples() OVERRIDE;
+ virtual void* GetDataBuffer() OVERRIDE;
+ virtual uint32_t GetDataBufferSize() OVERRIDE;
+ virtual MediaStreamFrame* GetFrameBuffer();
+ virtual int32_t GetFrameBufferIndex();
+ virtual void Invalidate();
+
+ // Frame index
+ int32_t index_;
+
+ MediaStreamFrame* frame_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioFrameResource);
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_AUDIO_FRAME_RESOURCE_H_
diff --git a/ppapi/proxy/media_stream_audio_track_resource.cc b/ppapi/proxy/media_stream_audio_track_resource.cc
new file mode 100644
index 0000000..10956ab
--- /dev/null
+++ b/ppapi/proxy/media_stream_audio_track_resource.cc
@@ -0,0 +1,148 @@
+// Copyright 2014 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/media_stream_audio_track_resource.h"
+
+#include "ppapi/proxy/audio_frame_resource.h"
+#include "ppapi/shared_impl/media_stream_frame.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+namespace proxy {
+
+MediaStreamAudioTrackResource::MediaStreamAudioTrackResource(
+ Connection connection,
+ PP_Instance instance,
+ int pending_renderer_id,
+ const std::string& id)
+ : MediaStreamTrackResourceBase(
+ connection, instance, pending_renderer_id, id),
+ get_frame_output_(NULL) {
+}
+
+MediaStreamAudioTrackResource::~MediaStreamAudioTrackResource() {
+ Close();
+}
+
+thunk::PPB_MediaStreamAudioTrack_API*
+MediaStreamAudioTrackResource::AsPPB_MediaStreamAudioTrack_API() {
+ return this;
+}
+
+PP_Var MediaStreamAudioTrackResource::GetId() {
+ return StringVar::StringToPPVar(id());
+}
+
+PP_Bool MediaStreamAudioTrackResource::HasEnded() {
+ return PP_FromBool(has_ended());
+}
+
+int32_t MediaStreamAudioTrackResource::Configure(
+ const int32_t attrib_list[],
+ scoped_refptr<TrackedCallback> callback) {
+ // TODO(penghuang): Implement this function.
+ return PP_ERROR_NOTSUPPORTED;
+}
+
+int32_t MediaStreamAudioTrackResource::GetAttrib(
+ PP_MediaStreamAudioTrack_Attrib attrib,
+ int32_t* value) {
+ // TODO(penghuang): Implement this function.
+ return PP_ERROR_NOTSUPPORTED;
+}
+
+int32_t MediaStreamAudioTrackResource::GetFrame(
+ PP_Resource* frame,
+ scoped_refptr<TrackedCallback> callback) {
+ if (has_ended())
+ return PP_ERROR_FAILED;
+
+ if (TrackedCallback::IsPending(get_frame_callback_))
+ return PP_ERROR_INPROGRESS;
+
+ *frame = GetAudioFrame();
+ if (*frame)
+ return PP_OK;
+
+ // TODO(penghuang): Use the callback as hints to determine which thread will
+ // use the resource, so we could deliver frames to the target thread directly
+ // for better performance.
+ get_frame_output_ = frame;
+ get_frame_callback_ = callback;
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t MediaStreamAudioTrackResource::RecycleFrame(PP_Resource frame) {
+ FrameMap::iterator it = frames_.find(frame);
+ if (it == frames_.end())
+ return PP_ERROR_BADRESOURCE;
+
+ scoped_refptr<AudioFrameResource> frame_resource = it->second;
+ frames_.erase(it);
+
+ if (has_ended())
+ return PP_OK;
+
+ DCHECK_GE(frame_resource->GetFrameBufferIndex(), 0);
+
+ SendEnqueueFrameMessageToHost(frame_resource->GetFrameBufferIndex());
+ frame_resource->Invalidate();
+ return PP_OK;
+}
+
+void MediaStreamAudioTrackResource::Close() {
+ if (has_ended())
+ return;
+
+ if (TrackedCallback::IsPending(get_frame_callback_)) {
+ *get_frame_output_ = 0;
+ get_frame_callback_->PostAbort();
+ get_frame_callback_ = NULL;
+ get_frame_output_ = 0;
+ }
+
+ ReleaseFrames();
+ MediaStreamTrackResourceBase::CloseInternal();
+}
+
+void MediaStreamAudioTrackResource::OnNewFrameEnqueued() {
+ if (!TrackedCallback::IsPending(get_frame_callback_))
+ return;
+
+ *get_frame_output_ = GetAudioFrame();
+ int32_t result = *get_frame_output_ ? PP_OK : PP_ERROR_FAILED;
+ get_frame_output_ = NULL;
+ scoped_refptr<TrackedCallback> callback;
+ callback.swap(get_frame_callback_);
+ callback->Run(result);
+}
+
+PP_Resource MediaStreamAudioTrackResource::GetAudioFrame() {
+ int32_t index = frame_buffer()->DequeueFrame();
+ if (index < 0)
+ return 0;
+
+ MediaStreamFrame* frame = frame_buffer()->GetFramePointer(index);
+ DCHECK(frame);
+ scoped_refptr<AudioFrameResource> resource =
+ new AudioFrameResource(pp_instance(), index, frame);
+ // Add |pp_resource()| and |resource| into |frames_|.
+ // |frames_| uses scoped_ptr<> to hold a ref of |resource|. It keeps the
+ // resource alive.
+ frames_.insert(FrameMap::value_type(resource->pp_resource(), resource));
+ return resource->GetReference();
+}
+
+void MediaStreamAudioTrackResource::ReleaseFrames() {
+ FrameMap::iterator it = frames_.begin();
+ while (it != frames_.end()) {
+ // Just invalidate and release VideoFrameResorce, but keep PP_Resource.
+ // So plugin can still use |RecycleFrame()|.
+ it->second->Invalidate();
+ it->second = NULL;
+ }
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/media_stream_audio_track_resource.h b/ppapi/proxy/media_stream_audio_track_resource.h
new file mode 100644
index 0000000..2686381
--- /dev/null
+++ b/ppapi/proxy/media_stream_audio_track_resource.h
@@ -0,0 +1,70 @@
+// Copyright 2014 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_MEDIA_STREAM_AUDIO_TRACK_RESOURCE_H_
+#define PPAPI_PROXY_MEDIA_STREAM_AUDIO_TRACK_RESOURCE_H_
+
+#include <map>
+
+#include "base/memory/ref_counted.h"
+#include "ppapi/proxy/media_stream_track_resource_base.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/thunk/ppb_media_stream_audio_track_api.h"
+
+namespace ppapi {
+namespace proxy {
+
+class AudioFrameResource;
+
+class PPAPI_PROXY_EXPORT MediaStreamAudioTrackResource
+ : public MediaStreamTrackResourceBase,
+ public thunk::PPB_MediaStreamAudioTrack_API {
+ public:
+ MediaStreamAudioTrackResource(Connection connection,
+ PP_Instance instance,
+ int pending_renderer_id,
+ const std::string& id);
+
+ virtual ~MediaStreamAudioTrackResource();
+
+ // Resource overrides:
+ virtual thunk::PPB_MediaStreamAudioTrack_API*
+ AsPPB_MediaStreamAudioTrack_API() OVERRIDE;
+
+ // PPB_MediaStreamAudioTrack_API overrides:
+ virtual PP_Var GetId() OVERRIDE;
+ virtual PP_Bool HasEnded() OVERRIDE;
+ virtual int32_t Configure(const int32_t attrib_list[],
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t GetAttrib(PP_MediaStreamAudioTrack_Attrib attrib,
+ int32_t* value) OVERRIDE;
+ virtual int32_t GetFrame(
+ PP_Resource* frame,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t RecycleFrame(PP_Resource frame) OVERRIDE;
+ virtual void Close() OVERRIDE;
+
+ // MediaStreamFrameBuffer::Delegate overrides:
+ virtual void OnNewFrameEnqueued() OVERRIDE;
+
+ private:
+ PP_Resource GetAudioFrame();
+
+ void ReleaseFrames();
+
+ // Allocated frame resources by |GetFrame()|.
+ typedef std::map<PP_Resource, scoped_refptr<AudioFrameResource> > FrameMap;
+ FrameMap frames_;
+
+ PP_Resource* get_frame_output_;
+
+ scoped_refptr<TrackedCallback> get_frame_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioTrackResource);
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_MEDIA_STREAM_AUDIO_TRACK_RESOURCE_H_
diff --git a/ppapi/proxy/media_stream_video_track_resource.cc b/ppapi/proxy/media_stream_video_track_resource.cc
index e8ab4c5..804df00 100644
--- a/ppapi/proxy/media_stream_video_track_resource.cc
+++ b/ppapi/proxy/media_stream_video_track_resource.cc
@@ -107,20 +107,24 @@ void MediaStreamVideoTrackResource::Close() {
}
void MediaStreamVideoTrackResource::OnNewFrameEnqueued() {
- if (TrackedCallback::IsPending(get_frame_callback_)) {
- *get_frame_output_ = GetVideoFrame();
- get_frame_output_ = NULL;
- scoped_refptr<TrackedCallback> callback;
- callback.swap(get_frame_callback_);
- callback->Run(PP_OK);
- }
+ if (!TrackedCallback::IsPending(get_frame_callback_))
+ return;
+
+ *get_frame_output_ = GetVideoFrame();
+ int32_t result = *get_frame_output_ ? PP_OK : PP_ERROR_FAILED;
+ get_frame_output_ = NULL;
+ scoped_refptr<TrackedCallback> callback;
+ callback.swap(get_frame_callback_);
+ callback->Run(result);
}
PP_Resource MediaStreamVideoTrackResource::GetVideoFrame() {
int32_t index = frame_buffer()->DequeueFrame();
if (index < 0)
return 0;
+
MediaStreamFrame* frame = frame_buffer()->GetFramePointer(index);
+ DCHECK(frame);
scoped_refptr<VideoFrameResource> resource =
new VideoFrameResource(pp_instance(), index, frame);
// Add |pp_resource()| and |resource| into |frames_|.
diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc
index e2db871..06db224 100644
--- a/ppapi/proxy/plugin_var_tracker.cc
+++ b/ppapi/proxy/plugin_var_tracker.cc
@@ -10,6 +10,7 @@
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/file_system_resource.h"
+#include "ppapi/proxy/media_stream_audio_track_resource.h"
#include "ppapi/proxy/media_stream_video_track_resource.h"
#include "ppapi/proxy/plugin_array_buffer_var.h"
#include "ppapi/proxy/plugin_dispatcher.h"
@@ -195,6 +196,24 @@ PP_Var PluginVarTracker::MakeResourcePPVarFromMessage(
file_system_type))->GetReference();
return MakeResourcePPVar(pp_resource);
}
+ case PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost::ID: {
+ DCHECK(pending_renderer_id);
+ std::string track_id;
+ if (!UnpackMessage<
+ PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost>(
+ creation_message, &track_id)) {
+ NOTREACHED() <<
+ "Invalid message of type "
+ "PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost";
+ return PP_MakeNull();
+ }
+ PP_Resource pp_resource =
+ (new MediaStreamAudioTrackResource(GetConnectionForInstance(instance),
+ instance,
+ pending_renderer_id,
+ track_id))->GetReference();
+ return MakeResourcePPVar(pp_resource);
+ }
case PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost::ID: {
DCHECK(pending_renderer_id);
std::string track_id;
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 7e6543e..92ed096 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1437,9 +1437,13 @@ IPC_MESSAGE_CONTROL1(PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply,
std::string /* fsid */)
// MediaStream -----------------------------------------------------------------
-// Message for init frames. It also takes a shared memory handle.
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost,
+ std::string /* track_id */)
IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost,
std::string /* track_id */)
+
+// Message for init frames. It also takes a shared memory handle which is put in
+// the outer ResourceReplyMessage.
IPC_MESSAGE_CONTROL2(PpapiPluginMsg_MediaStreamTrack_InitFrames,
int32_t /* number_of_frames */,
int32_t /* frame_size */)