Home | History | Annotate | Download | only in tests
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // Tests PPB_MediaStreamAudioTrack interface.
      6 
      7 #include "ppapi/tests/test_media_stream_audio_track.h"
      8 
      9 #include "ppapi/c/private/ppb_testing_private.h"
     10 #include "ppapi/cpp/audio_buffer.h"
     11 #include "ppapi/cpp/completion_callback.h"
     12 #include "ppapi/cpp/instance.h"
     13 #include "ppapi/cpp/var.h"
     14 #include "ppapi/tests/test_utils.h"
     15 #include "ppapi/tests/testing_instance.h"
     16 
     17 REGISTER_TEST_CASE(MediaStreamAudioTrack);
     18 
     19 namespace {
     20 
     21 // Real max defined in
     22 // content/renderer/pepper/pepper_media_stream_audio_track_host.cc.
     23 const int32_t kMaxNumberOfBuffers = 1000;
     24 const int32_t kTimes = 3;
     25 const char kJSCode[] =
     26     "function gotStream(stream) {"
     27     "  test_stream = stream;"
     28     "  var track = stream.getAudioTracks()[0];"
     29     "  var plugin = document.getElementById('plugin');"
     30     "  plugin.postMessage(track);"
     31     "}"
     32     "var constraints = {"
     33     "  audio: true,"
     34     "  video: false,"
     35     "};"
     36     "navigator.getUserMedia = "
     37     "    navigator.getUserMedia || navigator.webkitGetUserMedia;"
     38     "navigator.getUserMedia(constraints,"
     39     "    gotStream, function() {});";
     40 
     41 // Helper to check if the |sample_rate| is listed in PP_AudioBuffer_SampleRate
     42 // enum.
     43 bool IsSampleRateValid(PP_AudioBuffer_SampleRate sample_rate) {
     44   switch (sample_rate) {
     45     case PP_AUDIOBUFFER_SAMPLERATE_8000:
     46     case PP_AUDIOBUFFER_SAMPLERATE_16000:
     47     case PP_AUDIOBUFFER_SAMPLERATE_22050:
     48     case PP_AUDIOBUFFER_SAMPLERATE_32000:
     49     case PP_AUDIOBUFFER_SAMPLERATE_44100:
     50     case PP_AUDIOBUFFER_SAMPLERATE_48000:
     51     case PP_AUDIOBUFFER_SAMPLERATE_96000:
     52     case PP_AUDIOBUFFER_SAMPLERATE_192000:
     53       return true;
     54     default:
     55       return false;
     56   }
     57 }
     58 
     59 }  // namespace
     60 
     61 TestMediaStreamAudioTrack::TestMediaStreamAudioTrack(TestingInstance* instance)
     62     : TestCase(instance),
     63       event_(instance_->pp_instance()) {
     64 }
     65 
     66 bool TestMediaStreamAudioTrack::Init() {
     67   return true;
     68 }
     69 
     70 TestMediaStreamAudioTrack::~TestMediaStreamAudioTrack() {
     71 }
     72 
     73 void TestMediaStreamAudioTrack::RunTests(const std::string& filter) {
     74   RUN_TEST(Create, filter);
     75   RUN_TEST(GetBuffer, filter);
     76   RUN_TEST(Configure, filter);
     77 }
     78 
     79 void TestMediaStreamAudioTrack::HandleMessage(const pp::Var& message) {
     80   if (message.is_resource()) {
     81     audio_track_ = pp::MediaStreamAudioTrack(message.AsResource());
     82   }
     83   event_.Signal();
     84 }
     85 
     86 std::string TestMediaStreamAudioTrack::TestCreate() {
     87   // Create a track.
     88   instance_->EvalScript(kJSCode);
     89   event_.Wait();
     90   event_.Reset();
     91 
     92   ASSERT_FALSE(audio_track_.is_null());
     93   ASSERT_FALSE(audio_track_.HasEnded());
     94   ASSERT_FALSE(audio_track_.GetId().empty());
     95 
     96   // Close the track.
     97   audio_track_.Close();
     98   ASSERT_TRUE(audio_track_.HasEnded());
     99   audio_track_ = pp::MediaStreamAudioTrack();
    100   PASS();
    101 }
    102 
    103 std::string TestMediaStreamAudioTrack::TestGetBuffer() {
    104   // Create a track.
    105   instance_->EvalScript(kJSCode);
    106   event_.Wait();
    107   event_.Reset();
    108 
    109   ASSERT_FALSE(audio_track_.is_null());
    110   ASSERT_FALSE(audio_track_.HasEnded());
    111   ASSERT_FALSE(audio_track_.GetId().empty());
    112 
    113   PP_TimeDelta timestamp = 0.0;
    114 
    115   // Get |kTimes| buffers.
    116   for (int i = 0; i < kTimes; ++i) {
    117     TestCompletionCallbackWithOutput<pp::AudioBuffer> cc(
    118         instance_->pp_instance(), false);
    119     cc.WaitForResult(audio_track_.GetBuffer(cc.GetCallback()));
    120     ASSERT_EQ(PP_OK, cc.result());
    121     pp::AudioBuffer buffer = cc.output();
    122     ASSERT_FALSE(buffer.is_null());
    123     ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate()));
    124     ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS);
    125 
    126     ASSERT_GE(buffer.GetTimestamp(), timestamp);
    127     timestamp = buffer.GetTimestamp();
    128 
    129     ASSERT_GT(buffer.GetDataBufferSize(), 0U);
    130     ASSERT_TRUE(buffer.GetDataBuffer() != NULL);
    131 
    132     audio_track_.RecycleBuffer(buffer);
    133 
    134     // A recycled buffer should be invalidated.
    135     ASSERT_EQ(buffer.GetSampleRate(), PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN);
    136     ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_UNKNOWN);
    137     ASSERT_EQ(buffer.GetDataBufferSize(), 0U);
    138     ASSERT_TRUE(buffer.GetDataBuffer() == NULL);
    139   }
    140 
    141   // Close the track.
    142   audio_track_.Close();
    143   ASSERT_TRUE(audio_track_.HasEnded());
    144   audio_track_ = pp::MediaStreamAudioTrack();
    145   PASS();
    146 }
    147 
    148 std::string TestMediaStreamAudioTrack::TestConfigure() {
    149   // Create a track.
    150   instance_->EvalScript(kJSCode);
    151   event_.Wait();
    152   event_.Reset();
    153 
    154   ASSERT_FALSE(audio_track_.is_null());
    155   ASSERT_FALSE(audio_track_.HasEnded());
    156   ASSERT_FALSE(audio_track_.GetId().empty());
    157 
    158   PP_TimeDelta timestamp = 0.0;
    159 
    160   // Configure number of buffers.
    161   struct {
    162     int32_t buffers;
    163     int32_t expect_result;
    164   } buffers[] = {
    165     { 8, PP_OK },
    166     { 100, PP_OK },
    167     { kMaxNumberOfBuffers, PP_OK },
    168     { -1, PP_ERROR_BADARGUMENT },
    169     { kMaxNumberOfBuffers + 1, PP_OK },  // Clipped to max value.
    170     { 0, PP_OK },  // Use default.
    171   };
    172   for (size_t i = 0; i < sizeof(buffers) / sizeof(buffers[0]); ++i) {
    173     TestCompletionCallback cc_configure(instance_->pp_instance(), false);
    174     int32_t attrib_list[] = {
    175       PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, buffers[i].buffers,
    176       PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    177     };
    178     cc_configure.WaitForResult(
    179         audio_track_.Configure(attrib_list, cc_configure.GetCallback()));
    180     ASSERT_EQ(buffers[i].expect_result, cc_configure.result());
    181 
    182     // Get some buffers. This should also succeed when configure fails.
    183     for (int j = 0; j < kTimes; ++j) {
    184       TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer(
    185           instance_->pp_instance(), false);
    186       cc_get_buffer.WaitForResult(
    187           audio_track_.GetBuffer(cc_get_buffer.GetCallback()));
    188       ASSERT_EQ(PP_OK, cc_get_buffer.result());
    189       pp::AudioBuffer buffer = cc_get_buffer.output();
    190       ASSERT_FALSE(buffer.is_null());
    191       ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate()));
    192       ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS);
    193 
    194       ASSERT_GE(buffer.GetTimestamp(), timestamp);
    195       timestamp = buffer.GetTimestamp();
    196 
    197       ASSERT_GT(buffer.GetDataBufferSize(), 0U);
    198       ASSERT_TRUE(buffer.GetDataBuffer() != NULL);
    199 
    200       audio_track_.RecycleBuffer(buffer);
    201     }
    202   }
    203 
    204   // Configure should fail while plugin holds buffers.
    205   {
    206     TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer(
    207         instance_->pp_instance(), false);
    208     cc_get_buffer.WaitForResult(
    209         audio_track_.GetBuffer(cc_get_buffer.GetCallback()));
    210     ASSERT_EQ(PP_OK, cc_get_buffer.result());
    211     pp::AudioBuffer buffer = cc_get_buffer.output();
    212     int32_t attrib_list[] = {
    213       PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, 0,
    214       PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    215     };
    216     TestCompletionCallback cc_configure(instance_->pp_instance(), false);
    217     cc_configure.WaitForResult(
    218         audio_track_.Configure(attrib_list, cc_configure.GetCallback()));
    219     ASSERT_EQ(PP_ERROR_INPROGRESS, cc_configure.result());
    220     audio_track_.RecycleBuffer(buffer);
    221   }
    222 
    223   // Close the track.
    224   audio_track_.Close();
    225   ASSERT_TRUE(audio_track_.HasEnded());
    226   audio_track_ = pp::MediaStreamAudioTrack();
    227   PASS();
    228 }
    229