[PPAPI] Add media stream audio track c++ API

BUG=330851

Review URL: https://codereview.chromium.org/133583006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244730 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
index ccaf898..766e017 100644
--- a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
+++ b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
@@ -19,6 +19,7 @@
         'array_output.cc',
         'audio.cc',
         'audio_config.cc',
+        'audio_frame.cc',
         'core.cc',
         'directory_entry.cc',
         'file_io.cc',
@@ -33,6 +34,7 @@
         'input_event.cc',
         'instance.cc',
         'instance_handle.cc',
+        'media_stream_audio_track.cc',
         'media_stream_video_track.cc',
         'message_loop.cc',
         'module.cc',
@@ -111,6 +113,7 @@
       'FILES': [
         'array_output.h',
         'audio_config.h',
+        'audio_frame.h',
         'audio.h',
         'completion_callback.h',
         'core.h',
@@ -128,6 +131,7 @@
         'instance.h',
         'instance_handle.h',
         'logging.h',
+        'media_stream_audio_track.h',
         'media_stream_video_track.h',
         'message_loop.h',
         'module_embedder.h',
diff --git a/ppapi/cpp/audio_frame.cc b/ppapi/cpp/audio_frame.cc
new file mode 100644
index 0000000..7c3a1bbf
--- /dev/null
+++ b/ppapi/cpp/audio_frame.cc
@@ -0,0 +1,83 @@
+// 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/cpp/audio_frame.h"
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_AudioFrame_0_1>() {
+  return PPB_AUDIOFRAME_INTERFACE_0_1;
+}
+
+}  // namespace
+
+AudioFrame::AudioFrame() {
+}
+
+AudioFrame::AudioFrame(const AudioFrame& other) : Resource(other) {
+}
+
+AudioFrame::AudioFrame(const Resource& resource) : Resource(resource) {
+}
+
+AudioFrame::AudioFrame(PassRef, PP_Resource resource)
+    : Resource(PASS_REF, resource) {
+}
+
+AudioFrame::~AudioFrame() {
+}
+
+PP_TimeDelta AudioFrame::GetTimestamp() const {
+  if (has_interface<PPB_AudioFrame_0_1>())
+    return get_interface<PPB_AudioFrame_0_1>()->GetTimestamp(pp_resource());
+  return 0.0;
+}
+
+void AudioFrame::SetTimestamp(PP_TimeDelta timestamp) {
+  if (has_interface<PPB_AudioFrame_0_1>())
+    get_interface<PPB_AudioFrame_0_1>()->SetTimestamp(pp_resource(), timestamp);
+}
+
+uint32_t AudioFrame::GetSampleSize() const {
+  if (has_interface<PPB_AudioFrame_0_1>())
+    return get_interface<PPB_AudioFrame_0_1>()->GetSampleSize(pp_resource());
+  return 0;
+}
+
+uint32_t AudioFrame::GetNumberOfChannels() const {
+  if (has_interface<PPB_AudioFrame_0_1>()) {
+    return get_interface<PPB_AudioFrame_0_1>()->GetNumberOfChannels(
+        pp_resource());
+  }
+  return 0;
+}
+
+uint32_t AudioFrame::GetNumberOfSamples() const {
+  if (has_interface<PPB_AudioFrame_0_1>()) {
+    return get_interface<PPB_AudioFrame_0_1>()->GetNumberOfSamples(
+        pp_resource());
+  }
+  return 0;
+}
+
+void* AudioFrame::GetDataBuffer() {
+  if (has_interface<PPB_AudioFrame_0_1>())
+    return get_interface<PPB_AudioFrame_0_1>()->GetDataBuffer(pp_resource());
+  return NULL;
+}
+
+uint32_t AudioFrame::GetDataBufferSize() const {
+  if (has_interface<PPB_AudioFrame_0_1>()) {
+    return get_interface<PPB_AudioFrame_0_1>()->GetDataBufferSize(
+        pp_resource());
+  }
+  return 0;
+}
+
+}  // namespace pp
diff --git a/ppapi/cpp/audio_frame.h b/ppapi/cpp/audio_frame.h
new file mode 100644
index 0000000..32d55956
--- /dev/null
+++ b/ppapi/cpp/audio_frame.h
@@ -0,0 +1,80 @@
+// 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_CPP_AUDIO_FRAME_H_
+#define PPAPI_CPP_AUDIO_FRAME_H_
+
+#include "ppapi/c/ppb_audio_frame.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class AudioFrame : public Resource {
+ public:
+  /// Default constructor for creating an is_null()
+  /// <code>AudioFrame</code> object.
+  AudioFrame();
+
+  /// The copy constructor for <code>AudioFrame</code>.
+  ///
+  /// @param[in] other A reference to an <code>AudioFrame</code>.
+  AudioFrame(const AudioFrame& other);
+
+  /// Constructs an <code>AudioFrame</code> from a <code>Resource</code>.
+  ///
+  /// @param[in] resource A <code>PPB_AudioFrame</code> resource.
+  explicit AudioFrame(const Resource& resource);
+
+  /// A constructor used when you have received a <code>PP_Resource</code> as a
+  /// return value that has had 1 ref added for you.
+  ///
+  /// @param[in] resource A <code>PPB_AudioFrame</code> resource.
+  AudioFrame(PassRef, PP_Resource resource);
+
+  virtual ~AudioFrame();
+
+  /// Gets the timestamp of the audio frame.
+  ///
+  /// @return A <code>PP_TimeDelta</code> containing the timestamp of the audio
+  /// frame. Given in seconds since the start of the containing audio stream.
+  PP_TimeDelta GetTimestamp() const;
+
+  /// Sets the timestamp of the audio frame.
+  ///
+  /// @param[in] timestamp A <code>PP_TimeDelta</code> containing the timestamp
+  /// of the audio frame. Given in seconds since the start of the containing
+  /// audio stream.
+  void SetTimestamp(PP_TimeDelta timestamp);
+
+  /// Gets the sample size of the audio frame in bytes.
+  ///
+  /// @return The sample size of the audio frame in bytes.
+  uint32_t GetSampleSize() const;
+
+  /// Gets the number of channels in the audio frame.
+  ///
+  /// @return The number of channels in the audio frame.
+  uint32_t GetNumberOfChannels() const;
+
+  /// Gets the number of samples in the audio frame.
+  ///
+  /// @return The number of samples in the audio frame.
+  /// For example, at a sampling rate of 44,100 Hz in stereo audio, a frame
+  /// containing 4,410 * 2 samples would have a duration of 100 milliseconds.
+  uint32_t GetNumberOfSamples() const;
+
+  /// Gets the data buffer containing the audio frame samples.
+  ///
+  /// @return A pointer to the beginning of the data buffer.
+  void* GetDataBuffer();
+
+  /// Gets the size of data buffer in bytes.
+  ///
+  /// @return The size of the data buffer in bytes.
+  uint32_t GetDataBufferSize() const;
+};
+
+}  // namespace pp
+
+#endif  // PPAPI_CPP_AUDIO_FRAME_H_
diff --git a/ppapi/cpp/media_stream_audio_track.cc b/ppapi/cpp/media_stream_audio_track.cc
new file mode 100644
index 0000000..54dcba2
--- /dev/null
+++ b/ppapi/cpp/media_stream_audio_track.cc
@@ -0,0 +1,101 @@
+// 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/cpp/media_stream_audio_track.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_media_stream_audio_track.h"
+#include "ppapi/cpp/audio_frame.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_MediaStreamAudioTrack_0_1>() {
+  return PPB_MEDIASTREAMAUDIOTRACK_INTERFACE_0_1;
+}
+
+}  // namespace
+
+MediaStreamAudioTrack::MediaStreamAudioTrack() {
+}
+
+MediaStreamAudioTrack::MediaStreamAudioTrack(
+    const MediaStreamAudioTrack& other) : Resource(other) {
+}
+
+MediaStreamAudioTrack::MediaStreamAudioTrack(const Resource& resource)
+    : Resource(resource) {
+  PP_DCHECK(IsMediaStreamAudioTrack(resource));
+}
+
+MediaStreamAudioTrack::MediaStreamAudioTrack(PassRef, PP_Resource resource)
+    : Resource(PASS_REF, resource) {
+}
+
+MediaStreamAudioTrack::~MediaStreamAudioTrack() {
+}
+
+int32_t MediaStreamAudioTrack::Configure(uint32_t samples_per_frame,
+                                         uint32_t frame_buffer_size) {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    return get_interface<PPB_MediaStreamAudioTrack_0_1>()->Configure(
+        pp_resource(), samples_per_frame, frame_buffer_size);
+  }
+  return PP_ERROR_NOINTERFACE;
+}
+
+std::string MediaStreamAudioTrack::GetId() const {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    pp::Var id(PASS_REF, get_interface<PPB_MediaStreamAudioTrack_0_1>()->GetId(
+        pp_resource()));
+    if (id.is_string())
+      return id.AsString();
+  }
+  return std::string();
+}
+
+bool MediaStreamAudioTrack::HasEnded() const {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    return PP_ToBool(get_interface<PPB_MediaStreamAudioTrack_0_1>()->HasEnded(
+        pp_resource()));
+  }
+  return true;
+}
+
+int32_t MediaStreamAudioTrack::GetFrame(
+    const CompletionCallbackWithOutput<AudioFrame>& cc) {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    return get_interface<PPB_MediaStreamAudioTrack_0_1>()->GetFrame(
+        pp_resource(), cc.output(), cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t MediaStreamAudioTrack::RecycleFrame(const AudioFrame& frame) {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    return get_interface<PPB_MediaStreamAudioTrack_0_1>()->RecycleFrame(
+        pp_resource(), frame.pp_resource());
+  }
+  return PP_ERROR_NOINTERFACE;
+}
+
+void MediaStreamAudioTrack::Close() {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>())
+    get_interface<PPB_MediaStreamAudioTrack_0_1>()->Close(pp_resource());
+}
+
+// static
+bool MediaStreamAudioTrack::IsMediaStreamAudioTrack(const Resource& resource) {
+  if (has_interface<PPB_MediaStreamAudioTrack_0_1>()) {
+    return PP_ToBool(get_interface<PPB_MediaStreamAudioTrack_0_1>()->
+        IsMediaStreamAudioTrack(resource.pp_resource()));
+  }
+  return false;
+}
+
+}  // namespace pp
diff --git a/ppapi/cpp/media_stream_audio_track.h b/ppapi/cpp/media_stream_audio_track.h
new file mode 100644
index 0000000..28b978b10
--- /dev/null
+++ b/ppapi/cpp/media_stream_audio_track.h
@@ -0,0 +1,122 @@
+// 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_CPP_MEDIA_STREAM_AUDIO_TRACK_H_
+#define PPAPI_CPP_MEDIA_STREAM_AUDIO_TRACK_H_
+
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+/// @file
+/// This file defines the <code>MediaStreamAudioTrack</code> interface for an
+/// audio source resource, which receives audio frames from a MediaStream audio
+/// track in the browser.
+
+namespace pp {
+
+class AudioFrame;
+template <typename T> class CompletionCallbackWithOutput;
+
+/// The <code>MediaStreamAudioTrack</code> class contains methods for
+/// receiving audio frames from a MediaStream audio track in the browser.
+class MediaStreamAudioTrack : public Resource {
+ public:
+  /// Default constructor for creating an is_null()
+  /// <code>MediaStreamAudioTrack</code> object.
+  MediaStreamAudioTrack();
+
+  /// The copy constructor for <code>MediaStreamAudioTrack</code>.
+  ///
+  /// @param[in] other A reference to a <code>MediaStreamAudioTrack</code>.
+  MediaStreamAudioTrack(const MediaStreamAudioTrack& other);
+
+  /// Constructs a <code>MediaStreamAudioTrack</code> from
+  /// a <code>Resource</code>.
+  ///
+  /// @param[in] resource A <code>PPB_MediaStreamAudioTrack</code> resource.
+  explicit MediaStreamAudioTrack(const Resource& resource);
+
+  /// A constructor used when you have received a <code>PP_Resource</code> as a
+  /// return value that has had 1 ref added for you.
+  ///
+  /// @param[in] resource A <code>PPB_MediaStreamAudioTrack</code> resource.
+  MediaStreamAudioTrack(PassRef, PP_Resource resource);
+
+  ~MediaStreamAudioTrack();
+
+  /// Configures underlying frame buffers for incoming frames.
+  /// If the application doesn't want to drop frames, then the
+  /// <code>max_buffered_frames</code> should be chosen such that inter-frame
+  /// processing time variability won't overrun the input buffer. If the buffer
+  /// is overfilled, then frames will be dropped. The application can detect
+  /// this by examining the timestamp on returned frames.
+  /// If <code>Configure()</code> is not used, default settings will be used.
+  ///
+  /// @param[in] samples_per_frame The number of audio samples in an audio
+  /// frame.
+  /// @param[in] max_buffered_frames The maximum number of audio frames to
+  /// hold in the input buffer.
+  ///
+  /// @return An int32_t containing a result code from <code>pp_errors.h</code>.
+  int32_t Configure(uint32_t samples_per_frame,
+                    uint32_t max_buffered_frames);
+
+  /// Returns the track ID of the underlying MediaStream audio track.
+  std::string GetId() const;
+
+  /// Checks whether the underlying MediaStream track has ended.
+  /// Calls to GetFrame while the track has ended are safe to make and will
+  /// complete, but will fail.
+  bool HasEnded() const;
+
+  /// Gets the next audio frame from the MediaStream track.
+  /// If internal processing is slower than the incoming frame rate, new frames
+  /// will be dropped from the incoming stream. Once the input buffer is full,
+  /// frames will be dropped until <code>RecycleFrame()</code> is called to free
+  /// a spot for another frame to be buffered.
+  /// If there are no frames in the input buffer,
+  /// <code>PP_OK_COMPLETIONPENDING</code> will be returned immediately and the
+  /// <code>callback</code> will be called when a new frame is received or some
+  /// error happens.
+  ///
+  /// @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+  /// completion of <code>GetFrame()</code>. If success, an AudioFrame will be
+  /// passed into the completion callback function.
+  ///
+  /// @return An int32_t containing a result code from <code>pp_errors.h</code>.
+  /// Returns PP_ERROR_NOMEMORY if <code>max_buffered_frames</code> frames
+  /// buffer was not allocated successfully.
+  int32_t GetFrame(
+      const CompletionCallbackWithOutput<AudioFrame>& callback);
+
+  /// Recycles a frame returned by <code>GetFrame()</code>, so the track can
+  /// reuse the underlying buffer of this frame. And the frame will become
+  /// invalid. The caller should release all references it holds to
+  /// <code>frame</code> and not use it anymore.
+  ///
+  /// @param[in] frame A AudioFrame returned by <code>GetFrame()</code>.
+  ///
+  /// @return An int32_t containing a result code from <code>pp_errors.h</code>.
+  int32_t RecycleFrame(const AudioFrame& frame);
+
+  /// Closes the MediaStream audio track, and disconnects it from the audio
+  /// source.
+  /// After calling <code>Close()</code>, no new frames will be received.
+  void Close();
+
+  /// Checks whether a <code>Resource</code> is a MediaStream audio track,
+  /// to test whether it is appropriate for use with the
+  /// <code>MediaStreamAudioTrack</code> constructor.
+  ///
+  /// @param[in] resource A <code>Resource</code> to test.
+  ///
+  /// @return True if <code>resource</code> is a MediaStream audio track.
+  static bool IsMediaStreamAudioTrack(const Resource& resource);
+};
+
+}  // namespace pp
+
+#endif  // PPAPI_CPP_MEDIA_STREAM_AUDIO_TRACK_H_
diff --git a/ppapi/cpp/media_stream_video_track.h b/ppapi/cpp/media_stream_video_track.h
index b056178cb..ed7c93d 100644
--- a/ppapi/cpp/media_stream_video_track.h
+++ b/ppapi/cpp/media_stream_video_track.h
@@ -36,7 +36,7 @@
   /// Constructs a <code>MediaStreamVideoTrack</code> from
   /// a <code>Resource</code>.
   ///
