TestBitWriter.cpp (4212B)
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 <stdint.h> 8 9 #include "BitReader.h" 10 #include "BitWriter.h" 11 #include "H264.h" 12 #include "gtest/gtest.h" 13 14 using namespace mozilla; 15 16 TEST(BitWriter, BitWriter) 17 { 18 RefPtr<MediaByteBuffer> test = new MediaByteBuffer(); 19 BitWriter b(test); 20 b.WriteBit(false); 21 b.WriteBits(~1ULL, 1); // ensure that extra bits don't modify byte buffer. 22 b.WriteBits(3, 1); 23 b.WriteUE(1280 / 16 - 1); 24 b.WriteUE(720 / 16 - 1); 25 b.WriteUE(1280); 26 b.WriteUE(720); 27 b.WriteBit(true); 28 b.WriteBit(false); 29 b.WriteBit(true); 30 b.WriteU8(7); 31 b.WriteU32(16356); 32 b.WriteU64(116356); 33 b.WriteBits(~(0ULL) & ~1ULL, 16); 34 b.WriteULEB128(16ULL); 35 b.WriteULEB128(31895793ULL); 36 b.WriteULEB128(426894039235654ULL); 37 const uint32_t length = b.BitCount(); 38 b.CloseWithRbspTrailing(); 39 40 BitReader c(test); 41 42 EXPECT_EQ(c.ReadBit(), false); 43 EXPECT_EQ(c.ReadBit(), false); 44 EXPECT_EQ(c.ReadBit(), true); 45 EXPECT_EQ(c.ReadUE(), 1280u / 16 - 1); 46 EXPECT_EQ(c.ReadUE(), 720u / 16 - 1); 47 EXPECT_EQ(c.ReadUE(), 1280u); 48 EXPECT_EQ(c.ReadUE(), 720u); 49 EXPECT_EQ(c.ReadBit(), true); 50 EXPECT_EQ(c.ReadBit(), false); 51 EXPECT_EQ(c.ReadBit(), true); 52 EXPECT_EQ(c.ReadBits(8), 7u); 53 EXPECT_EQ(c.ReadU32(), 16356u); 54 EXPECT_EQ(c.ReadU64(), 116356u); 55 EXPECT_EQ(c.ReadBits(16), 0xfffeu); 56 EXPECT_EQ(c.ReadULEB128(), 16ull); 57 EXPECT_EQ(c.ReadULEB128(), 31895793ull); 58 EXPECT_EQ(c.ReadULEB128(), 426894039235654ull); 59 EXPECT_EQ(length, BitReader::GetBitLength(test)); 60 } 61 62 TEST(BitWriter, AdvanceBytes) 63 { 64 RefPtr<MediaByteBuffer> test = new MediaByteBuffer(); 65 BitWriter b(test); 66 b.WriteBits(0xff, 8); 67 EXPECT_EQ(test->Length(), 1u); 68 69 uint8_t data[] = {0xfe, 0xfd}; 70 test->AppendElements(data, sizeof(data)); 71 EXPECT_EQ(test->Length(), 3u); 72 b.AdvanceBytes(2); 73 74 b.WriteBits(0xfc, 8); 75 EXPECT_EQ(test->Length(), 4u); 76 77 BitReader c(test); 78 EXPECT_EQ(c.ReadU32(), 0xfffefdfc); 79 } 80 81 TEST(BitWriter, SPS) 82 { 83 uint8_t sps_pps[] = {0x01, 0x4d, 0x40, 0x0c, 0xff, 0xe1, 0x00, 0x1b, 0x67, 84 0x4d, 0x40, 0x0c, 0xe8, 0x80, 0x80, 0x9d, 0x80, 0xb5, 85 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 86 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x0a, 0x44, 0x80, 0x01, 87 0x00, 0x04, 0x68, 0xeb, 0xef, 0x20}; 88 89 RefPtr<MediaByteBuffer> extraData = new MediaByteBuffer(); 90 extraData->AppendElements(sps_pps, sizeof(sps_pps)); 91 SPSData spsdata1; 92 bool success = H264::DecodeSPSFromExtraData(extraData, spsdata1); 93 EXPECT_EQ(success, true); 94 95 auto testOutput = [&](uint8_t aProfile, uint8_t aConstraints, uint8_t aLevel, 96 gfx::IntSize aSize, char const* aDesc) { 97 RefPtr<MediaByteBuffer> extraData = H264::CreateExtraData( 98 aProfile, aConstraints, H264_LEVEL{aLevel}, aSize); 99 SPSData spsData; 100 success = H264::DecodeSPSFromExtraData(extraData, spsData); 101 EXPECT_EQ(success, true) << aDesc; 102 EXPECT_EQ(spsData.profile_idc, aProfile) << aDesc; 103 EXPECT_EQ(spsData.constraint_set0_flag, (aConstraints >> 7) & 1) << aDesc; 104 EXPECT_EQ(spsData.constraint_set1_flag, (aConstraints >> 6) & 1) << aDesc; 105 EXPECT_EQ(spsData.constraint_set2_flag, (aConstraints >> 5) & 1) << aDesc; 106 EXPECT_EQ(spsData.constraint_set3_flag, (aConstraints >> 4) & 1) << aDesc; 107 EXPECT_EQ(spsData.constraint_set4_flag, (aConstraints >> 3) & 1) << aDesc; 108 EXPECT_EQ(spsData.constraint_set5_flag, (aConstraints >> 2) & 1) << aDesc; 109 110 EXPECT_EQ(spsData.level_idc, aLevel) << aDesc; 111 EXPECT_TRUE(!aSize.IsEmpty()); 112 EXPECT_EQ(spsData.pic_width, static_cast<uint32_t>(aSize.width)) << aDesc; 113 EXPECT_EQ(spsData.pic_height, static_cast<uint32_t>(aSize.height)) << aDesc; 114 }; 115 116 testOutput(0x42, 0x40, 0x1E, {1920, 1080}, "Constrained Baseline Profile"); 117 testOutput(0x4D, 0x00, 0x0B, {300, 300}, "Main Profile"); 118 testOutput(0x64, 0x0C, 0x33, {1280, 720}, "Constrained High Profile"); 119 }