aboutsummaryrefslogtreecommitdiff
path: root/video/video_quality_test.h
blob: 034cf905fdd0c5b20872f067ec4c9be7682270fd (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#ifndef VIDEO_VIDEO_QUALITY_TEST_H_
#define VIDEO_VIDEO_QUALITY_TEST_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "media/engine/internalencoderfactory.h"
#include "test/call_test.h"
#include "test/frame_generator.h"
#include "test/layer_filtering_transport.h"

namespace webrtc {

class VideoQualityTest : public test::CallTest {
 public:
  // Parameters are grouped into smaller structs to make it easier to set
  // the desired elements and skip unused, using aggregate initialization.
  // Unfortunately, C++11 (as opposed to C11) doesn't support unnamed structs,
  // which makes the implementation of VideoQualityTest a bit uglier.
  struct Params {
    Params();
    ~Params();
    struct CallConfig {
      bool send_side_bwe;
      BitrateConstraints call_bitrate_config;
      int num_thumbnails;
      // Indicates if secondary_(video|ss|screenshare) structures are used.
      bool dual_video;
    } call;
    struct Video {
      bool enabled;
      size_t width;
      size_t height;
      int32_t fps;
      int min_bitrate_bps;
      int target_bitrate_bps;
      int max_bitrate_bps;
      bool suspend_below_min_bitrate;
      std::string codec;
      int num_temporal_layers;
      int selected_tl;
      int min_transmit_bps;
      bool ulpfec;
      bool flexfec;
      std::string clip_name;  // "Generator" to generate frames instead.
      size_t capture_device_index;
    } video[2];
    struct Audio {
      bool enabled;
      bool sync_video;
      bool dtx;
    } audio;
    struct Screenshare {
      bool enabled;
      bool generate_slides;
      int32_t slide_change_interval;
      int32_t scroll_duration;
      std::vector<std::string> slides;
    } screenshare[2];
    struct Analyzer {
      std::string test_label;
      double avg_psnr_threshold;  // (*)
      double avg_ssim_threshold;  // (*)
      int test_durations_secs;
      std::string graph_data_output_filename;
      std::string graph_title;
    } analyzer;
    FakeNetworkPipe::Config pipe;
    struct SS {                          // Spatial scalability.
      std::vector<VideoStream> streams;  // If empty, one stream is assumed.
      size_t selected_stream;
      int num_spatial_layers;
      int selected_sl;
      InterLayerPredMode inter_layer_pred;
      // If empty, bitrates are generated in VP9Impl automatically.
      std::vector<SpatialLayer> spatial_layers;
      // If set, default parameters will be used instead of |streams|.
      bool infer_streams;
    } ss[2];
    struct Logging {
      bool logs;
      std::string rtc_event_log_name;
      std::string rtp_dump_name;
      std::string encoded_frame_base_path;
    } logging;
  };

  VideoQualityTest();
  explicit VideoQualityTest(
      std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
  void RunWithAnalyzer(const Params& params);
  void RunWithRenderers(const Params& params);

  static void FillScalabilitySettings(
      Params* params,
      size_t video_idx,
      const std::vector<std::string>& stream_descriptors,
      int num_streams,
      size_t selected_stream,
      int num_spatial_layers,
      int selected_sl,
      InterLayerPredMode inter_layer_pred,
      const std::vector<std::string>& sl_descriptors);

 protected:
  class TestVideoEncoderFactory : public VideoEncoderFactory {
    std::vector<SdpVideoFormat> GetSupportedFormats() const override;

    CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;

    std::unique_ptr<VideoEncoder> CreateVideoEncoder(
        const SdpVideoFormat& format) override;

   private:
    InternalEncoderFactory internal_encoder_factory_;
  };

  std::map<uint8_t, webrtc::MediaType> payload_type_map_;
  std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;

  // No-op implementation to be able to instantiate this class from non-TEST_F
  // locations.
  void TestBody() override;

  // Helper methods accessing only params_.
  std::string GenerateGraphTitle() const;
  void CheckParams();

  // Helper static methods.
  static VideoStream DefaultVideoStream(const Params& params, size_t video_idx);
  static VideoStream DefaultThumbnailStream();
  static std::vector<int> ParseCSV(const std::string& str);

  // Helper methods for setting up the call.
  void CreateVideoStreams();
  void DestroyStreams();
  void CreateCapturers();
  std::unique_ptr<test::FrameGenerator> CreateFrameGenerator(size_t video_idx);
  void SetupThumbnailCapturers(size_t num_thumbnail_streams);
  void SetupVideo(Transport* send_transport, Transport* recv_transport);
  void SetupThumbnails(Transport* send_transport, Transport* recv_transport);
  void DestroyThumbnailStreams();
  void SetupAudio(Transport* transport,
                  AudioReceiveStream** audio_receive_stream);

  void StartEncodedFrameLogs(VideoSendStream* stream);
  void StartEncodedFrameLogs(VideoReceiveStream* stream);

  virtual std::unique_ptr<test::LayerFilteringTransport> CreateSendTransport();
  virtual std::unique_ptr<test::DirectTransport> CreateReceiveTransport();

  std::vector<std::unique_ptr<test::VideoCapturer>> video_capturers_;
  std::vector<std::unique_ptr<test::VideoCapturer>> thumbnail_capturers_;
  TestVideoEncoderFactory video_encoder_factory_;

  std::vector<VideoSendStream::Config> thumbnail_send_configs_;
  std::vector<VideoEncoderConfig> thumbnail_encoder_configs_;
  std::vector<VideoSendStream*> thumbnail_send_streams_;
  std::vector<VideoReceiveStream::Config> thumbnail_receive_configs_;
  std::vector<VideoReceiveStream*> thumbnail_receive_streams_;

  std::vector<VideoSendStream::Config> video_send_configs_;
  std::vector<VideoEncoderConfig> video_encoder_configs_;
  std::vector<VideoSendStream*> video_send_streams_;

  Clock* const clock_;

  int receive_logs_;
  int send_logs_;

  DegradationPreference degradation_preference_ =
      DegradationPreference::MAINTAIN_FRAMERATE;
  Params params_;

  std::unique_ptr<webrtc::RtcEventLog> recv_event_log_;
  std::unique_ptr<webrtc::RtcEventLog> send_event_log_;

  size_t num_video_streams_;
};

}  // namespace webrtc

#endif  // VIDEO_VIDEO_QUALITY_TEST_H_