Coverage Report

Created: 2018-09-25 14:53

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