1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "demuxer_plugin_unit_test.h" 17 #include "demuxer_plugin_manager.h" 18 #include "stream_demuxer.h" 19 #include "common/media_source.h" 20 #include "buffer/avbuffer.h" 21 #include "plugin/plugin_manager_v2.h" 22 #include <fcntl.h> 23 #include <fstream> 24 #include <gtest/gtest.h> 25 #include "media_description.h" 26 #include "file_server_demo.h" 27 #include <numeric> 28 #include <vector> 29 30 using namespace OHOS; 31 using namespace OHOS::Media; 32 using namespace testing::ext; 33 using namespace std; 34 using MediaAVBuffer = OHOS::Media::AVBuffer; 35 using FFmpegAVBuffer = ::AVBuffer; 36 using InvokerTypeAlias = OHOS::Media::Plugins::Ffmpeg::FFmpegDemuxerPlugin::InvokerType; 37 using namespace OHOS::MediaAVCodec; 38 using namespace OHOS::Media::Plugins; 39 // M4A, AAC, MP3, OGG, FLAC, WAV, AMR, APE 40 string g_m4aPath1 = string("/data/test/media/audio/h264_fmp4.m4a"); 41 string g_accPath1 = string("/data/test/media/audio/aac_44100_1.aac"); 42 string g_mp3Path1 = string("/data/test/media/audio/mp3_48000_1_cover.mp3"); 43 string g_oggPath1 = string("/data/test/media/audio/ogg_48000_1.ogg"); 44 string g_flacPath1 = string("/data/test/media/audio/flac_48000_1_cover.flac"); 45 string g_wavPath1 = string("/data/test/media/audio/wav_48000_1.wav"); 46 string g_wavPath2 = string("/data/test/media/audio/wav_48000_1_pcm_alaw.wav"); 47 string g_amrPath1 = string("/data/test/media/audio/amr_nb_8000_1.amr"); 48 string g_amrPath2 = string("/data/test/media/audio/amr_wb_16000_1.amr"); 49 string g_apePath1 = string("/data/test/media/ape_test.ape"); 50 51 /** 52 * @tc.name: Demuxer_ReadSample_M4A_0001 53 * @tc.desc: Copy current sample to buffer (M4A) 54 * @tc.type: FUNC 55 */ 56 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_M4A_0001, TestSize.Level1) 57 { 58 std::string pluginName = "avdemux_mov,mp4,m4a,3gp,3g2,mj2"; 59 std::string filePath = g_m4aPath1; 60 InitResource(filePath, pluginName); 61 ASSERT_TRUE(initStatus_); 62 std::vector<uint32_t> numbers(433); 63 std::iota(numbers.begin(), numbers.end(), 0); 64 CheckAllFrames({433}, {433}, numbers); 65 } 66 67 /** 68 * @tc.name: Demuxer_ReadSample_AAC_0001 69 * @tc.desc: Copy current sample to buffer (AAC) 70 * @tc.type: FUNC 71 */ 72 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_AAC_0001, TestSize.Level1) 73 { 74 std::string pluginName = "avdemux_aac"; 75 std::string filePath = g_accPath1; 76 InitResource(filePath, pluginName); 77 ASSERT_TRUE(initStatus_); 78 std::vector<uint32_t> numbers(1293); 79 std::iota(numbers.begin(), numbers.end(), 0); 80 CheckAllFrames({1293}, {1293}, numbers); 81 } 82 83 /** 84 * @tc.name: Demuxer_ReadSample_MP3_0001 85 * @tc.desc: Copy current sample to buffer (MP3) 86 * @tc.type: FUNC 87 */ 88 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_MP3_0001, TestSize.Level1) 89 { 90 std::string pluginName = "avdemux_mp3"; 91 std::string filePath = g_mp3Path1; 92 InitResource(filePath, pluginName); 93 ASSERT_TRUE(initStatus_); 94 std::vector<uint32_t> numbers(1251); 95 std::iota(numbers.begin(), numbers.end(), 0); 96 CheckAllFrames({1251, 0}, {1251, 0}, numbers); 97 } 98 99 /** 100 * @tc.name: Demuxer_ReadSample_OGG_0001 101 * @tc.desc: Copy current sample to buffer (OGG) 102 * @tc.type: FUNC 103 */ 104 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_OGG_0001, TestSize.Level1) 105 { 106 std::string pluginName = "avdemux_ogg"; 107 std::string filePath = g_oggPath1; 108 InitResource(filePath, pluginName); 109 ASSERT_TRUE(initStatus_); 110 std::vector<uint32_t> numbers(1598); 111 std::iota(numbers.begin(), numbers.end(), 0); 112 CheckAllFrames({1598}, {1598}, numbers); 113 } 114 115 /** 116 * @tc.name: Demuxer_ReadSample_FLAC_0001 117 * @tc.desc: Copy current sample to buffer (FLAC) 118 * @tc.type: FUNC 119 */ 120 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_FLAC_0001, TestSize.Level1) 121 { 122 std::string pluginName = "avdemux_flac"; 123 std::string filePath = g_flacPath1; 124 InitResource(filePath, pluginName); 125 ASSERT_TRUE(initStatus_); 126 std::vector<uint32_t> numbers(313); 127 std::iota(numbers.begin(), numbers.end(), 0); 128 CheckAllFrames({313, 0}, {313, 0}, numbers); 129 } 130 131 /** 132 * @tc.name: Demuxer_ReadSample_WAV_0001 133 * @tc.desc: Copy current sample to buffer (WAV) 134 * @tc.type: FUNC 135 */ 136 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WAV_0001, TestSize.Level1) 137 { 138 std::string pluginName = "avdemux_wav"; 139 std::string filePath = g_wavPath1; 140 InitResource(filePath, pluginName); 141 ASSERT_TRUE(initStatus_); 142 std::vector<uint32_t> numbers(704); 143 std::iota(numbers.begin(), numbers.end(), 0); 144 CheckAllFrames({704}, {704}, numbers); 145 } 146 147 /** 148 * @tc.name: Demuxer_ReadSample_WAV_0002 149 * @tc.desc: Copy current sample to buffer (WAV) 150 * @tc.type: FUNC 151 */ 152 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WAV_0002, TestSize.Level1) 153 { 154 std::string pluginName = "avdemux_wav"; 155 std::string filePath = g_wavPath2; 156 InitResource(filePath, pluginName); 157 ASSERT_TRUE(initStatus_); 158 std::vector<uint32_t> numbers(352); 159 std::iota(numbers.begin(), numbers.end(), 0); 160 CheckAllFrames({352}, {352}, numbers); 161 } 162 163 /** 164 * @tc.name: Demuxer_ReadSample_AMR_0001 165 * @tc.desc: Copy current sample to buffer (AMR) 166 * @tc.type: FUNC 167 */ 168 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_AMR_0001, TestSize.Level1) 169 { 170 std::string pluginName = "avdemux_amr"; 171 std::string filePath = g_amrPath1; 172 InitResource(filePath, pluginName); 173 ASSERT_TRUE(initStatus_); 174 std::vector<uint32_t> numbers(1501); 175 std::iota(numbers.begin(), numbers.end(), 0); 176 CheckAllFrames({1501}, {1501}, numbers); 177 } 178 179 /** 180 * @tc.name: Demuxer_ReadSample_AMR_0002 181 * @tc.desc: Copy current sample to buffer (AMR) 182 * @tc.type: FUNC 183 */ 184 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_AMR_0002, TestSize.Level1) 185 { 186 std::string pluginName = "avdemux_amr"; 187 std::string filePath = g_amrPath2; 188 InitResource(filePath, pluginName); 189 ASSERT_TRUE(initStatus_); 190 std::vector<uint32_t> numbers(1500); 191 std::iota(numbers.begin(), numbers.end(), 0); 192 CheckAllFrames({1500}, {1500}, numbers); 193 } 194 195 /** 196 * @tc.name: Demuxer_ReadSample_APE_0001 197 * @tc.desc: Copy current sample to buffer (APE) 198 * @tc.type: FUNC 199 */ 200 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_APE_0001, TestSize.Level1) 201 { 202 std::string pluginName = "avdemux_ape"; 203 std::string filePath = g_apePath1; 204 InitResource(filePath, pluginName); 205 ASSERT_TRUE(initStatus_); 206 std::vector<uint32_t> numbers(7); 207 std::iota(numbers.begin(), numbers.end(), 0); 208 CheckAllFrames({7}, {7}, numbers); 209 } 210 211 /** 212 * @tc.name: Demuxer_ReadSample_WeakNetwork_M4A_0001 213 * @tc.desc: Copy current sample to buffer (M4A) 214 * @tc.type: FUNC 215 */ 216 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_M4A_0001, TestSize.Level1) 217 { 218 std::string pluginName = "avdemux_mov,mp4,m4a,3gp,3g2,mj2"; 219 std::string filePath = g_m4aPath1; 220 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 221 ASSERT_TRUE(initStatus_); 222 std::vector<uint32_t> numbers(433); 223 std::iota(numbers.begin(), numbers.end(), 0); 224 CheckAllFrames({433}, {433}, numbers); 225 } 226 227 /** 228 * @tc.name: Demuxer_ReadSample_WeakNetwork_AAC_0001 229 * @tc.desc: Copy current sample to buffer (AAC) 230 * @tc.type: FUNC 231 */ 232 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_AAC_0001, TestSize.Level1) 233 { 234 std::string pluginName = "avdemux_aac"; 235 std::string filePath = g_accPath1; 236 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 237 ASSERT_TRUE(initStatus_); 238 std::vector<uint32_t> numbers(1293); 239 std::iota(numbers.begin(), numbers.end(), 0); 240 CheckAllFrames({1293}, {1293}, numbers); 241 } 242 243 /** 244 * @tc.name: Demuxer_ReadSample_WeakNetwork_MP3_0001 245 * @tc.desc: Copy current sample to buffer (MP3) 246 * @tc.type: FUNC 247 */ 248 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_MP3_0001, TestSize.Level1) 249 { 250 std::string pluginName = "avdemux_mp3"; 251 std::string filePath = g_mp3Path1; 252 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 253 ASSERT_TRUE(initStatus_); 254 std::vector<uint32_t> numbers(1251); 255 std::iota(numbers.begin(), numbers.end(), 0); 256 CheckAllFrames({1251, 0}, {1251, 0}, numbers); 257 } 258 259 /** 260 * @tc.name: Demuxer_ReadSample_WeakNetwork_OGG_0001 261 * @tc.desc: Copy current sample to buffer (OGG) 262 * @tc.type: FUNC 263 */ 264 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_OGG_0001, TestSize.Level1) 265 { 266 std::string pluginName = "avdemux_ogg"; 267 std::string filePath = g_oggPath1; 268 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 269 ASSERT_TRUE(initStatus_); 270 std::vector<uint32_t> numbers(1598); 271 std::iota(numbers.begin(), numbers.end(), 0); 272 CheckAllFrames({1598}, {1598}, numbers); 273 } 274 275 /** 276 * @tc.name: Demuxer_ReadSample_WeakNetwork_FLAC_0001 277 * @tc.desc: Copy current sample to buffer (FLAC) 278 * @tc.type: FUNC 279 */ 280 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_FLAC_0001, TestSize.Level1) 281 { 282 std::string pluginName = "avdemux_flac"; 283 std::string filePath = g_flacPath1; 284 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 285 ASSERT_TRUE(initStatus_); 286 std::vector<uint32_t> numbers(313); 287 std::iota(numbers.begin(), numbers.end(), 0); 288 CheckAllFrames({313, 0}, {313, 0}, numbers); 289 } 290 291 /** 292 * @tc.name: Demuxer_ReadSample_WeakNetwork_WAV_0001 293 * @tc.desc: Copy current sample to buffer (WAV) 294 * @tc.type: FUNC 295 */ 296 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_WAV_0001, TestSize.Level1) 297 { 298 std::string pluginName = "avdemux_wav"; 299 std::string filePath = g_wavPath1; 300 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 301 ASSERT_TRUE(initStatus_); 302 std::vector<uint32_t> numbers(704); 303 std::iota(numbers.begin(), numbers.end(), 0); 304 CheckAllFrames({704}, {704}, numbers); 305 } 306 307 /** 308 * @tc.name: Demuxer_ReadSample_WeakNetwork_WAV_0002 309 * @tc.desc: Copy current sample to buffer (WAV) 310 * @tc.type: FUNC 311 */ 312 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_WAV_0002, TestSize.Level1) 313 { 314 std::string pluginName = "avdemux_wav"; 315 std::string filePath = g_wavPath2; 316 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 317 ASSERT_TRUE(initStatus_); 318 std::vector<uint32_t> numbers(352); 319 std::iota(numbers.begin(), numbers.end(), 0); 320 CheckAllFrames({352}, {352}, numbers); 321 } 322 323 /** 324 * @tc.name: Demuxer_ReadSample_WeakNetwork_AMR_0001 325 * @tc.desc: Copy current sample to buffer (AMR) 326 * @tc.type: FUNC 327 */ 328 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_AMR_0001, TestSize.Level1) 329 { 330 std::string pluginName = "avdemux_amr"; 331 std::string filePath = g_amrPath1; 332 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 333 ASSERT_TRUE(initStatus_); 334 std::vector<uint32_t> numbers(1501); 335 std::iota(numbers.begin(), numbers.end(), 0); 336 CheckAllFrames({1501}, {1501}, numbers); 337 } 338 339 /** 340 * @tc.name: Demuxer_ReadSample_WeakNetwork_AMR_0002 341 * @tc.desc: Copy current sample to buffer (AMR) 342 * @tc.type: FUNC 343 */ 344 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_AMR_0002, TestSize.Level1) 345 { 346 std::string pluginName = "avdemux_amr"; 347 std::string filePath = g_amrPath2; 348 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 349 ASSERT_TRUE(initStatus_); 350 std::vector<uint32_t> numbers(1500); 351 std::iota(numbers.begin(), numbers.end(), 0); 352 CheckAllFrames({1500}, {1500}, numbers); 353 } 354 355 /** 356 * @tc.name: Demuxer_ReadSample_WeakNetwork_APE_0001 357 * @tc.desc: Copy current sample to buffer (APE) 358 * @tc.type: FUNC 359 */ 360 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_WeakNetwork_APE_0001, TestSize.Level1) 361 { 362 std::string pluginName = "avdemux_ape"; 363 std::string filePath = g_apePath1; 364 InitWeakNetworkDemuxerPlugin(filePath, pluginName, 2560656, 3); 365 ASSERT_TRUE(initStatus_); 366 std::vector<uint32_t> numbers(7); 367 std::iota(numbers.begin(), numbers.end(), 0); 368 CheckAllFrames({7}, {7}, numbers); 369 } 370 371 /** 372 * @tc.name: Demuxer_ReadSample_URI_M4A_0001 373 * @tc.desc: Copy current sample to buffer (M4A) 374 * @tc.type: FUNC 375 */ 376 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_M4A_0001, TestSize.Level1) 377 { 378 std::string pluginName = "avdemux_mov,mp4,m4a,3gp,3g2,mj2"; 379 std::string filePath = g_m4aPath1; 380 InitResourceURI(filePath, pluginName); 381 ASSERT_TRUE(initStatus_); 382 std::vector<uint32_t> numbers(433); 383 std::iota(numbers.begin(), numbers.end(), 0); 384 CheckAllFrames({433}, {433}, numbers); 385 } 386 387 /** 388 * @tc.name: Demuxer_ReadSample_URI_AAC_0001 389 * @tc.desc: Copy current sample to buffer (AAC) 390 * @tc.type: FUNC 391 */ 392 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_AAC_0001, TestSize.Level1) 393 { 394 std::string pluginName = "avdemux_aac"; 395 std::string filePath = g_accPath1; 396 InitResourceURI(filePath, pluginName); 397 ASSERT_TRUE(initStatus_); 398 std::vector<uint32_t> numbers(1293); 399 std::iota(numbers.begin(), numbers.end(), 0); 400 CheckAllFrames({1293}, {1293}, numbers); 401 } 402 403 /** 404 * @tc.name: Demuxer_ReadSample_URI_MP3_0001 405 * @tc.desc: Copy current sample to buffer (MP3) 406 * @tc.type: FUNC 407 */ 408 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_MP3_0001, TestSize.Level1) 409 { 410 std::string pluginName = "avdemux_mp3"; 411 std::string filePath = g_mp3Path1; 412 InitResourceURI(filePath, pluginName); 413 ASSERT_TRUE(initStatus_); 414 std::vector<uint32_t> numbers(1251); 415 std::iota(numbers.begin(), numbers.end(), 0); 416 CheckAllFrames({1251, 0}, {1251, 0}, numbers); 417 } 418 419 /** 420 * @tc.name: Demuxer_ReadSample_URI_OGG_0001 421 * @tc.desc: Copy current sample to buffer (OGG) 422 * @tc.type: FUNC 423 */ 424 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_OGG_0001, TestSize.Level1) 425 { 426 std::string pluginName = "avdemux_ogg"; 427 std::string filePath = g_oggPath1; 428 InitResourceURI(filePath, pluginName); 429 ASSERT_TRUE(initStatus_); 430 std::vector<uint32_t> numbers(1598); 431 std::iota(numbers.begin(), numbers.end(), 0); 432 CheckAllFrames({1598}, {1598}, numbers); 433 } 434 435 /** 436 * @tc.name: Demuxer_ReadSample_URI_FLAC_0001 437 * @tc.desc: Copy current sample to buffer (FLAC) 438 * @tc.type: FUNC 439 */ 440 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_FLAC_0001, TestSize.Level1) 441 { 442 std::string pluginName = "avdemux_flac"; 443 std::string filePath = g_flacPath1; 444 InitResourceURI(filePath, pluginName); 445 ASSERT_TRUE(initStatus_); 446 std::vector<uint32_t> numbers(313); 447 std::iota(numbers.begin(), numbers.end(), 0); 448 CheckAllFrames({313, 0}, {313, 0}, numbers); 449 } 450 451 /** 452 * @tc.name: Demuxer_ReadSample_URI_WAV_0001 453 * @tc.desc: Copy current sample to buffer (WAV) 454 * @tc.type: FUNC 455 */ 456 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_WAV_0001, TestSize.Level1) 457 { 458 std::string pluginName = "avdemux_wav"; 459 std::string filePath = g_wavPath1; 460 InitResourceURI(filePath, pluginName); 461 ASSERT_TRUE(initStatus_); 462 std::vector<uint32_t> numbers(704); 463 std::iota(numbers.begin(), numbers.end(), 0); 464 CheckAllFrames({704}, {704}, numbers); 465 } 466 467 /** 468 * @tc.name: Demuxer_ReadSample_URI_WAV_0002 469 * @tc.desc: Copy current sample to buffer (WAV) 470 * @tc.type: FUNC 471 */ 472 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_WAV_0002, TestSize.Level1) 473 { 474 std::string pluginName = "avdemux_wav"; 475 std::string filePath = g_wavPath2; 476 InitResourceURI(filePath, pluginName); 477 ASSERT_TRUE(initStatus_); 478 std::vector<uint32_t> numbers(352); 479 std::iota(numbers.begin(), numbers.end(), 0); 480 CheckAllFrames({352}, {352}, numbers); 481 } 482 483 /** 484 * @tc.name: Demuxer_ReadSample_URI_AMR_0001 485 * @tc.desc: Copy current sample to buffer (AMR) 486 * @tc.type: FUNC 487 */ 488 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_AMR_0001, TestSize.Level1) 489 { 490 std::string pluginName = "avdemux_amr"; 491 std::string filePath = g_amrPath1; 492 InitResourceURI(filePath, pluginName); 493 ASSERT_TRUE(initStatus_); 494 std::vector<uint32_t> numbers(1501); 495 std::iota(numbers.begin(), numbers.end(), 0); 496 CheckAllFrames({1501}, {1501}, numbers); 497 } 498 499 /** 500 * @tc.name: Demuxer_ReadSample_URI_AMR_0002 501 * @tc.desc: Copy current sample to buffer (AMR) 502 * @tc.type: FUNC 503 */ 504 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_AMR_0002, TestSize.Level1) 505 { 506 std::string pluginName = "avdemux_amr"; 507 std::string filePath = g_amrPath2; 508 InitResourceURI(filePath, pluginName); 509 ASSERT_TRUE(initStatus_); 510 std::vector<uint32_t> numbers(1500); 511 std::iota(numbers.begin(), numbers.end(), 0); 512 CheckAllFrames({1500}, {1500}, numbers); 513 } 514 515 /** 516 * @tc.name: Demuxer_ReadSample_URI_APE_0001 517 * @tc.desc: Copy current sample to buffer (APE) 518 * @tc.type: FUNC 519 */ 520 HWTEST_F(DemuxerPluginUnitTest, Demuxer_ReadSample_URI_APE_0001, TestSize.Level1) 521 { 522 std::string pluginName = "avdemux_ape"; 523 std::string filePath = g_apePath1; 524 InitResourceURI(filePath, pluginName); 525 ASSERT_TRUE(initStatus_); 526 std::vector<uint32_t> numbers(7); 527 std::iota(numbers.begin(), numbers.end(), 0); 528 CheckAllFrames({7}, {7}, numbers); 529 }