1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <memory>
12 #include <vector>
13 
14 #include "api/video_codecs/sdp_video_format.h"
15 #include "api/video_codecs/video_decoder.h"
16 #include "api/video_codecs/video_decoder_factory.h"
17 #include "api/video_codecs/video_encoder.h"
18 #include "api/video_codecs/video_encoder_factory.h"
19 #if defined(WEBRTC_ANDROID)
20 #include "modules/video_coding/codecs/test/android_codec_factory_helper.h"
21 #elif defined(WEBRTC_IOS)
22 #include "modules/video_coding/codecs/test/objc_codec_factory_helper.h"
23 #endif
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26 #include "test/video_codec_settings.h"
27 
28 namespace webrtc {
29 namespace test {
30 
31 namespace {
32 
33 using ::testing::NotNull;
34 
35 const VideoEncoder::Capabilities kCapabilities(false);
36 
InitEncoder(VideoCodecType codec_type,VideoEncoder * encoder)37 int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) {
38   VideoCodec codec;
39   CodecSettings(codec_type, &codec);
40   codec.width = 640;
41   codec.height = 480;
42   codec.maxFramerate = 30;
43   RTC_CHECK(encoder);
44   return encoder->InitEncode(
45       &codec, VideoEncoder::Settings(kCapabilities, 1 /* number_of_cores */,
46                                      1200 /* max_payload_size */));
47 }
48 
DecoderSettings(VideoCodecType codec_type)49 VideoDecoder::Settings DecoderSettings(VideoCodecType codec_type) {
50   VideoDecoder::Settings settings;
51   settings.set_max_render_resolution({640, 480});
52   settings.set_codec_type(codec_type);
53   return settings;
54 }
55 
56 }  // namespace
57 
58 class VideoEncoderDecoderInstantiationTest
59     : public ::testing::Test,
60       public ::testing::WithParamInterface<::testing::tuple<int, int>> {
61  protected:
VideoEncoderDecoderInstantiationTest()62   VideoEncoderDecoderInstantiationTest()
63       : vp8_format_("VP8"),
64         vp9_format_("VP9"),
65         h264cbp_format_("H264"),
66         num_encoders_(::testing::get<0>(GetParam())),
67         num_decoders_(::testing::get<1>(GetParam())) {
68 #if defined(WEBRTC_ANDROID)
69     InitializeAndroidObjects();
70     encoder_factory_ = CreateAndroidEncoderFactory();
71     decoder_factory_ = CreateAndroidDecoderFactory();
72 #elif defined(WEBRTC_IOS)
73     encoder_factory_ = CreateObjCEncoderFactory();
74     decoder_factory_ = CreateObjCDecoderFactory();
75 #else
76     RTC_DCHECK_NOTREACHED() << "Only support Android and iOS.";
77 #endif
78   }
79 
~VideoEncoderDecoderInstantiationTest()80   ~VideoEncoderDecoderInstantiationTest() {
81     for (auto& encoder : encoders_) {
82       encoder->Release();
83     }
84     for (auto& decoder : decoders_) {
85       decoder->Release();
86     }
87   }
88 
89   const SdpVideoFormat vp8_format_;
90   const SdpVideoFormat vp9_format_;
91   const SdpVideoFormat h264cbp_format_;
92   std::unique_ptr<VideoEncoderFactory> encoder_factory_;
93   std::unique_ptr<VideoDecoderFactory> decoder_factory_;
94 
95   const int num_encoders_;
96   const int num_decoders_;
97   std::vector<std::unique_ptr<VideoEncoder>> encoders_;
98   std::vector<std::unique_ptr<VideoDecoder>> decoders_;
99 };
100 
101 INSTANTIATE_TEST_SUITE_P(MultipleEncoders,
102                          VideoEncoderDecoderInstantiationTest,
103                          ::testing::Combine(::testing::Range(1, 4),
104                                             ::testing::Range(1, 2)));
105 
106 INSTANTIATE_TEST_SUITE_P(MultipleDecoders,
107                          VideoEncoderDecoderInstantiationTest,
108                          ::testing::Combine(::testing::Range(1, 2),
109                                             ::testing::Range(1, 9)));
110 
111 INSTANTIATE_TEST_SUITE_P(MultipleEncodersDecoders,
112                          VideoEncoderDecoderInstantiationTest,
113                          ::testing::Combine(::testing::Range(1, 4),
114                                             ::testing::Range(1, 9)));
115 
116 // TODO(brandtr): Check that the factories actually support the codecs before
117 // trying to instantiate. Currently, we will just crash with a Java exception
118 // if the factory does not support the codec.
TEST_P(VideoEncoderDecoderInstantiationTest,DISABLED_InstantiateVp8Codecs)119 TEST_P(VideoEncoderDecoderInstantiationTest, DISABLED_InstantiateVp8Codecs) {
120   for (int i = 0; i < num_encoders_; ++i) {
121     std::unique_ptr<VideoEncoder> encoder =
122         encoder_factory_->CreateVideoEncoder(vp8_format_);
123     EXPECT_EQ(0, InitEncoder(kVideoCodecVP8, encoder.get()));
124     encoders_.emplace_back(std::move(encoder));
125   }
126 
127   for (int i = 0; i < num_decoders_; ++i) {
128     std::unique_ptr<VideoDecoder> decoder =
129         decoder_factory_->CreateVideoDecoder(vp8_format_);
130     ASSERT_THAT(decoder, NotNull());
131     EXPECT_TRUE(decoder->Configure(DecoderSettings(kVideoCodecVP8)));
132     decoders_.emplace_back(std::move(decoder));
133   }
134 }
135 
TEST_P(VideoEncoderDecoderInstantiationTest,DISABLED_InstantiateH264CBPCodecs)136 TEST_P(VideoEncoderDecoderInstantiationTest,
137        DISABLED_InstantiateH264CBPCodecs) {
138   for (int i = 0; i < num_encoders_; ++i) {
139     std::unique_ptr<VideoEncoder> encoder =
140         encoder_factory_->CreateVideoEncoder(h264cbp_format_);
141     EXPECT_EQ(0, InitEncoder(kVideoCodecH264, encoder.get()));
142     encoders_.emplace_back(std::move(encoder));
143   }
144 
145   for (int i = 0; i < num_decoders_; ++i) {
146     std::unique_ptr<VideoDecoder> decoder =
147         decoder_factory_->CreateVideoDecoder(h264cbp_format_);
148     ASSERT_THAT(decoder, NotNull());
149     EXPECT_TRUE(decoder->Configure(DecoderSettings(kVideoCodecH264)));
150     decoders_.push_back(std::move(decoder));
151   }
152 }
153 
154 }  // namespace test
155 }  // namespace webrtc
156