Home | History | Annotate | Download | only in android
      1 // Copyright 2013 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 #include <string>
      6 
      7 #include "base/basictypes.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "media/base/android/media_codec_bridge.h"
     10 #include "media/base/android/media_player_manager.h"
     11 #include "media/base/android/media_source_player.h"
     12 #include "media/base/decoder_buffer.h"
     13 #include "media/base/test_data_util.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "ui/gl/android/surface_texture_bridge.h"
     16 
     17 namespace media {
     18 
     19 static const int kDefaultDurationInMs = 10000;
     20 
     21 // Mock of MediaPlayerManager for testing purpose
     22 class MockMediaPlayerManager : public MediaPlayerManager {
     23  public:
     24   MockMediaPlayerManager() : num_requests_(0), last_seek_request_id_(0) {}
     25   virtual ~MockMediaPlayerManager() {};
     26 
     27   // MediaPlayerManager implementation.
     28   virtual void RequestMediaResources(int player_id) OVERRIDE {}
     29   virtual void ReleaseMediaResources(int player_id) OVERRIDE {}
     30   virtual MediaResourceGetter* GetMediaResourceGetter() OVERRIDE {
     31     return NULL;
     32   }
     33   virtual void OnTimeUpdate(int player_id,
     34                             base::TimeDelta current_time) OVERRIDE {}
     35   virtual void OnMediaMetadataChanged(
     36       int player_id, base::TimeDelta duration, int width, int height,
     37       bool success) OVERRIDE {}
     38   virtual void OnPlaybackComplete(int player_id) OVERRIDE {
     39     if (message_loop_.is_running())
     40       message_loop_.Quit();
     41   }
     42   virtual void OnMediaInterrupted(int player_id) OVERRIDE {}
     43   virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE {}
     44   virtual void OnSeekComplete(int player_id,
     45                               base::TimeDelta current_time) OVERRIDE {}
     46   virtual void OnError(int player_id, int error) OVERRIDE {}
     47   virtual void OnVideoSizeChanged(int player_id, int width,
     48                                   int height) OVERRIDE {}
     49   virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; }
     50   virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; }
     51   virtual void DestroyAllMediaPlayers() OVERRIDE {}
     52   virtual void OnReadFromDemuxer(int player_id,
     53                                  media::DemuxerStream::Type type) OVERRIDE {
     54     num_requests_++;
     55     if (message_loop_.is_running())
     56       message_loop_.Quit();
     57   }
     58   virtual void OnMediaSeekRequest(int player_id, base::TimeDelta time_to_seek,
     59                                   unsigned seek_request_id) OVERRIDE {
     60     last_seek_request_id_ = seek_request_id;
     61   }
     62   virtual void OnMediaConfigRequest(int player_id) OVERRIDE {}
     63   virtual media::MediaDrmBridge* GetDrmBridge(int media_keys_id) OVERRIDE {
     64     return NULL;
     65   }
     66   virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE {}
     67   virtual void OnKeyAdded(int key_id,
     68                           const std::string& session_id) OVERRIDE {}
     69   virtual void OnKeyError(int key_id,
     70                           const std::string& session_id,
     71                           media::MediaKeys::KeyError error_code,
     72                           int system_code) OVERRIDE {}
     73   virtual void OnKeyMessage(int key_id,
     74                             const std::string& session_id,
     75                             const std::vector<uint8>& message,
     76                             const std::string& destination_url) OVERRIDE {}
     77 
     78   int num_requests() const { return num_requests_; }
     79   unsigned last_seek_request_id() const { return last_seek_request_id_; }
     80   base::MessageLoop* message_loop() { return &message_loop_; }
     81 
     82  private:
     83   // The number of request this object sents for decoding data.
     84   int num_requests_;
     85   unsigned last_seek_request_id_;
     86   base::MessageLoop message_loop_;
     87 };
     88 
     89 class MediaSourcePlayerTest : public testing::Test {
     90  public:
     91   MediaSourcePlayerTest() {
     92     manager_.reset(new MockMediaPlayerManager());
     93     player_.reset(new MediaSourcePlayer(0, manager_.get()));
     94   }
     95   virtual ~MediaSourcePlayerTest() {}
     96 
     97  protected:
     98   // Get the decoder job from the MediaSourcePlayer.
     99   MediaDecoderJob* GetMediaDecoderJob(bool is_audio) {
    100     if (is_audio) {
    101       return reinterpret_cast<MediaDecoderJob*>(
    102           player_->audio_decoder_job_.get());
    103     }
    104     return reinterpret_cast<MediaDecoderJob*>(
    105         player_->video_decoder_job_.get());
    106   }
    107 
    108   // Starts an audio decoder job.
    109   void StartAudioDecoderJob() {
    110     MediaPlayerHostMsg_DemuxerReady_Params params;
    111     params.audio_codec = kCodecVorbis;
    112     params.audio_channels = 2;
    113     params.audio_sampling_rate = 44100;
    114     params.is_audio_encrypted = false;
    115     params.duration_ms = kDefaultDurationInMs;
    116     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata");
    117     params.audio_extra_data = std::vector<uint8>(
    118         buffer->data(),
    119         buffer->data() + buffer->data_size());
    120     Start(params);
    121   }
    122 
    123   void StartVideoDecoderJob() {
    124     MediaPlayerHostMsg_DemuxerReady_Params params;
    125     params.video_codec = kCodecVP8;
    126     params.video_size = gfx::Size(320, 240);
    127     params.is_video_encrypted = false;
    128     params.duration_ms = kDefaultDurationInMs;
    129     Start(params);
    130   }
    131 
    132   // Starts decoding the data.
    133   void Start(const MediaPlayerHostMsg_DemuxerReady_Params& params) {
    134     player_->DemuxerReady(params);
    135     player_->Start();
    136   }
    137 
    138   MediaPlayerHostMsg_ReadFromDemuxerAck_Params
    139       CreateReadFromDemuxerAckForAudio() {
    140     MediaPlayerHostMsg_ReadFromDemuxerAck_Params ack_params;
    141     ack_params.type = DemuxerStream::AUDIO;
    142     ack_params.access_units.resize(1);
    143     ack_params.access_units[0].status = DemuxerStream::kOk;
    144     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-packet-0");
    145     ack_params.access_units[0].data = std::vector<uint8>(
    146         buffer->data(), buffer->data() + buffer->data_size());
    147     // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
    148     // NuMediaExtractor.cpp in Android source code.
    149     uint8 padding[4] = { 0xff , 0xff , 0xff , 0xff };
    150     ack_params.access_units[0].data.insert(
    151         ack_params.access_units[0].data.end(), padding, padding + 4);
    152     return ack_params;
    153   }
    154 
    155   MediaPlayerHostMsg_ReadFromDemuxerAck_Params
    156         CreateReadFromDemuxerAckForVideo() {
    157     MediaPlayerHostMsg_ReadFromDemuxerAck_Params ack_params;
    158     ack_params.type = DemuxerStream::VIDEO;
    159     ack_params.access_units.resize(1);
    160     ack_params.access_units[0].status = DemuxerStream::kOk;
    161     scoped_refptr<DecoderBuffer> buffer =
    162         ReadTestDataFile("vp8-I-frame-320x240");
    163     ack_params.access_units[0].data = std::vector<uint8>(
    164         buffer->data(), buffer->data() + buffer->data_size());
    165     return ack_params;
    166   }
    167 
    168   base::TimeTicks StartTimeTicks() {
    169     return player_->start_time_ticks_;
    170   }
    171 
    172  protected:
    173   scoped_ptr<MockMediaPlayerManager> manager_;
    174   scoped_ptr<MediaSourcePlayer> player_;
    175 
    176   DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest);
    177 };
    178 
    179 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithValidConfig) {
    180   if (!MediaCodecBridge::IsAvailable())
    181     return;
    182 
    183   // Test audio decoder job will be created when codec is successfully started.
    184   StartAudioDecoderJob();
    185   EXPECT_TRUE(NULL != GetMediaDecoderJob(true));
    186   EXPECT_EQ(1, manager_->num_requests());
    187 }
    188 
    189 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithInvalidConfig) {
    190   if (!MediaCodecBridge::IsAvailable())
    191     return;
    192 
    193   // Test audio decoder job will not be created when failed to start the codec.
    194   MediaPlayerHostMsg_DemuxerReady_Params params;
    195   params.audio_codec = kCodecVorbis;
    196   params.audio_channels = 2;
    197   params.audio_sampling_rate = 44100;
    198   params.is_audio_encrypted = false;
    199   params.duration_ms = kDefaultDurationInMs;
    200   uint8 invalid_codec_data[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
    201   params.audio_extra_data.insert(params.audio_extra_data.begin(),
    202                                  invalid_codec_data, invalid_codec_data + 4);
    203   Start(params);
    204   EXPECT_EQ(NULL, GetMediaDecoderJob(true));
    205   EXPECT_EQ(0, manager_->num_requests());
    206 }
    207 
    208 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithValidSurface) {
    209   if (!MediaCodecBridge::IsAvailable())
    210     return;
    211 
    212   // Test video decoder job will be created when surface is valid.
    213   scoped_refptr<gfx::SurfaceTextureBridge> surface_texture(
    214       new gfx::SurfaceTextureBridge(0));
    215   gfx::ScopedJavaSurface surface(surface_texture.get());
    216   StartVideoDecoderJob();
    217   // Video decoder job will not be created until surface is available.
    218   EXPECT_EQ(NULL, GetMediaDecoderJob(false));
    219   EXPECT_EQ(0, manager_->num_requests());
    220 
    221   player_->SetVideoSurface(surface.Pass());
    222   EXPECT_EQ(1u, manager_->last_seek_request_id());
    223   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    224   // The decoder job should be ready now.
    225   EXPECT_TRUE(NULL != GetMediaDecoderJob(false));
    226   EXPECT_EQ(1, manager_->num_requests());
    227 }
    228 
    229 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) {
    230   if (!MediaCodecBridge::IsAvailable())
    231     return;
    232 
    233   // Test video decoder job will be created when surface is valid.
    234   scoped_refptr<gfx::SurfaceTextureBridge> surface_texture(
    235       new gfx::SurfaceTextureBridge(0));
    236   gfx::ScopedJavaSurface surface(surface_texture.get());
    237   StartVideoDecoderJob();
    238   // Video decoder job will not be created until surface is available.
    239   EXPECT_EQ(NULL, GetMediaDecoderJob(false));
    240   EXPECT_EQ(0, manager_->num_requests());
    241 
    242   // Release the surface texture.
    243   surface_texture = NULL;
    244   player_->SetVideoSurface(surface.Pass());
    245   EXPECT_EQ(1u, manager_->last_seek_request_id());
    246   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    247   EXPECT_EQ(NULL, GetMediaDecoderJob(false));
    248   EXPECT_EQ(0, manager_->num_requests());
    249 }
    250 
    251 TEST_F(MediaSourcePlayerTest, ReadFromDemuxerAfterSeek) {
    252   if (!MediaCodecBridge::IsAvailable())
    253     return;
    254 
    255   // Test decoder job will resend a ReadFromDemuxer request after seek.
    256   StartAudioDecoderJob();
    257   EXPECT_TRUE(NULL != GetMediaDecoderJob(true));
    258   EXPECT_EQ(1, manager_->num_requests());
    259 
    260   // Initiate a seek
    261   player_->SeekTo(base::TimeDelta());
    262   EXPECT_EQ(1u, manager_->last_seek_request_id());
    263   // Sending back the seek ACK, this should trigger the player to call
    264   // OnReadFromDemuxer() again.
    265   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    266   EXPECT_EQ(2, manager_->num_requests());
    267 }
    268 
    269 TEST_F(MediaSourcePlayerTest, SetSurfaceWhileSeeking) {
    270   if (!MediaCodecBridge::IsAvailable())
    271     return;
    272 
    273   // Test SetVideoSurface() will not cause an extra seek while the player is
    274   // waiting for a seek ACK.
    275   scoped_refptr<gfx::SurfaceTextureBridge> surface_texture(
    276       new gfx::SurfaceTextureBridge(0));
    277   gfx::ScopedJavaSurface surface(surface_texture.get());
    278   StartVideoDecoderJob();
    279   // Player is still waiting for SetVideoSurface(), so no request is sent.
    280   EXPECT_EQ(0, manager_->num_requests());
    281   player_->SeekTo(base::TimeDelta());
    282   EXPECT_EQ(1u, manager_->last_seek_request_id());
    283 
    284   player_->SetVideoSurface(surface.Pass());
    285   EXPECT_TRUE(NULL == GetMediaDecoderJob(false));
    286   EXPECT_EQ(1u, manager_->last_seek_request_id());
    287 
    288   // Send the seek ack, player should start requesting data afterwards.
    289   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    290   EXPECT_TRUE(NULL != GetMediaDecoderJob(false));
    291   EXPECT_EQ(1, manager_->num_requests());
    292 }
    293 
    294 TEST_F(MediaSourcePlayerTest, StartAfterSeekFinish) {
    295   if (!MediaCodecBridge::IsAvailable())
    296     return;
    297 
    298   // Test decoder job will not start until all pending seek event is handled.
    299   MediaPlayerHostMsg_DemuxerReady_Params params;
    300   params.audio_codec = kCodecVorbis;
    301   params.audio_channels = 2;
    302   params.audio_sampling_rate = 44100;
    303   params.is_audio_encrypted = false;
    304   params.duration_ms = kDefaultDurationInMs;
    305   player_->DemuxerReady(params);
    306   EXPECT_EQ(NULL, GetMediaDecoderJob(true));
    307   EXPECT_EQ(0, manager_->num_requests());
    308 
    309   // Initiate a seek
    310   player_->SeekTo(base::TimeDelta());
    311   EXPECT_EQ(1u, manager_->last_seek_request_id());
    312 
    313   player_->Start();
    314   EXPECT_EQ(NULL, GetMediaDecoderJob(true));
    315   EXPECT_EQ(0, manager_->num_requests());
    316 
    317   // Sending back the seek ACK.
    318   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    319   EXPECT_TRUE(NULL != GetMediaDecoderJob(true));
    320   EXPECT_EQ(1, manager_->num_requests());
    321 }
    322 
    323 TEST_F(MediaSourcePlayerTest, StartImmediatelyAfterPause) {
    324   if (!MediaCodecBridge::IsAvailable())
    325     return;
    326 
    327   // Test that if the decoding job is not fully stopped after Pause(),
    328   // calling Start() will be a noop.
    329   StartAudioDecoderJob();
    330 
    331   MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
    332   EXPECT_TRUE(NULL != decoder_job);
    333   EXPECT_EQ(1, manager_->num_requests());
    334   EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
    335 
    336   // Sending data to player.
    337   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForAudio());
    338   EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
    339 
    340   // Decoder job will not immediately stop after Pause() since it is
    341   // running on another thread.
    342   player_->Pause();
    343   EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
    344 
    345   // Nothing happens when calling Start() again.
    346   player_->Start();
    347   // Verify that Start() will not destroy and recreate the decoder job.
    348   EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
    349   EXPECT_EQ(1, manager_->num_requests());
    350   EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
    351   manager_->message_loop()->Run();
    352   // The decoder job should finish and a new request will be sent.
    353   EXPECT_EQ(2, manager_->num_requests());
    354   EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
    355 }
    356 
    357 TEST_F(MediaSourcePlayerTest, DecoderJobsCannotStartWithoutAudio) {
    358   if (!MediaCodecBridge::IsAvailable())
    359     return;
    360 
    361   // Test that when Start() is called, video decoder jobs will wait for audio
    362   // decoder job before start decoding the data.
    363   MediaPlayerHostMsg_DemuxerReady_Params params;
    364   params.audio_codec = kCodecVorbis;
    365   params.audio_channels = 2;
    366   params.audio_sampling_rate = 44100;
    367   params.is_audio_encrypted = false;
    368   scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata");
    369   params.audio_extra_data = std::vector<uint8>(
    370       buffer->data(),
    371       buffer->data() + buffer->data_size());
    372   params.video_codec = kCodecVP8;
    373   params.video_size = gfx::Size(320, 240);
    374   params.is_video_encrypted = false;
    375   params.duration_ms = kDefaultDurationInMs;
    376   Start(params);
    377   EXPECT_EQ(0, manager_->num_requests());
    378 
    379   scoped_refptr<gfx::SurfaceTextureBridge> surface_texture(
    380       new gfx::SurfaceTextureBridge(0));
    381   gfx::ScopedJavaSurface surface(surface_texture.get());
    382   player_->SetVideoSurface(surface.Pass());
    383   EXPECT_EQ(1u, manager_->last_seek_request_id());
    384   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    385 
    386   MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true);
    387   MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false);
    388   EXPECT_EQ(2, manager_->num_requests());
    389   EXPECT_FALSE(audio_decoder_job->is_decoding());
    390   EXPECT_FALSE(video_decoder_job->is_decoding());
    391 
    392   // Sending audio data to player, audio decoder should not start.
    393   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForVideo());
    394   EXPECT_FALSE(video_decoder_job->is_decoding());
    395 
    396   // Sending video data to player, both decoders should start now.
    397   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForAudio());
    398   EXPECT_TRUE(audio_decoder_job->is_decoding());
    399   EXPECT_TRUE(video_decoder_job->is_decoding());
    400 }
    401 
    402 // Disabled due to http://crbug.com/266041.
    403 // TODO(xhwang/qinmin): Fix this test and reenable it.
    404 TEST_F(MediaSourcePlayerTest,
    405        DISABLED_StartTimeTicksResetAfterDecoderUnderruns) {
    406   if (!MediaCodecBridge::IsAvailable())
    407     return;
    408 
    409   // Test start time ticks will reset after decoder job underruns.
    410   StartAudioDecoderJob();
    411   EXPECT_TRUE(NULL != GetMediaDecoderJob(true));
    412   EXPECT_EQ(1, manager_->num_requests());
    413   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForAudio());
    414   EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
    415 
    416   manager_->message_loop()->Run();
    417   // The decoder job should finish and a new request will be sent.
    418   EXPECT_EQ(2, manager_->num_requests());
    419   EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
    420   base::TimeTicks previous = StartTimeTicks();
    421 
    422   // Let the decoder timeout and execute the OnDecoderStarved() callback.
    423   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
    424   manager_->message_loop()->RunUntilIdle();
    425 
    426   // Send new data to the decoder. This should reset the start time ticks.
    427   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForAudio());
    428   base::TimeTicks current = StartTimeTicks();
    429   EXPECT_LE(100.0, (current - previous).InMillisecondsF());
    430 }
    431 
    432 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterInputEOS) {
    433   if (!MediaCodecBridge::IsAvailable())
    434     return;
    435 
    436   // Test MediaSourcePlayer will not request for new data after input EOS is
    437   // reached.
    438   scoped_refptr<gfx::SurfaceTextureBridge> surface_texture(
    439       new gfx::SurfaceTextureBridge(0));
    440   gfx::ScopedJavaSurface surface(surface_texture.get());
    441   player_->SetVideoSurface(surface.Pass());
    442   StartVideoDecoderJob();
    443   player_->OnSeekRequestAck(manager_->last_seek_request_id());
    444   EXPECT_EQ(1, manager_->num_requests());
    445   // Send the first input chunk.
    446   player_->ReadFromDemuxerAck(CreateReadFromDemuxerAckForVideo());
    447   manager_->message_loop()->Run();
    448   EXPECT_EQ(2, manager_->num_requests());
    449 
    450   // Send EOS.
    451   MediaPlayerHostMsg_ReadFromDemuxerAck_Params ack_params;
    452   ack_params.type = DemuxerStream::VIDEO;
    453   ack_params.access_units.resize(1);
    454   ack_params.access_units[0].status = DemuxerStream::kOk;
    455   ack_params.access_units[0].end_of_stream = true;
    456   player_->ReadFromDemuxerAck(ack_params);
    457   manager_->message_loop()->Run();
    458   // No more request for data should be made.
    459   EXPECT_EQ(2, manager_->num_requests());
    460 }
    461 
    462 }  // namespace media
    463