summaryrefslogtreecommitdiff
path: root/chromium/media/mojo/services/webrtc_video_perf_recorder_unittest.cc
blob: 8d9a9aba68276f9179da66671307928157f7e3c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "base/bind.h"
#include "media/base/video_codecs.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "media/mojo/services/webrtc_video_perf_recorder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;

namespace media {

namespace {

// Aliases for readability.
const bool kDecode = true;
const bool kEncode = false;
const VideoCodecProfile kProfileA = H264PROFILE_MIN;
const VideoCodecProfile kProfileB = VP9PROFILE_MIN;
const VideoCodecProfile kProfileC = VP8PROFILE_MIN;
const VideoCodecProfile kProfileUnknown = VIDEO_CODEC_PROFILE_UNKNOWN;
const int kPixelSizeA = 1280 * 720;
const int kPixelSizeB = 1920 * 1080;
const bool kHw = true;
const bool kSw = false;

MATCHER_P(MojoEq, value, "") {
  return arg.Equals(value);
}

}  // namespace

using Features = media::mojom::WebrtcPredictionFeatures;
using VideoStats = media::mojom::WebrtcVideoStats;

class WebrtcVideoPerfRecorderTest : public ::testing::Test {
 public:
  void MakeRecorder() {
    recorder_ = std::make_unique<WebrtcVideoPerfRecorder>(
        base::BindRepeating(&WebrtcVideoPerfRecorderTest::SavePerfCallback,
                            base::Unretained(this)));
  }
  ~WebrtcVideoPerfRecorderTest() override = default;

  MOCK_METHOD3(SavePerfCallback,
               void(media::mojom::WebrtcPredictionFeatures features,
                    media::mojom::WebrtcVideoStats targets,
                    base::OnceClosure save_done_cb));

 protected:
  std::unique_ptr<WebrtcVideoPerfRecorder> recorder_;
};

TEST_F(WebrtcVideoPerfRecorderTest, SaveOnNewConfig) {
  MakeRecorder();
  // Update decode entry.
  recorder_->UpdateRecord(Features::New(kDecode, kProfileA, kPixelSizeA, kSw),
                          VideoStats::New(11, 3, 12.0f));
  // New data for the same decode entry should not result in a callback.
  recorder_->UpdateRecord(Features::New(kDecode, kProfileA, kPixelSizeA, kSw),
                          VideoStats::New(111, 8, 11.7f));

  // Update encode entry. This should not result in a callback either since
  // encode and decode states are tracked individually.
  recorder_->UpdateRecord(Features::New(kEncode, kProfileC, kPixelSizeA, kSw),
                          VideoStats::New(13, 7, 17.0f));

  // Expect save with the previous state upon changing to a HW decoder.
  EXPECT_CALL(*this,
              SavePerfCallback((Features(kDecode, kProfileA, kPixelSizeA, kSw)),
                               (VideoStats(111, 8, 11.7f)), _))
      .Times(1);
  recorder_->UpdateRecord(Features::New(kDecode, kProfileA, kPixelSizeA, kHw),
                          VideoStats::New(15, 4, 9.0f));

  // Expect save with the previous state upon changing decode pixel size.
  EXPECT_CALL(*this,
              SavePerfCallback((Features(kDecode, kProfileA, kPixelSizeA, kHw)),
                               (VideoStats(15, 4, 9.0f)), _))
      .Times(1);
  recorder_->UpdateRecord(Features::New(kDecode, kProfileA, kPixelSizeB, kHw),
                          VideoStats::New(17, 6, 14.0f));

  // Expect save with the previous state upon changing decode codec profile.
  EXPECT_CALL(*this,
              SavePerfCallback((Features(kDecode, kProfileA, kPixelSizeB, kHw)),
                               (VideoStats(17, 6, 14.0f)), _))
      .Times(1);
  recorder_->UpdateRecord(Features::New(kDecode, kProfileB, kPixelSizeB, kHw),
                          VideoStats::New(21, 5, 13.0f));

  // An empty record saves the current state.
  EXPECT_CALL(*this,
              SavePerfCallback((Features(kDecode, kProfileB, kPixelSizeB, kHw)),
                               (VideoStats(21, 5, 13.0f)), _))
      .Times(1);
  recorder_->UpdateRecord(Features::New(kDecode, kProfileUnknown, 0, kHw),
                          VideoStats::New(0, 0, 0.0f));

  EXPECT_CALL(*this,
              SavePerfCallback((Features(kEncode, kProfileC, kPixelSizeA, kSw)),
                               (VideoStats(13, 7, 17.0f)), _))
      .Times(1);
  recorder_->UpdateRecord(Features::New(kEncode, kProfileUnknown, 0, kHw),
                          VideoStats::New(0, 0, 0.0f));
}

TEST_F(WebrtcVideoPerfRecorderTest, SaveOnDestruction) {
  MakeRecorder();
  // Update decode entry.
  recorder_->UpdateRecord(Features::New(kDecode, kProfileA, kPixelSizeA, kSw),
                          VideoStats::New(11, 3, 12.0f));
  // Update encode entry. This should not result in a callback either since
  // encode and decode states are tracked individually.
  recorder_->UpdateRecord(Features::New(kEncode, kProfileB, kPixelSizeB, kHw),
                          VideoStats::New(13, 7, 17.0f));

  // Expect save for both encode and decode upon destruction.
  EXPECT_CALL(*this, SavePerfCallback(
                         MojoEq(Features(kDecode, kProfileA, kPixelSizeA, kSw)),
                         MojoEq(VideoStats(11, 3, 12.0f)), _))
      .Times(1);
  EXPECT_CALL(*this, SavePerfCallback(
                         MojoEq(Features(kEncode, kProfileB, kPixelSizeB, kHw)),
                         MojoEq(VideoStats(13, 7, 17.0f)), _))
      .Times(1);

  recorder_.reset();
}

}  // namespace media