1 /* 2 * Copyright (c) 2011 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 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" 14 #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" 15 16 #include "vpx/vpx_encoder.h" 17 #include "vpx/vp8cx.h" 18 19 namespace webrtc { 20 21 enum { 22 kTemporalUpdateLast = VP8_EFLAG_NO_UPD_GF | 23 VP8_EFLAG_NO_UPD_ARF | 24 VP8_EFLAG_NO_REF_GF | 25 VP8_EFLAG_NO_REF_ARF, 26 kTemporalUpdateGoldenWithoutDependency = VP8_EFLAG_NO_REF_GF | 27 VP8_EFLAG_NO_REF_ARF | 28 VP8_EFLAG_NO_UPD_ARF | 29 VP8_EFLAG_NO_UPD_LAST, 30 kTemporalUpdateGolden = VP8_EFLAG_NO_REF_ARF | 31 VP8_EFLAG_NO_UPD_ARF | 32 VP8_EFLAG_NO_UPD_LAST, 33 kTemporalUpdateAltrefWithoutDependency = VP8_EFLAG_NO_REF_ARF | 34 VP8_EFLAG_NO_REF_GF | 35 VP8_EFLAG_NO_UPD_GF | 36 VP8_EFLAG_NO_UPD_LAST, 37 kTemporalUpdateAltref = VP8_EFLAG_NO_UPD_GF | 38 VP8_EFLAG_NO_UPD_LAST, 39 kTemporalUpdateNone = VP8_EFLAG_NO_UPD_GF | 40 VP8_EFLAG_NO_UPD_ARF | 41 VP8_EFLAG_NO_UPD_LAST | 42 VP8_EFLAG_NO_UPD_ENTROPY, 43 kTemporalUpdateNoneNoRefAltRef = VP8_EFLAG_NO_REF_ARF | 44 VP8_EFLAG_NO_UPD_GF | 45 VP8_EFLAG_NO_UPD_ARF | 46 VP8_EFLAG_NO_UPD_LAST | 47 VP8_EFLAG_NO_UPD_ENTROPY, 48 kTemporalUpdateNoneNoRefGolden = VP8_EFLAG_NO_REF_GF | 49 VP8_EFLAG_NO_UPD_GF | 50 VP8_EFLAG_NO_UPD_ARF | 51 VP8_EFLAG_NO_UPD_LAST | 52 VP8_EFLAG_NO_UPD_ENTROPY, 53 kTemporalUpdateGoldenWithoutDependencyRefAltRef = VP8_EFLAG_NO_REF_GF | 54 VP8_EFLAG_NO_UPD_ARF | 55 VP8_EFLAG_NO_UPD_LAST, 56 kTemporalUpdateGoldenRefAltRef = VP8_EFLAG_NO_UPD_ARF | 57 VP8_EFLAG_NO_UPD_LAST, 58 kTemporalUpdateLastRefAltRef = VP8_EFLAG_NO_UPD_GF | 59 VP8_EFLAG_NO_UPD_ARF | 60 VP8_EFLAG_NO_REF_GF, 61 kTemporalUpdateLastAndGoldenRefAltRef = VP8_EFLAG_NO_UPD_ARF | 62 VP8_EFLAG_NO_REF_GF, 63 }; 64 65 TEST(TemporalLayersTest, 2Layers) { 66 DefaultTemporalLayers tl(2, 0); 67 vpx_codec_enc_cfg_t cfg; 68 CodecSpecificInfoVP8 vp8_info; 69 tl.ConfigureBitrates(500, 500, 30, &cfg); 70 71 int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, 72 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 73 kTemporalUpdateLastRefAltRef, 74 kTemporalUpdateGoldenRefAltRef, 75 kTemporalUpdateLastRefAltRef, 76 kTemporalUpdateGoldenRefAltRef, 77 kTemporalUpdateLastRefAltRef, 78 kTemporalUpdateNone, 79 kTemporalUpdateLastAndGoldenRefAltRef, 80 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 81 kTemporalUpdateLastRefAltRef, 82 kTemporalUpdateGoldenRefAltRef, 83 kTemporalUpdateLastRefAltRef, 84 kTemporalUpdateGoldenRefAltRef, 85 kTemporalUpdateLastRefAltRef, 86 kTemporalUpdateNone, 87 }; 88 int expected_temporal_idx[16] = 89 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; 90 91 bool expected_layer_sync[16] = 92 { false, true, false, false, false, false, false, false, 93 false, true, false, false, false, false, false, false }; 94 95 uint32_t timestamp = 0; 96 for (int i = 0; i < 16; ++i) { 97 EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); 98 tl.PopulateCodecSpecific(false, &vp8_info, 0); 99 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 100 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 101 timestamp += 3000; 102 } 103 } 104 105 TEST(TemporalLayersTest, 3Layers) { 106 DefaultTemporalLayers tl(3, 0); 107 vpx_codec_enc_cfg_t cfg; 108 CodecSpecificInfoVP8 vp8_info; 109 tl.ConfigureBitrates(500, 500, 30, &cfg); 110 111 int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, 112 kTemporalUpdateNoneNoRefGolden, 113 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 114 kTemporalUpdateNone, 115 kTemporalUpdateLastRefAltRef, 116 kTemporalUpdateNone, 117 kTemporalUpdateGoldenRefAltRef, 118 kTemporalUpdateNone, 119 kTemporalUpdateLastAndGoldenRefAltRef, 120 kTemporalUpdateNoneNoRefGolden, 121 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 122 kTemporalUpdateNone, 123 kTemporalUpdateLastRefAltRef, 124 kTemporalUpdateNone, 125 kTemporalUpdateGoldenRefAltRef, 126 kTemporalUpdateNone, 127 }; 128 int expected_temporal_idx[16] = 129 { 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 1, 2 }; 130 131 bool expected_layer_sync[16] = 132 { false, true, true, false, false, false, false, false, 133 false, true, true, false, false, false, false, false }; 134 135 unsigned int timestamp = 0; 136 for (int i = 0; i < 16; ++i) { 137 EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); 138 tl.PopulateCodecSpecific(false, &vp8_info, 0); 139 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 140 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 141 timestamp += 3000; 142 } 143 } 144 145 TEST(TemporalLayersTest, 4Layers) { 146 DefaultTemporalLayers tl(4, 0); 147 vpx_codec_enc_cfg_t cfg; 148 CodecSpecificInfoVP8 vp8_info; 149 tl.ConfigureBitrates(500, 500, 30, &cfg); 150 int expected_flags[16] = { 151 kTemporalUpdateLast, 152 kTemporalUpdateNone, 153 kTemporalUpdateAltrefWithoutDependency, 154 kTemporalUpdateNone, 155 kTemporalUpdateGoldenWithoutDependency, 156 kTemporalUpdateNone, 157 kTemporalUpdateAltref, 158 kTemporalUpdateNone, 159 kTemporalUpdateLast, 160 kTemporalUpdateNone, 161 kTemporalUpdateAltref, 162 kTemporalUpdateNone, 163 kTemporalUpdateGolden, 164 kTemporalUpdateNone, 165 kTemporalUpdateAltref, 166 kTemporalUpdateNone, 167 }; 168 int expected_temporal_idx[16] = 169 { 0, 3, 2, 3, 1, 3, 2, 3, 0, 3, 2, 3, 1, 3, 2, 3 }; 170 171 bool expected_layer_sync[16] = 172 { false, true, true, true, true, true, false, true, 173 false, true, false, true, false, true, false, true }; 174 175 uint32_t timestamp = 0; 176 for (int i = 0; i < 16; ++i) { 177 EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); 178 tl.PopulateCodecSpecific(false, &vp8_info, 0); 179 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 180 EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); 181 timestamp += 3000; 182 } 183 } 184 185 TEST(TemporalLayersTest, KeyFrame) { 186 DefaultTemporalLayers tl(3, 0); 187 vpx_codec_enc_cfg_t cfg; 188 CodecSpecificInfoVP8 vp8_info; 189 tl.ConfigureBitrates(500, 500, 30, &cfg); 190 191 int expected_flags[8] = { 192 kTemporalUpdateLastAndGoldenRefAltRef, 193 kTemporalUpdateNoneNoRefGolden, 194 kTemporalUpdateGoldenWithoutDependencyRefAltRef, 195 kTemporalUpdateNone, 196 kTemporalUpdateLastRefAltRef, 197 kTemporalUpdateNone, 198 kTemporalUpdateGoldenRefAltRef, 199 kTemporalUpdateNone, 200 }; 201 int expected_temporal_idx[8] = 202 { 0, 0, 0, 0, 0, 0, 0, 2}; 203 204 uint32_t timestamp = 0; 205 for (int i = 0; i < 7; ++i) { 206 EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); 207 tl.PopulateCodecSpecific(true, &vp8_info, 0); 208 EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 209 EXPECT_EQ(true, vp8_info.layerSync); 210 timestamp += 3000; 211 } 212 EXPECT_EQ(expected_flags[7], tl.EncodeFlags(timestamp)); 213 tl.PopulateCodecSpecific(false, &vp8_info, 0); 214 EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx); 215 EXPECT_EQ(true, vp8_info.layerSync); 216 } 217 } // namespace webrtc 218