Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/mediacapabilities/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  DecoderBenchmark.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "DecoderBenchmark.h"
#include "mozilla/BenchmarkStorageChild.h"
#include "mozilla/media/MediaUtils.h"
#include "mozilla/StaticPrefs_media.h"

namespace mozilla {

void DecoderBenchmark::StoreScore(const nsACString& aDecoderName,
                                  const nsACString& aKey,
                                  RefPtr<FrameStatistics> aStats) {
  FrameStatisticsData statsData = aStats->GetFrameStatisticsData();
  uint64_t totalFrames = FrameStatistics::GetTotalFrames(statsData);
  uint64_t droppedFrames = FrameStatistics::GetDroppedFrames(statsData);

  MOZ_ASSERT(droppedFrames <= totalFrames);
  MOZ_ASSERT(totalFrames >= mLastTotalFrames);
  MOZ_ASSERT(droppedFrames >= mLastDroppedFrames);

  uint64_t diffTotalFrames = totalFrames - mLastTotalFrames;
  uint64_t diffDroppedFrames = droppedFrames - mLastDroppedFrames;

  /* Update now in case the method returns at the if check bellow. */
  mLastTotalFrames = totalFrames;
  mLastDroppedFrames = droppedFrames;

  /* A minimum number of 10 frames is required to store the score. */
  if (diffTotalFrames < 10) {
    return;
  }

  int32_t percentage =
      100 - 100 * float(diffDroppedFrames) / float(diffTotalFrames);

  MOZ_ASSERT(percentage >= 0);

  Put(aDecoderName, aKey, percentage);
}

void DecoderBenchmark::Put(const nsACString& aDecoderName,
                           const nsACString& aKey, int32_t aValue) {
  MOZ_ASSERT(NS_IsMainThread());
  const nsCString name(aDecoderName);
  const nsCString key(aKey);
  BenchmarkStorageChild::Instance()->SendPut(name, key, aValue);
}

RefPtr<BenchmarkScorePromise> DecoderBenchmark::GetScore(
    const nsACString& aDecoderName, const nsACString& aKey) {
  if (NS_IsMainThread()) {
    return Get(aDecoderName, aKey);
  }

  RefPtr<DecoderBenchmark> self = this;
  const nsCString decoderName(aDecoderName);
  const nsCString key(aKey);
  return InvokeAsync(
      GetMainThreadSerialEventTarget(), __func__,
      [self, decoderName, key] { return self->Get(decoderName, key); });
}

RefPtr<BenchmarkScorePromise> DecoderBenchmark::Get(
    const nsACString& aDecoderName, const nsACString& aKey) {
  MOZ_ASSERT(NS_IsMainThread());

  const nsCString name(aDecoderName);
  const nsCString key(aKey);
  return BenchmarkStorageChild::Instance()->SendGet(name, key)->Then(
      GetCurrentSerialEventTarget(), __func__,
      [](int32_t aResult) {
        return BenchmarkScorePromise::CreateAndResolve(aResult, __func__);
      },
      [](ipc::ResponseRejectReason&&) {
        return BenchmarkScorePromise::CreateAndReject(NS_ERROR_FAILURE,
                                                      __func__);
      });
}

/* The key string consists of the video properties resolution, framerate,
 * and bitdepth. There are various levels for each of them. The key is
 * formated by the closest level, for example, a video with width=1920,
 * height=1080, frameRate=24, and bitdepth=8bit will have the key:
 * "ResolutionLevel5-FrameRateLevel1-8bit". */


#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))

/* Keep them sorted */
const uint32_t PixelLevels[] = {
    /* 256x144   =*/36864,
    /* 426x240   =*/102240,
    /* 640x360   =*/230400,
    /* 854x480   =*/409920,
    /* 1280x720  =*/921600,
    /* 1920x1080 =*/2073600,
    /* 2560x1440 =*/3686400,
    /* 3840x2160 =*/8294400,
};
const size_t PixelLevelsSize = NELEMS(PixelLevels);

const uint32_t FrameRateLevels[] = {
    15, 24, 30, 50, 60,
};
const size_t FrameRateLevelsSize = NELEMS(FrameRateLevels);

/* static */
nsCString KeyUtil::FindLevel(const uint32_t aLevels[], const size_t length,
                             uint32_t aValue) {
  MOZ_ASSERT(aValue);
  if (aValue <= aLevels[0]) {
    return "Level0"_ns;
  }
  nsAutoCString level("Level");
  size_t lastIndex = length - 1;
  if (aValue >= aLevels[lastIndex]) {
    level.AppendInt(static_cast<uint32_t>(lastIndex));
    return std::move(level);
  }
  for (size_t i = 0; i < lastIndex; ++i) {
    if (aValue >= aLevels[i + 1]) {
      continue;
    }
    if (aValue - aLevels[i] < aLevels[i + 1] - aValue) {
      level.AppendInt(static_cast<uint32_t>(i));
      return std::move(level);
    }
    level.AppendInt(static_cast<uint32_t>(i + 1));
    return std::move(level);
  }
  MOZ_CRASH("Array is not sorted");
  return ""_ns;
}

/* static */
nsCString KeyUtil::BitDepthToStr(uint8_t aBitDepth) {
  switch (aBitDepth) {
    case 8:  // ColorDepth::COLOR_8
      return "-8bit"_ns;
    case 10:  // ColorDepth::COLOR_10
    case 12:  // ColorDepth::COLOR_12
    case 16:  // ColorDepth::COLOR_16
      return "-non8bit"_ns;
  }
  MOZ_ASSERT_UNREACHABLE("invalid color depth value");
  return ""_ns;
}

/* static */
nsCString KeyUtil::CreateKey(const DecoderBenchmarkInfo& aBenchInfo) {
  nsAutoCString key("Resolution");
  key.Append(FindLevel(PixelLevels, PixelLevelsSize,
                       aBenchInfo.mWidth * aBenchInfo.mHeight));

  key.Append("-FrameRate");
  key.Append(
      FindLevel(FrameRateLevels, FrameRateLevelsSize, aBenchInfo.mFrameRate));

  key.Append(BitDepthToStr(aBenchInfo.mBitDepth));

  return std::move(key);
}

void DecoderBenchmark::Store(const DecoderBenchmarkInfo& aBenchInfo,
                             RefPtr<FrameStatistics> aStats) {
  if (!XRE_IsContentProcess()) {
    NS_WARNING(
        "Storing a benchmark is only allowed only from the content process.");
    return;
  }
  StoreScore(aBenchInfo.mContentType, KeyUtil::CreateKey(aBenchInfo), aStats);
}

/* static */
RefPtr<BenchmarkScorePromise> DecoderBenchmark::Get(
    const DecoderBenchmarkInfo& aBenchInfo) {
  if (!XRE_IsContentProcess()) {
    NS_WARNING(
        "Getting a benchmark is only allowed only from the content process.");
    return BenchmarkScorePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
  }
  // There is no need for any of the data members to query the database, thus
  // it can be a static method.
  auto bench = MakeRefPtr<DecoderBenchmark>();
  return bench->GetScore(aBenchInfo.mContentType,
                         KeyUtil::CreateKey(aBenchInfo));
}

static nsTHashMap<nsCStringHashKey, int32_t> DecoderVersionTable() {
  nsTHashMap<nsCStringHashKey, int32_t> decoderVersionTable;

  /*
   * For the decoders listed here, the benchmark version number will be checked.
   * If the version number does not exist in the database or is different than
   * the version number listed here, all the benchmark entries for this decoder
   * will be erased. An example of assigning the version number `1` for AV1
   * decoder is:
   *
   * decoderVersionTable.InsertOrUpdate("video/av1"_ns, 1);
   *
   * For the decoders not listed here the `CheckVersion` method exits early, to
   * avoid sending unecessary IPC messages.
   */


  return decoderVersionTable;
}

/* static */
void DecoderBenchmark::CheckVersion(const nsACString& aDecoderName) {
  if (!XRE_IsContentProcess()) {
    NS_WARNING(
        "Checking version is only allowed only from the content process.");
    return;
  }

  if (!StaticPrefs::media_mediacapabilities_from_database()) {
    return;
  }

  nsCString name(aDecoderName);
  int32_t version;
  if (!DecoderVersionTable().Get(name, &version)) {
    // A version is not set for that decoder ignore.
    return;
  }

  if (NS_IsMainThread()) {
    BenchmarkStorageChild::Instance()->SendCheckVersion(name, version);
    return;
  }

  DebugOnly<nsresult> rv =
      GetMainThreadSerialEventTarget()->Dispatch(NS_NewRunnableFunction(
          "DecoderBenchmark::CheckVersion", [name, version]() {
            BenchmarkStorageChild::Instance()->SendCheckVersion(name, version);
          }));
  MOZ_ASSERT(NS_SUCCEEDED(rv));
}

}  // namespace mozilla

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.