Home | History | Annotate | Download | only in base
      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 #include "chromecast/media/cma/base/mock_frame_consumer.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/location.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "base/time/time.h"
     11 #include "chromecast/media/cma/base/coded_frame_provider.h"
     12 #include "chromecast/media/cma/base/decoder_buffer_base.h"
     13 #include "chromecast/media/cma/base/frame_generator_for_test.h"
     14 #include "media/base/video_decoder_config.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace chromecast {
     18 namespace media {
     19 
     20 MockFrameConsumer::MockFrameConsumer(
     21     CodedFrameProvider* coded_frame_provider)
     22     : coded_frame_provider_(coded_frame_provider),
     23       pattern_idx_(0),
     24       last_read_aborted_by_flush_(false) {
     25 }
     26 
     27 MockFrameConsumer::~MockFrameConsumer() {
     28 }
     29 
     30 void MockFrameConsumer::Configure(
     31     const std::vector<bool>& delayed_task_pattern,
     32     bool last_read_aborted_by_flush,
     33     scoped_ptr<FrameGeneratorForTest> frame_generator) {
     34   delayed_task_pattern_ = delayed_task_pattern;
     35   last_read_aborted_by_flush_ = last_read_aborted_by_flush;
     36   frame_generator_.reset(frame_generator.release());
     37 }
     38 
     39 void MockFrameConsumer::Start(const base::Closure& done_cb) {
     40   done_cb_ = done_cb;
     41 
     42   pattern_idx_ = 0;
     43 
     44   base::MessageLoopProxy::current()->PostTask(
     45       FROM_HERE,
     46       base::Bind(&MockFrameConsumer::ReadFrame, base::Unretained(this)));
     47 }
     48 
     49 void MockFrameConsumer::ReadFrame() {
     50   // Once all the frames have been read, flush the frame provider.
     51   if (frame_generator_->RemainingFrameCount() == 0 &&
     52       !last_read_aborted_by_flush_) {
     53     coded_frame_provider_->Flush(
     54         base::Bind(&MockFrameConsumer::OnFlushCompleted,
     55                    base::Unretained(this)));
     56     return;
     57   }
     58 
     59   coded_frame_provider_->Read(
     60       base::Bind(&MockFrameConsumer::OnNewFrame,
     61                  base::Unretained(this)));
     62 
     63   // The last read is right away aborted by a Flush.
     64   if (frame_generator_->RemainingFrameCount() == 0 &&
     65       last_read_aborted_by_flush_) {
     66     coded_frame_provider_->Flush(
     67         base::Bind(&MockFrameConsumer::OnFlushCompleted,
     68                    base::Unretained(this)));
     69     return;
     70   }
     71 }
     72 
     73 void MockFrameConsumer::OnNewFrame(
     74     const scoped_refptr<DecoderBufferBase>& buffer,
     75     const ::media::AudioDecoderConfig& audio_config,
     76     const ::media::VideoDecoderConfig& video_config) {
     77   bool ref_has_config = frame_generator_->HasDecoderConfig();
     78   scoped_refptr<DecoderBufferBase> ref_buffer = frame_generator_->Generate();
     79 
     80   ASSERT_TRUE(buffer.get());
     81   ASSERT_TRUE(ref_buffer.get());
     82 
     83   EXPECT_EQ(video_config.IsValidConfig(), ref_has_config);
     84 
     85   EXPECT_EQ(buffer->end_of_stream(), ref_buffer->end_of_stream());
     86   if (!ref_buffer->end_of_stream()) {
     87     EXPECT_EQ(buffer->timestamp(), ref_buffer->timestamp());
     88     ASSERT_EQ(buffer->data_size(), ref_buffer->data_size());
     89     for (size_t k = 0; k < ref_buffer->data_size(); k++)
     90       EXPECT_EQ(buffer->data()[k], ref_buffer->data()[k]);
     91   }
     92 
     93   bool delayed = delayed_task_pattern_[pattern_idx_];
     94   pattern_idx_ = (pattern_idx_ + 1) % delayed_task_pattern_.size();
     95 
     96   if (delayed) {
     97     base::MessageLoopProxy::current()->PostDelayedTask(
     98         FROM_HERE,
     99         base::Bind(&MockFrameConsumer::ReadFrame,
    100                    base::Unretained(this)),
    101         base::TimeDelta::FromMilliseconds(1));
    102   } else {
    103     base::MessageLoopProxy::current()->PostTask(
    104         FROM_HERE,
    105         base::Bind(&MockFrameConsumer::ReadFrame,
    106                    base::Unretained(this)));
    107   }
    108 }
    109 
    110 void MockFrameConsumer::OnFlushCompleted() {
    111   EXPECT_EQ(frame_generator_->RemainingFrameCount(), 0);
    112   done_cb_.Run();
    113 }
    114 
    115 }  // namespace media
    116 }  // namespace chromecast
    117