Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/gtest/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 6 kB image not shown  

Quelle  TestAOMDecoder.cpp

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "AOMDecoder.h"
#include "gtest/gtest.h"
#include "mozilla/gfx/Types.h"
#include "nsTArray.h"

using namespace mozilla;

// AV1 §6.7.4: primary_chromaticity is 0.16 fixed-point (2^16 = 65536).
static constexpr float kAV1PrimariesDivisor = 65536.0f;
// luminance_max is 24.8 fixed-point (2^8 = 256), luminance_min is 18.14 (2^14 =
// 16384).
static constexpr float kAV1MaxLumDivisor = 256.0f;
static constexpr float kAV1MinLumDivisor = 16384.0f;

static void AppendU16BE(nsTArray<uint8_t>& aDest, uint16_t aValue) {
  aDest.AppendElement(static_cast<uint8_t>(aValue >> 8));
  aDest.AppendElement(static_cast<uint8_t>(aValue & 0xff));
}

static void AppendU32BE(nsTArray<uint8_t>& aDest, uint32_t aValue) {
  aDest.AppendElement(static_cast<uint8_t>(aValue >> 24));
  aDest.AppendElement(static_cast<uint8_t>((aValue >> 16) & 0xff));
  aDest.AppendElement(static_cast<uint8_t>((aValue >> 8) & 0xff));
  aDest.AppendElement(static_cast<uint8_t>(aValue & 0xff));
}

// Build an AV1 Metadata OBU with the given metadata_type (leb128) and payload.
// Returns the full OBU byte sequence including the OBU header + size field.
static nsTArray<uint8_t> BuildMetadataOBU(uint64_t aMetadataType,
                                          const nsTArray<uint8_t>& aPayload) {
  nsTArray<uint8_t> buf;

  // OBU header: obu_forbidden_bit=0, obu_type=5 (Metadata), obu_extension=0,
  //             obu_has_size_field=1, obu_reserved_1bit=0
  // bit layout: 0 | 00101 | 0 | 1 | 0 = 0b00101010 = 0x2A
  buf.AppendElement(0x2A);

  // metadata_type as leb128 (values 1 and 2 each fit in one byte)
  nsTArray<uint8_t> content;
  content.AppendElement(static_cast<uint8_t>(aMetadataType));
  content.AppendElements(aPayload);

  // OBU size field as leb128 (content size fits in 1 byte for small payloads)
  size_t contentLen = content.Length();
  MOZ_ASSERT(contentLen < 128);
  buf.AppendElement(static_cast<uint8_t>(contentLen));

  buf.AppendElements(content);
  return buf;
}

static nsTArray<uint8_t> BuildMDCVPayload() {
  // METADATA_TYPE_HDR_MDCV (type 2): R/G/B primaries (u16 each, 0.16
  // fixed-point) + white point (u16x2) + max/min luminance (u32 each).
  // AV1 §6.7.4 primary order: R[0], G[1], B[2].
  // Values: R=(35000,17500), G=(50000,25000), B=(15000,7500),
  //         WP=(15635,16450), maxLum=10000000, minLum=100
  // Expected: R.x=35000/65536, maxLum=10000000/256, minLum=100/16384
  nsTArray<uint8_t> p;
  AppendU16BE(p, 35000);     // R x
  AppendU16BE(p, 17500);     // R y
  AppendU16BE(p, 50000);     // G x
  AppendU16BE(p, 25000);     // G y
  AppendU16BE(p, 15000);     // B x
  AppendU16BE(p, 7500);      // B y
  AppendU16BE(p, 15635);     // white point x
  AppendU16BE(p, 16450);     // white point y
  AppendU32BE(p, 10000000);  // max luminance (24.8 fixed-point)
  AppendU32BE(p, 100);       // min luminance (18.14 fixed-point)
  return p;
}

static nsTArray<uint8_t> BuildCLLPayload() {
  // METADATA_TYPE_HDR_CLL (type 1): maxCLL u16 + maxFALL u16
  nsTArray<uint8_t> p;
  AppendU16BE(p, 1000);  // maxCLL
  AppendU16BE(p, 400);   // maxFALL
  return p;
}

