Home | History | Annotate | Download | only in media
      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 "base/synchronization/waitable_event.h"
      6 #include "base/task_runner_util.h"
      7 #include "base/threading/thread.h"
      8 #include "content/renderer/media/rtc_video_decoder_factory_tv.h"
      9 #include "media/base/decoder_buffer.h"
     10 #include "media/base/video_decoder_config.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 #include "third_party/webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
     14 #include "ui/gfx/rect.h"
     15 
     16 using ::testing::_;
     17 using ::testing::Return;
     18 
     19 namespace content {
     20 
     21 class RTCVideoDecoderFactoryTvTest : public ::testing::Test {
     22  public:
     23   RTCVideoDecoderFactoryTvTest()
     24       : factory_(new RTCVideoDecoderFactoryTv),
     25         decoder_(NULL),
     26         is_demuxer_acquired_(false),
     27         video_stream_(NULL),
     28         size_(1280, 720),
     29         input_image_(&data_, sizeof(data_), sizeof(data_)),
     30         data_('a'),
     31         read_event_(false, false),
     32         decoder_thread_("Test decoder thread"),
     33         decoder_thread_event_(false, false) {
     34     memset(&codec_, 0, sizeof(codec_));
     35     message_loop_proxy_ = base::MessageLoopProxy::current();
     36     input_image_._frameType = webrtc::kKeyFrame;
     37     input_image_._encodedWidth = size_.width();
     38     input_image_._encodedHeight = size_.height();
     39     input_image_._completeFrame = true;
     40     decoder_thread_.Start();
     41   }
     42 
     43   virtual ~RTCVideoDecoderFactoryTvTest() {
     44     if (is_demuxer_acquired_) {
     45       factory_->ReleaseDemuxer();
     46       is_demuxer_acquired_ = false;
     47     }
     48     if (decoder_) {
     49       factory_->DestroyVideoDecoder(decoder_);
     50       decoder_ = NULL;
     51     }
     52 
     53     decoder_thread_.Stop();
     54   }
     55 
     56   void ReadCallback(media::DemuxerStream::Status status,
     57                     const scoped_refptr<media::DecoderBuffer>& decoder_buffer) {
     58     switch (status) {
     59       case media::DemuxerStream::kOk:
     60         EXPECT_TRUE(decoder_buffer);
     61         break;
     62       case media::DemuxerStream::kConfigChanged:
     63       case media::DemuxerStream::kAborted:
     64         EXPECT_FALSE(decoder_buffer);
     65         break;
     66     }
     67     last_decoder_buffer_ = decoder_buffer;
     68     read_event_.Signal();
     69   }
     70 
     71   void ExpectEqualsAndSignal(int32_t expected, int32_t actual) {
     72     EXPECT_EQ(expected, actual);
     73     decoder_thread_event_.Signal();
     74   }
     75 
     76   void ExpectNotEqualsAndSignal(int32_t unexpected, int32_t actual) {
     77     EXPECT_NE(unexpected, actual);
     78     decoder_thread_event_.Signal();
     79   }
     80 
     81  protected:
     82   base::Callback<void(int32_t)> BindExpectEquals(int32_t expected) {
     83     return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectEqualsAndSignal,
     84                       base::Unretained(this),
     85                       expected);
     86   }
     87 
     88   base::Callback<void(int32_t)> BindExpectNotEquals(int32_t unexpected) {
     89     return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectNotEqualsAndSignal,
     90                       base::Unretained(this),
     91                       unexpected);
     92   }
     93 
     94   base::Callback<int32_t(void)> BindInitDecode(const webrtc::VideoCodec* codec,
     95                                                int32_t num_cores) {
     96     return base::Bind(&webrtc::VideoDecoder::InitDecode,
     97                       base::Unretained(decoder_),
     98                       codec,
     99                       num_cores);
    100   }
    101 
    102   base::Callback<int32_t(void)> BindDecode(
    103       const webrtc::EncodedImage& input_image,
    104       bool missing_frames,
    105       const webrtc::RTPFragmentationHeader* fragmentation,
    106       const webrtc::CodecSpecificInfo* info,
    107       int64_t render_time_ms) {
    108     return base::Bind(&webrtc::VideoDecoder::Decode,
    109                       base::Unretained(decoder_),
    110                       input_image,
    111                       missing_frames,
    112                       fragmentation,
    113                       info,
    114                       render_time_ms);
    115   }
    116 
    117   void CreateDecoderAndAcquireDemuxer() {
    118     decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
    119     ASSERT_TRUE(decoder_);
    120     ASSERT_TRUE(factory_->AcquireDemuxer());
    121     is_demuxer_acquired_ = true;
    122   }
    123 
    124   void InitDecode() {
    125     codec_.codecType = webrtc::kVideoCodecVP8;
    126     codec_.width = size_.width();
    127     codec_.height = size_.height();
    128     base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
    129                                      FROM_HERE,
    130                                      BindInitDecode(&codec_, 1),
    131                                      BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
    132     decoder_thread_event_.Wait();
    133     base::PostTaskAndReplyWithResult(
    134         decoder_thread_.message_loop_proxy(),
    135         FROM_HERE,
    136         base::Bind(&webrtc::VideoDecoder::RegisterDecodeCompleteCallback,
    137                    base::Unretained(decoder_),
    138                    &decode_complete_callback_),
    139         BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
    140     decoder_thread_event_.Wait();
    141   }
    142 
    143   void GetVideoStream() {
    144     video_stream_ = factory_->GetStream(media::DemuxerStream::VIDEO);
    145     ASSERT_TRUE(video_stream_);
    146     EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec());
    147     EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size());
    148     EXPECT_EQ(gfx::Rect(size_),
    149               video_stream_->video_decoder_config().visible_rect());
    150     EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size());
    151   }
    152 
    153   void PostDecodeAndWait(int32_t expected,
    154                          const webrtc::EncodedImage& input_image,
    155                          bool missing_frames,
    156                          const webrtc::RTPFragmentationHeader* fragmentation,
    157                          const webrtc::CodecSpecificInfo* info,
    158                          int64_t render_time_ms) {
    159     base::PostTaskAndReplyWithResult(
    160         decoder_thread_.message_loop_proxy(),
    161         FROM_HERE,
    162         BindDecode(
    163             input_image, missing_frames, fragmentation, info, render_time_ms),
    164         BindExpectEquals(expected));
    165     decoder_thread_event_.Wait();
    166   }
    167 
    168   RTCVideoDecoderFactoryTv* factory_;
    169   webrtc::VideoDecoder* decoder_;
    170   bool is_demuxer_acquired_;
    171   base::MessageLoopProxy* message_loop_proxy_;
    172   media::DemuxerStream* video_stream_;
    173   webrtc::VideoCodec codec_;
    174   gfx::Size size_;
    175   webrtc::EncodedImage input_image_;
    176   unsigned char data_;
    177   webrtc::MockDecodedImageCallback decode_complete_callback_;
    178   base::WaitableEvent read_event_;
    179   base::Thread decoder_thread_;
    180   base::WaitableEvent decoder_thread_event_;
    181   scoped_refptr<media::DecoderBuffer> last_decoder_buffer_;
    182 };
    183 
    184 TEST_F(RTCVideoDecoderFactoryTvTest, CreateAndDestroyDecoder) {
    185   // Only VP8 decoder is supported.
    186   ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecI420));
    187   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
    188   ASSERT_TRUE(decoder_);
    189   // Only one decoder at a time will be created.
    190   ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8));
    191   factory_->DestroyVideoDecoder(decoder_);
    192 }
    193 
    194 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerAfterCreateDecoder) {
    195   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
    196   ASSERT_TRUE(decoder_);
    197   ASSERT_TRUE(factory_->AcquireDemuxer());
    198   is_demuxer_acquired_ = true;
    199   // Demuxer can be acquired only once.
    200   ASSERT_FALSE(factory_->AcquireDemuxer());
    201 }
    202 
    203 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerBeforeCreateDecoder) {
    204   ASSERT_TRUE(factory_->AcquireDemuxer());
    205   is_demuxer_acquired_ = true;
    206   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
    207   ASSERT_TRUE(decoder_);
    208 }
    209 
    210 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnNonVP8Codec) {
    211   CreateDecoderAndAcquireDemuxer();
    212   codec_.codecType = webrtc::kVideoCodecI420;
    213   base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
    214                                    FROM_HERE,
    215                                    BindInitDecode(&codec_, 1),
    216                                    BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
    217   decoder_thread_event_.Wait();
    218 }
    219 
    220 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnFeedbackMode) {
    221   CreateDecoderAndAcquireDemuxer();
    222   codec_.codecType = webrtc::kVideoCodecVP8;
    223   codec_.codecSpecific.VP8.feedbackModeOn = true;
    224   base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
    225                                    FROM_HERE,
    226                                    BindInitDecode(&codec_, 1),
    227                                    BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
    228   decoder_thread_event_.Wait();
    229 }
    230 
    231 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorBeforeInitDecode) {
    232   CreateDecoderAndAcquireDemuxer();
    233   PostDecodeAndWait(
    234       WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0);
    235 }
    236 
    237 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnDamagedBitstream) {
    238   CreateDecoderAndAcquireDemuxer();
    239   InitDecode();
    240   input_image_._completeFrame = false;
    241   PostDecodeAndWait(
    242       WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
    243 }
    244 
    245 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnMissingFrames) {
    246   CreateDecoderAndAcquireDemuxer();
    247   InitDecode();
    248   PostDecodeAndWait(
    249       WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0);
    250 }
    251 
    252 TEST_F(RTCVideoDecoderFactoryTvTest, GetNonVideoStreamFails) {
    253   CreateDecoderAndAcquireDemuxer();
    254   InitDecode();
    255   EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::AUDIO));
    256   EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::UNKNOWN));
    257 }
    258 
    259 TEST_F(RTCVideoDecoderFactoryTvTest, GetVideoStreamSucceeds) {
    260   CreateDecoderAndAcquireDemuxer();
    261   InitDecode();
    262   GetVideoStream();
    263 }
    264 
    265 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) {
    266   CreateDecoderAndAcquireDemuxer();
    267   InitDecode();
    268   GetVideoStream();
    269   input_image_._frameType = webrtc::kDeltaFrame;
    270   PostDecodeAndWait(
    271       WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
    272 }
    273 
    274 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeUpdatesVideoSizeOnKeyFrame) {
    275   CreateDecoderAndAcquireDemuxer();
    276   InitDecode();
    277   GetVideoStream();
    278   gfx::Size new_size(320, 240);
    279   input_image_._encodedWidth = new_size.width();
    280   input_image_._encodedHeight = new_size.height();
    281   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
    282   EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size());
    283   EXPECT_EQ(gfx::Rect(new_size),
    284             video_stream_->video_decoder_config().visible_rect());
    285   EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size());
    286 }
    287 
    288 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeAdjustsTimestampFromZero) {
    289   CreateDecoderAndAcquireDemuxer();
    290   InitDecode();
    291   GetVideoStream();
    292   PostDecodeAndWait(
    293       WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000);
    294   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
    295                                  base::Unretained(this)));
    296   read_event_.Wait();
    297   EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
    298             last_decoder_buffer_->GetTimestamp());
    299   PostDecodeAndWait(
    300       WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033);
    301   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
    302                                  base::Unretained(this)));
    303   read_event_.Wait();
    304   EXPECT_EQ(base::TimeDelta::FromMilliseconds(33),
    305             last_decoder_buffer_->GetTimestamp());
    306 }
    307 
    308 TEST_F(RTCVideoDecoderFactoryTvTest, DecodePassesDataCorrectly) {
    309   CreateDecoderAndAcquireDemuxer();
    310   InitDecode();
    311   GetVideoStream();
    312   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
    313                                  base::Unretained(this)));
    314   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
    315   read_event_.Wait();
    316   EXPECT_EQ(static_cast<int>(sizeof(data_)),
    317             last_decoder_buffer_->GetDataSize());
    318   EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]);
    319 }
    320 
    321 TEST_F(RTCVideoDecoderFactoryTvTest, NextReadTriggersDecodeCompleteCallback) {
    322   EXPECT_CALL(decode_complete_callback_, Decoded(_))
    323       .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
    324 
    325   CreateDecoderAndAcquireDemuxer();
    326   InitDecode();
    327   GetVideoStream();
    328   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
    329                                  base::Unretained(this)));
    330   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
    331   read_event_.Wait();
    332   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
    333                                  base::Unretained(this)));
    334 }
    335 
    336 TEST_F(RTCVideoDecoderFactoryTvTest, ResetReturnsOk) {
    337   CreateDecoderAndAcquireDemuxer();
    338   InitDecode();
    339   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Reset());
    340 }
    341 
    342 TEST_F(RTCVideoDecoderFactoryTvTest, ReleaseReturnsOk) {
    343   CreateDecoderAndAcquireDemuxer();
    344   InitDecode();
    345   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
    346 }
    347 
    348 }  // content
    349