TestMP4Demuxer.cpp (24381B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "MP4Demuxer.h" 8 #include "MediaDataDemuxer.h" 9 #include "MockMediaResource.h" 10 #include "VideoUtils.h" 11 #include "gtest/gtest.h" 12 #include "mozilla/MozPromise.h" 13 #include "mozilla/SharedThreadPool.h" 14 #include "mozilla/TaskQueue.h" 15 16 using namespace mozilla; 17 using media::TimeUnit; 18 19 #define DO_FAIL \ 20 [binding]() -> void { \ 21 EXPECT_TRUE(false); \ 22 binding->mTaskQueue->BeginShutdown(); \ 23 } 24 25 class MP4DemuxerBinding { 26 public: 27 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MP4DemuxerBinding); 28 29 RefPtr<MockMediaResource> resource; 30 RefPtr<MP4Demuxer> mDemuxer; 31 RefPtr<TaskQueue> mTaskQueue; 32 RefPtr<MediaTrackDemuxer> mAudioTrack; 33 RefPtr<MediaTrackDemuxer> mVideoTrack; 34 uint32_t mIndex; 35 nsTArray<RefPtr<MediaRawData>> mSamples; 36 nsTArray<int64_t> mKeyFrameTimecodes; 37 MozPromiseHolder<GenericPromise> mCheckTrackKeyFramePromise; 38 MozPromiseHolder<GenericPromise> mCheckTrackSamples; 39 40 explicit MP4DemuxerBinding(const char* aFileName = "dash_dashinit.mp4") 41 : resource(new MockMediaResource(aFileName)), 42 mDemuxer(new MP4Demuxer(resource)), 43 mTaskQueue(TaskQueue::Create( 44 GetMediaThreadPool(MediaThreadType::SUPERVISOR), "TestMP4Demuxer")), 45 mIndex(0) { 46 EXPECT_EQ(NS_OK, resource->Open()); 47 } 48 49 template <typename Function> 50 void RunTestAndWait(const Function& aFunction) { 51 Function func(aFunction); 52 RefPtr<MP4DemuxerBinding> binding = this; 53 mDemuxer->Init()->Then(mTaskQueue, __func__, std::move(func), DO_FAIL); 54 mTaskQueue->AwaitShutdownAndIdle(); 55 } 56 57 RefPtr<GenericPromise> CheckTrackKeyFrame(MediaTrackDemuxer* aTrackDemuxer) { 58 MOZ_RELEASE_ASSERT(mTaskQueue->IsCurrentThreadIn()); 59 60 RefPtr<MediaTrackDemuxer> track = aTrackDemuxer; 61 RefPtr<MP4DemuxerBinding> binding = this; 62 63 auto time = TimeUnit::Invalid(); 64 while (mIndex < mSamples.Length()) { 65 uint32_t i = mIndex++; 66 if (mSamples[i]->mKeyframe) { 67 time = mSamples[i]->mTime; 68 break; 69 } 70 } 71 72 RefPtr<GenericPromise> p = mCheckTrackKeyFramePromise.Ensure(__func__); 73 74 if (!time.IsValid()) { 75 mCheckTrackKeyFramePromise.Resolve(true, __func__); 76 return p; 77 } 78 79 DispatchTask([track, time, binding]() { 80 track->Seek(time)->Then( 81 binding->mTaskQueue, __func__, 82 [track, time, binding]() { 83 track->GetSamples()->Then( 84 binding->mTaskQueue, __func__, 85 [track, time, 86 binding](RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) { 87 EXPECT_EQ(time, aSamples->GetSamples()[0]->mTime); 88 binding->CheckTrackKeyFrame(track); 89 }, 90 DO_FAIL); 91 }, 92 DO_FAIL); 93 }); 94 95 return p; 96 } 97 98 RefPtr<GenericPromise> CheckTrackSamples(MediaTrackDemuxer* aTrackDemuxer) { 99 MOZ_RELEASE_ASSERT(mTaskQueue->IsCurrentThreadIn()); 100 101 RefPtr<MediaTrackDemuxer> track = aTrackDemuxer; 102 RefPtr<MP4DemuxerBinding> binding = this; 103 104 RefPtr<GenericPromise> p = mCheckTrackSamples.Ensure(__func__); 105 106 DispatchTask([track, binding]() { 107 track->GetSamples()->Then( 108 binding->mTaskQueue, __func__, 109 [track, binding](RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) { 110 if (aSamples->GetSamples().Length()) { 111 binding->mSamples.AppendElements(aSamples->GetSamples()); 112 binding->CheckTrackSamples(track); 113 } 114 }, 115 [binding](const MediaResult& aError) { 116 if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) { 117 EXPECT_TRUE(binding->mSamples.Length() > 1); 118 for (uint32_t i = 0; i < (binding->mSamples.Length() - 1); i++) { 119 EXPECT_LT(binding->mSamples[i]->mTimecode, 120 binding->mSamples[i + 1]->mTimecode); 121 if (binding->mSamples[i]->mKeyframe) { 122 binding->mKeyFrameTimecodes.AppendElement( 123 binding->mSamples[i]->mTimecode.ToMicroseconds()); 124 } 125 } 126 binding->mCheckTrackSamples.Resolve(true, __func__); 127 } else { 128 EXPECT_TRUE(false); 129 binding->mCheckTrackSamples.Reject(aError, __func__); 130 } 131 }); 132 }); 133 134 return p; 135 } 136 137 private: 138 template <typename FunctionType> 139 void DispatchTask(FunctionType aFun) { 140 RefPtr<Runnable> r = 141 NS_NewRunnableFunction("MP4DemuxerBinding::DispatchTask", aFun); 142 (void)mTaskQueue->Dispatch(r.forget()); 143 } 144 145 virtual ~MP4DemuxerBinding() = default; 146 }; 147 148 TEST(MP4Demuxer, Seek) 149 { 150 RefPtr<MP4DemuxerBinding> binding = new MP4DemuxerBinding(); 151 152 binding->RunTestAndWait([binding]() { 153 binding->mVideoTrack = 154 binding->mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0); 155 binding->CheckTrackSamples(binding->mVideoTrack) 156 ->Then( 157 binding->mTaskQueue, __func__, 158 [binding]() { 159 binding->CheckTrackKeyFrame(binding->mVideoTrack) 160 ->Then( 161 binding->mTaskQueue, __func__, 162 [binding]() { binding->mTaskQueue->BeginShutdown(); }, 163 DO_FAIL); 164 }, 165 DO_FAIL); 166 }); 167 } 168 169 static nsCString ToCryptoString(const CryptoSample& aCrypto) { 170 nsCString res; 171 if (aCrypto.IsEncrypted()) { 172 res.AppendPrintf("%d ", aCrypto.mIVSize); 173 for (size_t i = 0; i < aCrypto.mKeyId.Length(); i++) { 174 res.AppendPrintf("%02x", aCrypto.mKeyId[i]); 175 } 176 res.AppendLiteral(" "); 177 for (size_t i = 0; i < aCrypto.mIV.Length(); i++) { 178 res.AppendPrintf("%02x", aCrypto.mIV[i]); 179 } 180 EXPECT_EQ(aCrypto.mPlainSizes.Length(), aCrypto.mEncryptedSizes.Length()); 181 for (size_t i = 0; i < aCrypto.mPlainSizes.Length(); i++) { 182 res.AppendPrintf(" %d,%d", aCrypto.mPlainSizes[i], 183 aCrypto.mEncryptedSizes[i]); 184 } 185 } else { 186 res.AppendLiteral("no crypto"); 187 } 188 return res; 189 } 190 191 TEST(MP4Demuxer, CENCFragVideo) 192 { 193 const char* video[] = { 194 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000000 " 195 "5,684 5,16980", 196 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000450 " 197 "5,1826", 198 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000004c3 " 199 "5,1215", 200 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000050f " 201 "5,1302", 202 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000561 " 203 "5,939", 204 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000059c " 205 "5,763", 206 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000005cc " 207 "5,672", 208 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000005f6 " 209 "5,748", 210 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000625 " 211 "5,1025", 212 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000666 " 213 "5,730", 214 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000694 " 215 "5,897", 216 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000006cd " 217 "5,643", 218 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000006f6 " 219 "5,556", 220 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000719 " 221 "5,527", 222 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000073a " 223 "5,606", 224 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000760 " 225 "5,701", 226 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000078c " 227 "5,531", 228 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000007ae " 229 "5,562", 230 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000007d2 " 231 "5,576", 232 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000007f6 " 233 "5,514", 234 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000817 " 235 "5,404", 236 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000831 " 237 "5,635", 238 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000859 " 239 "5,433", 240 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000875 " 241 "5,478", 242 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000893 " 243 "5,474", 244 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000008b1 " 245 "5,462", 246 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000008ce " 247 "5,473", 248 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000008ec " 249 "5,437", 250 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000908 " 251 "5,418", 252 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000923 " 253 "5,475", 254 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000941 " 255 "5,23133", 256 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000ee7 " 257 "5,475", 258 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f05 " 259 "5,402", 260 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f1f " 261 "5,415", 262 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f39 " 263 "5,408", 264 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f53 " 265 "5,442", 266 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f6f " 267 "5,385", 268 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f88 " 269 "5,368", 270 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000f9f " 271 "5,354", 272 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000fb6 " 273 "5,400", 274 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000fcf " 275 "5,399", 276 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000000fe8 " 277 "5,1098", 278 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000102d " 279 "5,1508", 280 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000108c " 281 "5,1345", 282 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000010e1 " 283 "5,1945", 284 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000115b " 285 "5,1824", 286 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000011cd " 287 "5,2133", 288 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001253 " 289 "5,2486", 290 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000012ef " 291 "5,1739", 292 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000135c " 293 "5,1836", 294 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000013cf " 295 "5,2367", 296 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001463 " 297 "5,2571", 298 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001504 " 299 "5,3008", 300 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000015c0 " 301 "5,3255", 302 "16 7e571d037e571d037e571d037e571d03 0000000000000000000000000000168c " 303 "5,3225", 304 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001756 " 305 "5,3118", 306 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001819 " 307 "5,2407", 308 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000018b0 " 309 "5,2400", 310 "16 7e571d037e571d037e571d037e571d03 00000000000000000000000000001946 " 311 "5,2158", 312 "16 7e571d037e571d037e571d037e571d03 000000000000000000000000000019cd " 313 "5,2392", 314 }; 315 316 RefPtr<MP4DemuxerBinding> binding = new MP4DemuxerBinding("gizmo-frag.mp4"); 317 318 binding->RunTestAndWait([binding, video]() { 319 // grab all video samples. 320 binding->mVideoTrack = 321 binding->mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0); 322 binding->CheckTrackSamples(binding->mVideoTrack) 323 ->Then( 324 binding->mTaskQueue, __func__, 325 [binding, video]() { 326 for (uint32_t i = 0; i < binding->mSamples.Length(); i++) { 327 nsCString text = ToCryptoString(binding->mSamples[i]->mCrypto); 328 EXPECT_STREQ(video[i++], text.get()); 329 } 330 EXPECT_EQ(std::size(video), binding->mSamples.Length()); 331 binding->mTaskQueue->BeginShutdown(); 332 }, 333 DO_FAIL); 334 }); 335 } 336 337 TEST(MP4Demuxer, CENCFragAudio) 338 { 339 const char* audio[] = { 340 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000000 " 341 "0,281", 342 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000012 " 343 "0,257", 344 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000023 " 345 "0,246", 346 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000033 " 347 "0,257", 348 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000044 " 349 "0,260", 350 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000055 " 351 "0,260", 352 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000066 " 353 "0,272", 354 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000077 " 355 "0,280", 356 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000089 " 357 "0,284", 358 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000009b " 359 "0,290", 360 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000000ae " 361 "0,278", 362 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000000c0 " 363 "0,268", 364 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000000d1 " 365 "0,307", 366 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000000e5 " 367 "0,290", 368 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000000f8 " 369 "0,304", 370 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000010b " 371 "0,316", 372 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000011f " 373 "0,308", 374 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000133 " 375 "0,301", 376 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000146 " 377 "0,318", 378 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000015a " 379 "0,311", 380 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000016e " 381 "0,303", 382 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000181 " 383 "0,325", 384 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000196 " 385 "0,334", 386 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000001ab " 387 "0,344", 388 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000001c1 " 389 "0,344", 390 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000001d7 " 391 "0,387", 392 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000001f0 " 393 "0,396", 394 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000209 " 395 "0,368", 396 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000220 " 397 "0,373", 398 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000238 " 399 "0,425", 400 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000253 " 401 "0,428", 402 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000026e " 403 "0,426", 404 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000289 " 405 "0,427", 406 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000002a4 " 407 "0,424", 408 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000002bf " 409 "0,447", 410 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000002db " 411 "0,446", 412 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000002f7 " 413 "0,442", 414 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000313 " 415 "0,444", 416 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000032f " 417 "0,374", 418 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000347 " 419 "0,405", 420 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000361 " 421 "0,372", 422 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000379 " 423 "0,395", 424 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000392 " 425 "0,435", 426 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000003ae " 427 "0,426", 428 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000003c9 " 429 "0,430", 430 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000003e4 " 431 "0,390", 432 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000003fd " 433 "0,335", 434 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000412 " 435 "0,339", 436 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000428 " 437 "0,352", 438 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000043e " 439 "0,364", 440 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000455 " 441 "0,398", 442 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000046e " 443 "0,451", 444 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000048b " 445 "0,448", 446 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000004a7 " 447 "0,436", 448 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000004c3 " 449 "0,424", 450 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000004de " 451 "0,428", 452 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000004f9 " 453 "0,413", 454 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000513 " 455 "0,430", 456 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000052e " 457 "0,450", 458 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000054b " 459 "0,386", 460 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000564 " 461 "0,320", 462 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000578 " 463 "0,347", 464 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000058e " 465 "0,382", 466 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000005a6 " 467 "0,437", 468 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000005c2 " 469 "0,387", 470 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000005db " 471 "0,340", 472 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000005f1 " 473 "0,337", 474 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000607 " 475 "0,389", 476 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000620 " 477 "0,428", 478 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000063b " 479 "0,426", 480 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000656 " 481 "0,446", 482 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000672 " 483 "0,456", 484 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000068f " 485 "0,468", 486 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000006ad " 487 "0,468", 488 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000006cb " 489 "0,463", 490 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000006e8 " 491 "0,467", 492 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000706 " 493 "0,460", 494 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000723 " 495 "0,446", 496 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000073f " 497 "0,453", 498 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000075c " 499 "0,448", 500 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000778 " 501 "0,446", 502 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000794 " 503 "0,439", 504 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000007b0 " 505 "0,436", 506 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000007cc " 507 "0,441", 508 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000007e8 " 509 "0,465", 510 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000806 " 511 "0,448", 512 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000822 " 513 "0,448", 514 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000083e " 515 "0,469", 516 "16 7e571d047e571d047e571d047e571d04 0000000000000000000000000000085c " 517 "0,431", 518 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000877 " 519 "0,437", 520 "16 7e571d047e571d047e571d047e571d04 00000000000000000000000000000893 " 521 "0,474", 522 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000008b1 " 523 "0,436", 524 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000008cd " 525 "0,433", 526 "16 7e571d047e571d047e571d047e571d04 000000000000000000000000000008e9 " 527 "0,481", 528 }; 529 530 RefPtr<MP4DemuxerBinding> binding = new MP4DemuxerBinding("gizmo-frag.mp4"); 531 532 binding->RunTestAndWait([binding, audio]() { 533 // grab all audio samples. 534 binding->mAudioTrack = 535 binding->mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0); 536 binding->CheckTrackSamples(binding->mAudioTrack) 537 ->Then( 538 binding->mTaskQueue, __func__, 539 [binding, audio]() { 540 EXPECT_TRUE(binding->mSamples.Length() > 1); 541 for (uint32_t i = 0; i < binding->mSamples.Length(); i++) { 542 nsCString text = ToCryptoString(binding->mSamples[i]->mCrypto); 543 EXPECT_STREQ(audio[i++], text.get()); 544 } 545 EXPECT_EQ(std::size(audio), binding->mSamples.Length()); 546 binding->mTaskQueue->BeginShutdown(); 547 }, 548 DO_FAIL); 549 }); 550 } 551 552 TEST(MP4Demuxer, GetNextKeyframe) 553 { 554 RefPtr<MP4DemuxerBinding> binding = new MP4DemuxerBinding("gizmo-frag.mp4"); 555 556 binding->RunTestAndWait([binding]() { 557 // Insert a [0,end] buffered range, to simulate Moof's being buffered 558 // via MSE. 559 auto len = binding->resource->GetLength(); 560 binding->resource->MockAddBufferedRange(0, len); 561 562 // gizmp-frag has two keyframes; one at dts=cts=0, and another at 563 // dts=cts=1000000. Verify we get expected results. 564 TimeUnit time; 565 binding->mVideoTrack = 566 binding->mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0); 567 binding->mVideoTrack->Reset(); 568 binding->mVideoTrack->GetNextRandomAccessPoint(&time); 569 EXPECT_EQ(time.ToMicroseconds(), 0); 570 binding->mVideoTrack->GetSamples()->Then( 571 binding->mTaskQueue, __func__, 572 [binding]() { 573 TimeUnit time; 574 binding->mVideoTrack->GetNextRandomAccessPoint(&time); 575 EXPECT_EQ(time.ToMicroseconds(), 1000000); 576 binding->mTaskQueue->BeginShutdown(); 577 }, 578 DO_FAIL); 579 }); 580 } 581 582 TEST(MP4Demuxer, ZeroInLastMoov) 583 { 584 RefPtr<MP4DemuxerBinding> binding = 585 new MP4DemuxerBinding("short-zero-in-moov.mp4"); 586 binding->RunTestAndWait([binding]() { 587 // It demuxes without error. That is sufficient. 588 binding->mTaskQueue->BeginShutdown(); 589 }); 590 } 591 592 TEST(MP4Demuxer, ZeroInMoovQuickTime) 593 { 594 RefPtr<MP4DemuxerBinding> binding = 595 new MP4DemuxerBinding("short-zero-inband.mov"); 596 binding->RunTestAndWait([binding]() { 597 // It demuxes without error. That is sufficient. 598 binding->mTaskQueue->BeginShutdown(); 599 }); 600 } 601 602 TEST(MP4Demuxer, IgnoreMinus1Duration) 603 { 604 RefPtr<MP4DemuxerBinding> binding = 605 new MP4DemuxerBinding("negative_duration.mp4"); 606 binding->RunTestAndWait([binding]() { 607 // It demuxes without error. That is sufficient. 608 binding->mTaskQueue->BeginShutdown(); 609 }); 610 } 611 612 #undef DO_FAIL