TEST(AOMDecoder, ReadMetadataOBUHDR_MDCVOnly)
{
  auto mdcvPayload = BuildMDCVPayload();
  auto obu = BuildMetadataOBU(2, mdcvPayload);  // MDCV = type 2
  auto span = Span<const uint8_t>(obu.Elements(), obu.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  ASSERT_TRUE(result.isSome());
  const auto& hdr = result.value();

  ASSERT_TRUE(hdr.mSmpte2086.isSome());
  const auto& s = hdr.mSmpte2086.value();
  // AV1 primary order is R[0], G[1], B[2] — direct mapping to struct fields
  EXPECT_FLOAT_EQ(s.displayPrimaryRed.x, 35000.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.displayPrimaryRed.y, 17500.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.displayPrimaryGreen.x, 50000.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.displayPrimaryGreen.y, 25000.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.displayPrimaryBlue.x, 15000.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.displayPrimaryBlue.y, 7500.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.whitePoint.x, 15635.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.whitePoint.y, 16450.0f / kAV1PrimariesDivisor);
  EXPECT_FLOAT_EQ(s.maxLuminance, 10000000.0f / kAV1MaxLumDivisor);
  EXPECT_FLOAT_EQ(s.minLuminance, 100.0f / kAV1MinLumDivisor);
  EXPECT_TRUE(hdr.mContentLightLevel.isNothing());
}

TEST(AOMDecoder, ReadMetadataOBUHDR_CLLOnly)
{
  auto cllPayload = BuildCLLPayload();
  auto obu = BuildMetadataOBU(1, cllPayload);  // CLL = type 1
  auto span = Span<const uint8_t>(obu.Elements(), obu.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  ASSERT_TRUE(result.isSome());
  const auto& hdr = result.value();

  EXPECT_TRUE(hdr.mSmpte2086.isNothing());
  ASSERT_TRUE(hdr.mContentLightLevel.isSome());
  EXPECT_EQ(hdr.mContentLightLevel->maxContentLightLevel, 1000u);
  EXPECT_EQ(hdr.mContentLightLevel->maxFrameAverageLightLevel, 400u);
}

TEST(AOMDecoder, ReadMetadataOBUHDR_MDCVAndCLL)
{
  nsTArray<uint8_t> sample;
  auto mdcvPayload = BuildMDCVPayload();
  auto mdcvOBU = BuildMetadataOBU(2, mdcvPayload);  // MDCV = type 2
  auto cllPayload = BuildCLLPayload();
  auto cllOBU = BuildMetadataOBU(1, cllPayload);  // CLL = type 1
  sample.AppendElements(mdcvOBU);
  sample.AppendElements(cllOBU);

  auto span = Span<const uint8_t>(sample.Elements(), sample.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  ASSERT_TRUE(result.isSome());
  const auto& hdr = result.value();

  EXPECT_TRUE(hdr.mSmpte2086.isSome());
  EXPECT_TRUE(hdr.mContentLightLevel.isSome());
}

TEST(AOMDecoder, ReadMetadataOBUHDR_NoHDROBU)
{
  // A temporal delimiter OBU (type 2) — no Metadata OBU present
  nsTArray<uint8_t> sample;
  sample.AppendElement(0x12);  // obu_type=2 (TemporalDelimiter), has_size=1
  sample.AppendElement(0x00);  // size=0
  auto span = Span<const uint8_t>(sample.Elements(), sample.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  EXPECT_TRUE(result.isNothing());
}

TEST(AOMDecoder, ReadMetadataOBUHDR_WrongMDCVSize)
{
  // MDCV OBU with payload too small (< 24 bytes) — should be skipped.
  nsTArray<uint8_t> shortPayload;
  for (int i = 0; i < 10; i++) {
    shortPayload.AppendElement(0x00);
  }
  auto obu = BuildMetadataOBU(2, shortPayload);  // MDCV = type 2
  auto span = Span<const uint8_t>(obu.Elements(), obu.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  EXPECT_TRUE(result.isNothing());
}

TEST(AOMDecoder, ReadMetadataOBUHDR_WrongCLLSize)
{
  // CLL OBU with payload too small (< 4 bytes) — should be skipped.
  nsTArray<uint8_t> shortPayload;
  shortPayload.AppendElement(0x00);
  shortPayload.AppendElement(0x01);
  auto obu = BuildMetadataOBU(1, shortPayload);  // CLL = type 1
  auto span = Span<const uint8_t>(obu.Elements(), obu.Length());
  auto result = AOMDecoder::ReadMetadataOBUHDR(span);
  EXPECT_TRUE(result.isNothing());
}

Messung V0.5 in Prozent
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.