OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Joint encoder and decoder testing. | 5 // Joint encoder and decoder testing. |
6 // These tests operate directly on the VP8 encoder and decoder, not the | 6 // These tests operate directly on the VP8 encoder and decoder, not the |
7 // transport layer, and are targeted at validating the bit stream. | 7 // transport layer, and are targeted at validating the bit stream. |
8 | 8 |
9 #include <gtest/gtest.h> | 9 #include <gtest/gtest.h> |
10 | 10 |
| 11 #include "base/bind.h" |
11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "media/cast/cast_environment.h" |
| 14 #include "media/cast/test/fake_task_runner.h" |
12 #include "media/cast/test/video_utility.h" | 15 #include "media/cast/test/video_utility.h" |
13 #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h" | 16 #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h" |
14 #include "media/cast/video_sender/codecs/vp8/vp8_encoder.h" | 17 #include "media/cast/video_sender/codecs/vp8/vp8_encoder.h" |
15 | 18 |
16 namespace media { | 19 namespace media { |
17 namespace cast { | 20 namespace cast { |
18 | 21 |
| 22 static const int64 kStartMillisecond = GG_INT64_C(1245); |
| 23 static const int kWidth = 1280; |
| 24 static const int kHeight = 720; |
| 25 static const int kStartbitrate = 4000000; |
| 26 static const int kMaxQp = 54; |
| 27 static const int kMinQp = 4; |
| 28 static const int kMaxFrameRate = 30; |
| 29 |
19 namespace { | 30 namespace { |
20 const int kWidth = 1280; | 31 class EncodeDecodeTestFrameCallback : |
21 const int kHeight = 720; | 32 public base::RefCountedThreadSafe<EncodeDecodeTestFrameCallback> { |
22 const int kStartbitrate = 4000000; | 33 public: |
23 const int kMaxQp = 54; | 34 EncodeDecodeTestFrameCallback() |
24 const int kMinQp = 4; | 35 : num_called_(0) { |
25 const int kMaxFrameRate = 30; | 36 original_frame_.width = kWidth; |
| 37 original_frame_.height = kHeight; |
| 38 } |
| 39 |
| 40 void SetFrameStartValue(int start_value) { |
| 41 PopulateVideoFrame(&original_frame_, start_value); |
| 42 } |
| 43 |
| 44 void DecodeComplete(scoped_ptr<I420VideoFrame> decoded_frame, |
| 45 const base::TimeTicks& render_time) { |
| 46 ++num_called_; |
| 47 // Compare frames. |
| 48 // Compare resolution. |
| 49 EXPECT_EQ(original_frame_.width, decoded_frame->width); |
| 50 EXPECT_EQ(original_frame_.height, decoded_frame->height); |
| 51 // Compare data. |
| 52 EXPECT_GT(I420PSNR(original_frame_, *(decoded_frame.get())), 40.0); |
| 53 } |
| 54 |
| 55 int num_called() const { |
| 56 return num_called_; |
| 57 } |
| 58 |
| 59 protected: |
| 60 virtual ~EncodeDecodeTestFrameCallback() {} |
| 61 |
| 62 private: |
| 63 friend class base::RefCountedThreadSafe<EncodeDecodeTestFrameCallback>; |
| 64 |
| 65 int num_called_; |
| 66 I420VideoFrame original_frame_; |
| 67 }; |
26 } // namespace | 68 } // namespace |
27 | 69 |
28 class EncodeDecodeTest : public ::testing::Test { | 70 class EncodeDecodeTest : public ::testing::Test { |
29 protected: | 71 protected: |
30 EncodeDecodeTest() { | 72 EncodeDecodeTest() |
| 73 : task_runner_(new test::FakeTaskRunner(&testing_clock_)), |
| 74 // CastEnvironment will only be used by the vp8 decoder; Enable only the |
| 75 // video decoder and main threads. |
| 76 cast_environment_(new CastEnvironment(&testing_clock_, task_runner_, |
| 77 NULL, NULL, NULL, task_runner_)), |
| 78 test_callback_(new EncodeDecodeTestFrameCallback()) { |
| 79 testing_clock_.Advance( |
| 80 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
31 encoder_config_.max_number_of_video_buffers_used = 1; | 81 encoder_config_.max_number_of_video_buffers_used = 1; |
32 encoder_config_.number_of_cores = 1; | 82 encoder_config_.number_of_cores = 1; |
33 encoder_config_.width = kWidth; | 83 encoder_config_.width = kWidth; |
34 encoder_config_.height = kHeight; | 84 encoder_config_.height = kHeight; |
35 encoder_config_.start_bitrate = kStartbitrate; | 85 encoder_config_.start_bitrate = kStartbitrate; |
36 encoder_config_.min_qp = kMaxQp; | 86 encoder_config_.min_qp = kMaxQp; |
37 encoder_config_.min_qp = kMinQp; | 87 encoder_config_.min_qp = kMinQp; |
38 encoder_config_.max_frame_rate = kMaxFrameRate; | 88 encoder_config_.max_frame_rate = kMaxFrameRate; |
39 int max_unacked_frames = 1; | 89 int max_unacked_frames = 1; |
40 encoder_.reset(new Vp8Encoder(encoder_config_, max_unacked_frames)); | 90 encoder_.reset(new Vp8Encoder(encoder_config_, max_unacked_frames)); |
41 // Initialize to use one core. | 91 // Initialize to use one core. |
42 decoder_.reset(new Vp8Decoder(1)); | 92 decoder_.reset(new Vp8Decoder(1, cast_environment_)); |
43 } | 93 } |
44 | 94 |
45 virtual void SetUp() { | 95 virtual ~EncodeDecodeTest() {} |
| 96 |
| 97 virtual void SetUp() OVERRIDE { |
46 // Create test frame. | 98 // Create test frame. |
47 int start_value = 10; // Random value to start from. | 99 int start_value = 10; // Random value to start from. |
48 video_frame_.reset(new I420VideoFrame()); | 100 video_frame_.reset(new I420VideoFrame()); |
49 video_frame_->width = encoder_config_.width; | 101 video_frame_->width = encoder_config_.width; |
50 video_frame_->height = encoder_config_.height; | 102 video_frame_->height = encoder_config_.height; |
51 PopulateVideoFrame(video_frame_.get(), start_value); | 103 PopulateVideoFrame(video_frame_.get(), start_value); |
| 104 test_callback_->SetFrameStartValue(start_value); |
52 } | 105 } |
53 | 106 |
54 virtual void TearDown() { | 107 virtual void TearDown() OVERRIDE { |
55 delete [] video_frame_->y_plane.data; | 108 delete [] video_frame_->y_plane.data; |
56 delete [] video_frame_->u_plane.data; | 109 delete [] video_frame_->u_plane.data; |
57 delete [] video_frame_->v_plane.data; | 110 delete [] video_frame_->v_plane.data; |
58 } | 111 } |
59 | 112 |
60 void Compare(const I420VideoFrame& original_image, | |
61 const I420VideoFrame& decoded_image) { | |
62 // Compare resolution. | |
63 EXPECT_EQ(original_image.width, decoded_image.width); | |
64 EXPECT_EQ(original_image.height, decoded_image.height); | |
65 // Compare data. | |
66 EXPECT_GT(I420PSNR(original_image, decoded_image), 40.0); | |
67 } | |
68 | |
69 VideoSenderConfig encoder_config_; | 113 VideoSenderConfig encoder_config_; |
70 scoped_ptr<Vp8Encoder> encoder_; | 114 scoped_ptr<Vp8Encoder> encoder_; |
71 scoped_ptr<Vp8Decoder> decoder_; | 115 scoped_ptr<Vp8Decoder> decoder_; |
72 scoped_ptr<I420VideoFrame> video_frame_; | 116 scoped_ptr<I420VideoFrame> video_frame_; |
| 117 base::SimpleTestTickClock testing_clock_; |
| 118 scoped_refptr<test::FakeTaskRunner> task_runner_; |
| 119 scoped_refptr<CastEnvironment> cast_environment_; |
| 120 scoped_refptr<EncodeDecodeTestFrameCallback> test_callback_; |
73 }; | 121 }; |
74 | 122 |
75 TEST_F(EncodeDecodeTest, BasicEncodeDecode) { | 123 TEST_F(EncodeDecodeTest, BasicEncodeDecode) { |
76 EncodedVideoFrame encoded_frame; | 124 EncodedVideoFrame encoded_frame; |
77 I420VideoFrame decoded_frame; | |
78 // Encode frame. | 125 // Encode frame. |
79 encoder_->Encode(*(video_frame_.get()), &encoded_frame); | 126 encoder_->Encode(*(video_frame_.get()), &encoded_frame); |
80 EXPECT_GT(encoded_frame.data.size(), GG_UINT64_C(0)); | 127 EXPECT_GT(encoded_frame.data.size(), GG_UINT64_C(0)); |
81 // Decode frame. | 128 // Decode frame. |
82 decoder_->Decode(encoded_frame, &decoded_frame); | 129 decoder_->Decode(&encoded_frame, base::TimeTicks(), base::Bind( |
83 // Validate data. | 130 &EncodeDecodeTestFrameCallback::DecodeComplete, test_callback_)); |
84 Compare(*(video_frame_.get()), decoded_frame); | 131 task_runner_->RunTasks(); |
85 } | 132 } |
86 | 133 |
87 } // namespace cast | 134 } // namespace cast |
88 } // namespace media | 135 } // namespace media |
OLD | NEW |