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