-  /// @param[in] resource A <code>Resource</code> containing a file system.
+  /// @param[in] resource A <code>PPB_MediaStreamVideoTrack</code> resource.
   explicit MediaStreamVideoTrack(const Resource& resource);
 
   /// A constructor used when you have received a <code>PP_Resource</code> as a
diff --git a/ppapi/cpp/video_frame.cc b/ppapi/cpp/video_frame.cc
index a3c9311..6ee75ebf 100644
--- a/ppapi/cpp/video_frame.cc
+++ b/ppapi/cpp/video_frame.cc
@@ -34,12 +34,9 @@
 }
 
 PP_TimeDelta VideoFrame::GetTimestamp() const {
-  PP_TimeDelta timestamp = .0;
-  if (has_interface<PPB_VideoFrame_0_1>()) {
-    timestamp = get_interface<PPB_VideoFrame_0_1>()->GetTimestamp(
-        pp_resource());
-  }
-  return timestamp;
+  if (has_interface<PPB_VideoFrame_0_1>())
+    return get_interface<PPB_VideoFrame_0_1>()->GetTimestamp(pp_resource());
+  return 0.0;
 }
 
 void VideoFrame::SetTimestamp(PP_TimeDelta timestamp) {
diff --git a/ppapi/cpp/video_frame.h b/ppapi/cpp/video_frame.h
index 0c3b3ea..d456158 100644
--- a/ppapi/cpp/video_frame.h
+++ b/ppapi/cpp/video_frame.h
@@ -22,12 +22,15 @@
   /// @param[in] other A reference to a <code>VideoFrame</code>.
   VideoFrame(const VideoFrame& other);
 
-  VideoFrame(const Resource& resource);
+  /// Constructs a <code>VideoFrame</code> from a <code>Resource</code>.
+  ///
+  /// @param[in] resource A <code>PPB_VideoFrame</code> resource.
+  explicit VideoFrame(const Resource& resource);
 
   /// A constructor used when you have received a <code>PP_Resource</code> as a
   /// return value that has had 1 ref added for you.
   ///
-  /// @para[in] resource A <code>PPB_VideoFrame</code> resource.
+  /// @param[in] resource A <code>PPB_VideoFrame</code> resource.
   VideoFrame(PassRef, PP_Resource resource);
 
   virtual ~VideoFrame();
@@ -38,8 +41,7 @@
   /// frame. Given in seconds since the start of the containing video stream.
   PP_TimeDelta GetTimestamp() const;
 
-  /// Sets the timestamp of the video frame. Given in seconds since the
-  /// start of the containing video stream.
+  /// Sets the timestamp of the video frame.
   ///
   /// @param[in] timestamp A <code>PP_TimeDelta</code> containing the timestamp
   /// of the video frame. Given in seconds since the start of the containing
@@ -64,9 +66,9 @@
   /// @return A pointer to the beginning of the data buffer.
   void* GetDataBuffer();
 
-  /// Gets the size of data buffer.
+  /// Gets the size of data buffer in bytes.
   ///
-  /// @return The size of the data buffer.
+  /// @return The size of the data buffer in bytes.
   uint32_t GetDataBufferSize() const;
 };
 
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 9e83be10..f47d3f97 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -157,6 +157,8 @@
       'cpp/audio.h',
       'cpp/audio_config.cc',
       'cpp/audio_config.h',
