tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestMediaQueue.cpp (9774B)


      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 <gtest/gtest.h>
      8 
      9 #include "MediaData.h"
     10 #include "MediaQueue.h"
     11 #include "nsISupportsImpl.h"
     12 
     13 using namespace mozilla;
     14 using mozilla::media::TimeUnit;
     15 
     16 MediaData* CreateDataRawPtr(
     17    int64_t aStartTime, int64_t aEndTime,
     18    MediaData::Type aType = MediaData::Type::NULL_DATA) {
     19  const TimeUnit startTime = TimeUnit::FromMicroseconds(aStartTime);
     20  const TimeUnit endTime = TimeUnit::FromMicroseconds(aEndTime);
     21  MediaData* data;
     22  if (aType == MediaData::Type::AUDIO_DATA) {
     23    AlignedAudioBuffer samples;
     24    data = new AudioData(0, startTime, std::move(samples), 2, 44100);
     25    data->mDuration = endTime - startTime;
     26  } else if (aType == MediaData::Type::VIDEO_DATA) {
     27    data = new VideoData(0, startTime, endTime - startTime, true, startTime,
     28                         gfx::IntSize(), 0);
     29  } else {
     30    data = new NullData(0, startTime, endTime - startTime);
     31  }
     32  return data;
     33 }
     34 
     35 already_AddRefed<MediaData> CreateData(int64_t aStartTime, int64_t aEndTime) {
     36  RefPtr<MediaData> data = CreateDataRawPtr(aStartTime, aEndTime);
     37  return data.forget();
     38 }
     39 
     40 // Used to avoid the compile error `comparison of integers of different signs`
     41 // when comparing 'const unsigned long' and 'const int'.
     42 #define EXPECT_EQUAL_SIZE_T(lhs, rhs) EXPECT_EQ(size_t(lhs), size_t(rhs))
     43 
     44 TEST(MediaQueue, BasicPopOperations)
     45 {
     46  MediaQueue<MediaData> queue;
     47  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
     48 
     49  // Test only one element
     50  const RefPtr<MediaData> data = CreateDataRawPtr(0, 10);
     51  queue.Push(data.get());
     52  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
     53 
     54  RefPtr<MediaData> rv = queue.PopFront();
     55  EXPECT_EQ(rv, data);
     56 
     57  queue.Push(data.get());
     58  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
     59 
     60  rv = queue.PopBack();
     61  EXPECT_EQ(rv, data);
     62  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
     63 
     64  // Test multiple elements
     65  const RefPtr<MediaData> data1 = CreateDataRawPtr(0, 10);
     66  const RefPtr<MediaData> data2 = CreateDataRawPtr(11, 20);
     67  const RefPtr<MediaData> data3 = CreateDataRawPtr(21, 30);
     68  queue.Push(data1.get());
     69  queue.Push(data2.get());
     70  queue.Push(data3.get());
     71  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 3);
     72 
     73  rv = queue.PopFront();
     74  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 2);
     75  EXPECT_EQ(rv, data1);
     76 
     77  rv = queue.PopBack();
     78  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
     79  EXPECT_EQ(rv, data3);
     80 
     81  rv = queue.PopBack();
     82  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
     83  EXPECT_EQ(rv, data2);
     84 }
     85 
     86 TEST(MediaQueue, BasicPeekOperations)
     87 {
     88  MediaQueue<MediaData> queue;
     89  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
     90 
     91  // Test only one element
     92  const RefPtr<MediaData> data1 = CreateDataRawPtr(0, 10);
     93  queue.Push(data1.get());
     94  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
     95 
     96  RefPtr<MediaData> rv = queue.PeekFront();
     97  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
     98  EXPECT_EQ(rv, data1);
     99 
    100  rv = queue.PeekBack();
    101  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
    102  EXPECT_EQ(rv, data1);
    103 
    104  // Test multiple elements
    105  const RefPtr<MediaData> data2 = CreateDataRawPtr(11, 20);
    106  const RefPtr<MediaData> data3 = CreateDataRawPtr(21, 30);
    107  queue.Push(data2.get());
    108  queue.Push(data3.get());
    109  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 3);
    110 
    111  rv = queue.PeekFront();
    112  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 3);
    113  EXPECT_EQ(rv, data1);
    114 
    115  rv = queue.PeekBack();
    116  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 3);
    117  EXPECT_EQ(rv, data3);
    118 }
    119 
    120 TEST(MediaQueue, FinishQueue)
    121 {
    122  MediaQueue<MediaData> queue;
    123  EXPECT_FALSE(queue.IsFinished());
    124 
    125  queue.Finish();
    126  EXPECT_TRUE(queue.IsFinished());
    127 }
    128 
    129 TEST(MediaQueue, EndOfStream)
    130 {
    131  MediaQueue<MediaData> queue;
    132  EXPECT_FALSE(queue.IsFinished());
    133 
    134  queue.Push(CreateData(0, 10));
    135  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
    136 
    137  queue.Finish();
    138  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 1);
    139  EXPECT_TRUE(queue.IsFinished());
    140  EXPECT_FALSE(queue.AtEndOfStream());
    141 
    142  RefPtr<MediaData> rv = queue.PopFront();
    143  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
    144  EXPECT_TRUE(queue.IsFinished());
    145  EXPECT_TRUE(queue.AtEndOfStream());
    146 }
    147 
    148 TEST(MediaQueue, QueueDuration)
    149 {
    150  MediaQueue<MediaData> queue;
    151  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 0);
    152 
    153  queue.Push(CreateData(0, 10));
    154  queue.Push(CreateData(11, 20));
    155  queue.Push(CreateData(21, 30));
    156  EXPECT_EQUAL_SIZE_T(queue.GetSize(), 3);
    157 
    158  const int64_t rv = queue.Duration();
    159  EXPECT_EQ(rv, 30);
    160 }
    161 
    162 TEST(MediaQueue, CallGetElementAfterOnSingleElement)
    163 {
    164  MediaQueue<MediaData> queue;
    165  queue.Push(CreateData(0, 10));
    166 
    167  // Target time is earlier than data's end time
    168  TimeUnit targetTime = TimeUnit::FromMicroseconds(5);
    169  nsTArray<RefPtr<MediaData>> foundResult;
    170  queue.GetElementsAfter(targetTime, &foundResult);
    171  EXPECT_EQUAL_SIZE_T(foundResult.Length(), 1);
    172  EXPECT_TRUE(foundResult[0]->GetEndTime() > targetTime);
    173 
    174  // Target time is later than data's end time
    175  targetTime = TimeUnit::FromMicroseconds(15);
    176  nsTArray<RefPtr<MediaData>> emptyResult;
    177  queue.GetElementsAfter(targetTime, &emptyResult);
    178  EXPECT_TRUE(emptyResult.IsEmpty());
    179 }
    180 
    181 TEST(MediaQueue, CallGetElementAfterOnMultipleElements)
    182 {
    183  MediaQueue<MediaData> queue;
    184  queue.Push(CreateData(0, 10));
    185  queue.Push(CreateData(11, 20));
    186  queue.Push(CreateData(21, 30));
    187  queue.Push(CreateData(31, 40));
    188  queue.Push(CreateData(41, 50));
    189 
    190  // Should find [21,30], [31,40] and [41,50]
    191  TimeUnit targetTime = TimeUnit::FromMicroseconds(25);
    192  nsTArray<RefPtr<MediaData>> foundResult;
    193  queue.GetElementsAfter(targetTime, &foundResult);
    194  EXPECT_EQUAL_SIZE_T(foundResult.Length(), 3);
    195  for (const auto& data : foundResult) {
    196    EXPECT_TRUE(data->GetEndTime() > targetTime);
    197  }
    198 
    199  // Should find [31,40] and [41,50]
    200  targetTime = TimeUnit::FromMicroseconds(30);
    201  foundResult.Clear();
    202  queue.GetElementsAfter(targetTime, &foundResult);
    203  EXPECT_EQUAL_SIZE_T(foundResult.Length(), 2);
    204  for (const auto& data : foundResult) {
    205    EXPECT_TRUE(data->GetEndTime() > targetTime);
    206  }
    207 
    208  // Should find no data.
    209  targetTime = TimeUnit::FromMicroseconds(60);
    210  nsTArray<RefPtr<MediaData>> emptyResult;
    211  queue.GetElementsAfter(targetTime, &emptyResult);
    212  EXPECT_TRUE(emptyResult.IsEmpty());
    213 }
    214 
    215 TEST(MediaQueue, TimestampAdjustmentForSupportDataType)
    216 {
    217  const size_t kOffSet = 30;
    218  {
    219    MediaQueue<AudioData> audioQueue;
    220    audioQueue.Push(
    221        CreateDataRawPtr(0, 10, MediaData::Type::AUDIO_DATA)->As<AudioData>());
    222    audioQueue.SetOffset(TimeUnit::FromMicroseconds(kOffSet));
    223    audioQueue.Push(
    224        CreateDataRawPtr(0, 10, MediaData::Type::AUDIO_DATA)->As<AudioData>());
    225 
    226    // Data stored before setting the offset shouldn't be changed
    227    RefPtr<AudioData> data = audioQueue.PopFront();
    228    EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    229    EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    230 
    231    // Data stored after setting the offset should be changed
    232    data = audioQueue.PopFront();
    233    EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0 + kOffSet));
    234    EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10 + kOffSet));
    235 
    236    // Reset will clean the offset.
    237    audioQueue.Reset();
    238    audioQueue.Push(
    239        CreateDataRawPtr(0, 10, MediaData::Type::AUDIO_DATA)->As<AudioData>());
    240    data = audioQueue.PopFront();
    241    EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    242    EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    243  }
    244 
    245  // Check another supported type
    246  MediaQueue<VideoData> videoQueue;
    247  videoQueue.Push(
    248      CreateDataRawPtr(0, 10, MediaData::Type::VIDEO_DATA)->As<VideoData>());
    249  videoQueue.SetOffset(TimeUnit::FromMicroseconds(kOffSet));
    250  videoQueue.Push(
    251      CreateDataRawPtr(0, 10, MediaData::Type::VIDEO_DATA)->As<VideoData>());
    252 
    253  // Data stored before setting the offset shouldn't be changed
    254  RefPtr<VideoData> data = videoQueue.PopFront();
    255  EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    256  EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    257 
    258  // Data stored after setting the offset should be changed
    259  data = videoQueue.PopFront();
    260  EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0 + kOffSet));
    261  EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10 + kOffSet));
    262 
    263  // Reset will clean the offset.
    264  videoQueue.Reset();
    265  videoQueue.Push(
    266      CreateDataRawPtr(0, 10, MediaData::Type::VIDEO_DATA)->As<VideoData>());
    267  data = videoQueue.PopFront();
    268  EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    269  EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    270 }
    271 
    272 TEST(MediaQueue, TimestampAdjustmentForNotSupportDataType)
    273 {
    274  const size_t kOffSet = 30;
    275 
    276  MediaQueue<MediaData> queue;
    277  queue.Push(CreateDataRawPtr(0, 10));
    278  queue.SetOffset(TimeUnit::FromMicroseconds(kOffSet));
    279  queue.Push(CreateDataRawPtr(0, 10));
    280 
    281  // Offset won't affect any data at all.
    282  RefPtr<MediaData> data = queue.PopFront();
    283  EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    284  EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    285 
    286  data = queue.PopFront();
    287  EXPECT_EQ(data->mTime, TimeUnit::FromMicroseconds(0));
    288  EXPECT_EQ(data->GetEndTime(), TimeUnit::FromMicroseconds(10));
    289 }
    290 
    291 TEST(MediaQueue, PreciseDuration)
    292 {
    293  MediaQueue<MediaData> queueOff;
    294  queueOff.Push(CreateDataRawPtr(5, 10));
    295  queueOff.Push(CreateDataRawPtr(0, 5));
    296  EXPECT_EQ(queueOff.Duration(), 0);
    297  EXPECT_EQ(queueOff.PreciseDuration(), -1);
    298 
    299  MediaQueue<MediaData> queueOn(true /* aEnablePreciseDuration */);
    300  queueOn.Push(CreateDataRawPtr(5, 10));
    301  queueOn.Push(CreateDataRawPtr(0, 5));
    302  EXPECT_EQ(queueOn.Duration(), 0);
    303  EXPECT_EQ(queueOn.PreciseDuration(), 10);
    304 }
    305 
    306 #undef EXPECT_EQUAL_SIZE_T