tor-browser

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

TestContainerParser.cpp (5633B)


      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 <stdint.h>
      8 
      9 #include "ContainerParser.h"
     10 #include "mozilla/gtest/MozAssertions.h"
     11 
     12 using namespace mozilla;
     13 using TimeUnit = mozilla::media::TimeUnit;
     14 
     15 TEST(ContainerParser, MIMETypes)
     16 {
     17  const char* containerTypes[] = {"video/webm", "audio/webm", "video/mp4",
     18                                  "audio/mp4", "audio/aac"};
     19  UniquePtr<ContainerParser> parser;
     20  for (size_t i = 0; i < std::size(containerTypes); ++i) {
     21    Maybe<MediaContainerType> containerType =
     22        MakeMediaContainerType(containerTypes[i]);
     23    ASSERT_TRUE(containerType.isSome());
     24    parser = ContainerParser::CreateForMIMEType(*containerType);
     25    ASSERT_NE(parser, nullptr);
     26  }
     27 }
     28 
     29 already_AddRefed<MediaByteBuffer> make_adts_header() {
     30  const uint8_t test[] = {0xff, 0xf1, 0x50, 0x80, 0x03, 0x1f, 0xfc};
     31  RefPtr<MediaByteBuffer> buffer(new MediaByteBuffer);
     32  buffer->AppendElements(test, std::size(test));
     33  return buffer.forget();
     34 }
     35 
     36 TEST(ContainerParser, ADTSHeader)
     37 {
     38  UniquePtr<ContainerParser> parser;
     39  parser = ContainerParser::CreateForMIMEType(
     40      MediaContainerType(MEDIAMIMETYPE("audio/aac")));
     41  ASSERT_NE(parser, nullptr);
     42 
     43  // Audio data should have no gaps.
     44  EXPECT_EQ(parser->GetRoundingError(), 0);
     45 
     46  // Test a valid header.
     47  RefPtr<MediaByteBuffer> header = make_adts_header();
     48  EXPECT_NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header)));
     49 
     50  // Test variations.
     51  uint8_t save = header->ElementAt(1);
     52  for (uint8_t i = 1; i < 3; ++i) {
     53    // Set non-zero layer.
     54    header->ReplaceElementAt(1, (header->ElementAt(1) & 0xf9) | (i << 1));
     55    EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header))))
     56        << "Accepted non-zero layer in header.";
     57  }
     58  header->ReplaceElementAt(1, save);
     59  save = header->ElementAt(2);
     60  header->ReplaceElementAt(2, (header->ElementAt(2) & 0x3b) | (15 << 2));
     61  EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header))))
     62      << "Accepted explicit frequency in header.";
     63  header->ReplaceElementAt(2, save);
     64 
     65  // Test a short header.
     66  header->SetLength(6);
     67  EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header))))
     68      << "Accepted too-short header.";
     69  EXPECT_FALSE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(MediaSpan(header))))
     70      << "Found media segment when there was just a partial header.";
     71 
     72  // Test a header with short data.
     73  header = make_adts_header();
     74  header->AppendElements(1);
     75  EXPECT_TRUE(NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header))))
     76      << "Rejected a valid header.";
     77  EXPECT_TRUE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(MediaSpan(header))))
     78      << "Rejected a one-byte media segment.";
     79 
     80  // Test parse results.
     81  header = make_adts_header();
     82  EXPECT_FALSE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(MediaSpan(header))))
     83      << "Found media segment when there was just a header.";
     84  TimeUnit start;
     85  TimeUnit end;
     86  EXPECT_TRUE(NS_FAILED(
     87      parser->ParseStartAndEndTimestamps(MediaSpan(header), start, end)));
     88 
     89  EXPECT_TRUE(parser->HasInitData());
     90  EXPECT_TRUE(parser->HasCompleteInitData());
     91  MediaByteBuffer* init = parser->InitData();
     92  ASSERT_NE(init, nullptr);
     93  EXPECT_EQ(init->Length(), header->Length());
     94 
     95  EXPECT_EQ(parser->InitSegmentRange(),
     96            MediaByteRange(0, int64_t(header->Length())));
     97  // Media segment range should be empty here.
     98  EXPECT_EQ(parser->MediaHeaderRange(), MediaByteRange());
     99  EXPECT_EQ(parser->MediaSegmentRange(), MediaByteRange());
    100 }
    101 
    102 TEST(ContainerParser, ADTSBlankMedia)
    103 {
    104  UniquePtr<ContainerParser> parser;
    105  parser = ContainerParser::CreateForMIMEType(
    106      MediaContainerType(MEDIAMIMETYPE("audio/aac")));
    107  ASSERT_NE(parser, nullptr);
    108 
    109  // Audio data should have no gaps.
    110  EXPECT_EQ(parser->GetRoundingError(), 0);
    111 
    112  // Test the header only.
    113  RefPtr<MediaByteBuffer> header = make_adts_header();
    114  EXPECT_NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header)));
    115 
    116  // Test with the correct length of (invalid) frame data.
    117  size_t header_length = header->Length();
    118  size_t data_length = 24;
    119  size_t frame_length = header_length + data_length;
    120  header->AppendElements(data_length);
    121  EXPECT_TRUE(NS_SUCCEEDED(parser->IsInitSegmentPresent(MediaSpan(header))))
    122      << "Rejected a valid header.";
    123  EXPECT_TRUE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(MediaSpan(header))))
    124      << "Rejected a full (but zeroed) media segment.";
    125  TimeUnit start;
    126  TimeUnit end;
    127  // We don't report timestamps from ADTS.
    128  EXPECT_TRUE(NS_FAILED(
    129      parser->ParseStartAndEndTimestamps(MediaSpan(header), start, end)));
    130  EXPECT_TRUE(start.IsZero());
    131  EXPECT_TRUE(end.IsZero());
    132 
    133  // Verify the parser calculated header and packet data boundaries.
    134  EXPECT_TRUE(parser->HasInitData());
    135  EXPECT_TRUE(parser->HasCompleteInitData());
    136  MediaByteBuffer* init = parser->InitData();
    137  ASSERT_NE(init, nullptr);
    138  EXPECT_EQ(init->Length(), header_length)
    139      << "Found incorrect init segment length.";
    140  EXPECT_EQ(parser->InitSegmentRange(),
    141            MediaByteRange(0, int64_t(header_length)));
    142  // In ADTS the Media Header is the same as the Media Segment.
    143  MediaByteRange expected_media =
    144      MediaByteRange(int64_t(header_length), int64_t(frame_length));
    145  EXPECT_EQ(parser->MediaHeaderRange(), expected_media);
    146  EXPECT_EQ(parser->MediaSegmentRange(), expected_media);
    147 }