+      'cpp/audio_frame.cc',
+      'cpp/audio_frame.h',
       'cpp/completion_callback.h',
       'cpp/core.cc',
       'cpp/core.h',
@@ -187,6 +189,8 @@
       'cpp/instance_handle.cc',
       'cpp/instance_handle.h',
       'cpp/logging.h',
+      'cpp/media_stream_audio_track.cc',
+      'cpp/media_stream_audio_track.h',
       'cpp/media_stream_video_track.cc',
       'cpp/media_stream_video_track.h',
       'cpp/message_loop.cc',
diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h
index 75cfbf83..99f111d 100644
--- a/ppapi/tests/all_cpp_includes.h
+++ b/ppapi/tests/all_cpp_includes.h
@@ -10,6 +10,7 @@
 
 #include "ppapi/cpp/audio.h"
 #include "ppapi/cpp/audio_config.h"
+#include "ppapi/cpp/audio_frame.h"
 #include "ppapi/cpp/completion_callback.h"
 #include "ppapi/cpp/core.h"
 #include "ppapi/cpp/dev/alarms_dev.h"
@@ -51,6 +52,7 @@
 #include "ppapi/cpp/image_data.h"
 #include "ppapi/cpp/instance.h"
 #include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/media_stream_audio_track.h"
 #include "ppapi/cpp/media_stream_video_track.h"
 #include "ppapi/cpp/module.h"
 #include "ppapi/cpp/module_impl.h"