[TTVD] Split decoder promotion file functionalities 48/315348/2
authorJakub Gajownik <j.gajownik2@samsung.com>
Thu, 25 Jul 2024 13:15:55 +0000 (15:15 +0200)
committerBot Blink <blinkbot@samsung.com>
Tue, 30 Jul 2024 12:34:58 +0000 (12:34 +0000)
Single decoder_promotion.cc file handled multiple
responsibilities of both tracking allocated decoders and
category selection. It resulted in rather long file that's
hard to read and introduce unit tests.

After this change, category selection is splitted into
its own file which is then used by DecoderPromotion class.
Additionally, there is not function for selecting video
decoder category and it's shortened a little bit to improve
readability.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-372
Change-Id: Ief5a19f99dae2a37e3661c32d16664ee17724f58
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
media/filters/BUILD.gn
media/filters/tizen/category_selector.cc [new file with mode: 0644]
media/filters/tizen/category_selector.h [new file with mode: 0644]
media/filters/tizen/decoder_promotion.cc
media/filters/tizen/decoder_promotion.h
media/filters/tizen/decoder_promotion_test.cc
media/filters/tizen/latency_mode.h [new file with mode: 0644]
media/filters/tizen/ttvd_video_decoder_base.cc
media/filters/tizen/ttvd_video_decoder_impl.cc
tizen_src/chromium_impl/base/tizen/resource_manager.cc
tizen_src/chromium_impl/base/tizen/resource_manager.h

index 8a74138268bc3367b4767dff27115415ebe19a0d..e6f1e46f494f1a3a2cca88d1dd74c1ac9b848b97 100644 (file)
@@ -288,6 +288,8 @@ source_set("filters") {
       "//tizen_src/build:omxil-e4x12-v4l2",
     ]
     sources += [
+      "tizen/category_selector.cc",
+      "tizen/category_selector.h",
       "tizen/cdm_utils.cc",
       "tizen/cdm_utils.h",
       "tizen/decoder_facade_factory.cc",
@@ -299,6 +301,7 @@ source_set("filters") {
       "tizen/dummy_drm.cc",
       "tizen/dummy_drm.h",
       "tizen/extended_video_decoder_config.h",
+      "tizen/latency_mode.h",
       "tizen/lazy_frame_ranges.cc",
       "tizen/lazy_frame_ranges.h",
       "tizen/media_video_codec.cc",
diff --git a/media/filters/tizen/category_selector.cc b/media/filters/tizen/category_selector.cc
new file mode 100644 (file)
index 0000000..39d445d
--- /dev/null
@@ -0,0 +1,448 @@
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/tizen/category_selector.h"
+
+#include "base/bits.h"
+#include "media/base/tizen/logger/media_logger.h"
+#include "media/filters/tizen/resource_manager_utils.h"
+#include "media/video/h264_level_limits.h"
+
+namespace media {
+
+namespace {
+constexpr const gfx::Size kFullHd(1920, 1080);
+constexpr const gfx::Size kQHD(2560, 1440);
+constexpr const gfx::Size k4k(3840, 2160);
+
+absl::optional<uint32_t> H264MaxLumaSamples(VideoCodecLevel level) {
+  constexpr static const uint32_t kMaxMacroblockSize = 16;
+  auto max_macroblocks = H264LevelToMaxMBPS(level);
+  if (!max_macroblocks) {
+    return absl::nullopt;
+  }
+  return max_macroblocks * kMaxMacroblockSize * kMaxMacroblockSize;
+}
+
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+constexpr static const uint32_t kH265Level10 = 30;
+constexpr static const uint32_t kH265Level20 = 60;
+constexpr static const uint32_t kH265Level21 = 63;
+constexpr static const uint32_t kH265Level30 = 90;
+constexpr static const uint32_t kH265Level31 = 93;
+constexpr static const uint32_t kH265Level40 = 120;
+constexpr static const uint32_t kH265Level41 = 123;
+constexpr static const uint32_t kH265Level50 = 150;
+constexpr static const uint32_t kH265Level51 = 153;
+constexpr static const uint32_t kH265Level52 = 156;
+constexpr static const uint32_t kH265Level60 = 180;
+constexpr static const uint32_t kH265Level61 = 183;
+constexpr static const uint32_t kH265Level62 = 186;
+
+absl::optional<uint32_t> H265MaxLumaSamples(VideoCodecLevel level) {
+  switch (level) {
+    case kH265Level10:
+      return 552'960u;
+    case kH265Level20:
+      return 3'686'400u;
+    case kH265Level21:
+      return 7'372'800u;
+    case kH265Level30:
+      return 16'588'800u;
+    case kH265Level31:
+      return 33'177'600u;
+    case kH265Level40:
+      return 66'846'720u;
+    case kH265Level41:
+      return 133'693'440u;
+    case kH265Level50:
+      return 267'386'880u;
+    case kH265Level51:
+      return 534'773'760u;
+    case kH265Level52:
+      return 1'069'547'520u;
+    case kH265Level60:
+      return 1'069'547'520u;
+    case kH265Level61:
+      return 2'139'095'040u;
+    case kH265Level62:
+      return 4'278'190'080u;
+    default:
+      TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR) << "Invalid codec level: " << level;
+      return absl::nullopt;
+  }
+}
+#endif
+
+constexpr static const uint32_t kAV1Level20 = 0;
+constexpr static const uint32_t kAV1Level21 = 1;
+constexpr static const uint32_t kAV1Level22 = 2;
+constexpr static const uint32_t kAV1Level23 = 3;
+constexpr static const uint32_t kAV1Level30 = 4;
+constexpr static const uint32_t kAV1Level31 = 5;
+constexpr static const uint32_t kAV1Level32 = 6;
+constexpr static const uint32_t kAV1Level33 = 7;
+constexpr static const uint32_t kAV1Level40 = 8;
+constexpr static const uint32_t kAV1Level41 = 9;
+constexpr static const uint32_t kAV1Level42 = 10;
+constexpr static const uint32_t kAV1Level43 = 11;
+constexpr static const uint32_t kAV1Level50 = 12;
+constexpr static const uint32_t kAV1Level51 = 13;
+constexpr static const uint32_t kAV1Level52 = 14;
+constexpr static const uint32_t kAV1Level53 = 15;
+constexpr static const uint32_t kAV1Level60 = 16;
+constexpr static const uint32_t kAV1Level61 = 17;
+constexpr static const uint32_t kAV1Level62 = 18;
+constexpr static const uint32_t kAV1Level63 = 19;
+constexpr static const uint32_t kAV1Level70 = 20;
+constexpr static const uint32_t kAV1Level71 = 21;
+constexpr static const uint32_t kAV1Level72 = 22;
+constexpr static const uint32_t kAV1Level73 = 23;
+
+// AV1 Spec, Annex A, A.3. Levels
+absl::optional<uint32_t> AV1MaxDisplayRate(VideoCodecLevel level) {
+  switch (level) {
+    case kAV1Level73:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level72:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level71:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level70:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level63:
+      return 4'278'190'080u;
+    case kAV1Level62:
+      return 4'278'190'080u;
+    case kAV1Level61:
+      return 2'139'095'040u;
+    case kAV1Level60:
+      return 1'069'547'520u;
+    case kAV1Level53:
+      return 1'069'547'520u;
+    case kAV1Level52:
+      return 1'069'547'520u;
+    case kAV1Level51:
+      return 534'773'760u;
+    case kAV1Level50:
+      return 267'386'880u;
+    case kAV1Level43:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level42:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level41:
+      return 141'557'760u;
+    case kAV1Level40:
+      return 70'778'880u;
+    case kAV1Level33:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level32:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level31:
+      return 31'950'720u;
+    case kAV1Level30:
+      return 19'975'680u;
+    case kAV1Level23:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level22:  // limit not specified in AV1 spec
+      [[fallthrough]];
+    case kAV1Level21:
+      return 8'363'520u;
+    case kAV1Level20:
+      return 4'423'680u;
+    default:
+      TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR) << "Invalid codec level: " << level;
+      return absl::nullopt;
+  }
+}
+
+absl::optional<float> GetMaximalFramerate(MediaVideoCodec codec,
+                                          VideoCodecLevel level,
+                                          gfx::Size coded_size) {
+  if (level == kNoVideoCodecLevel) {
+    TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING) << "No video codec level";
+    return absl::nullopt;
+  }
+
+  switch (codec) {
+    case MediaVideoCodec::kCodecH264: {
+      auto max_luma_samples = H264MaxLumaSamples(level);
+      if (!max_luma_samples) {
+        return absl::nullopt;
+      }
+      return static_cast<float>(*max_luma_samples) / coded_size.width() /
+             coded_size.height();
+    }
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+    case MediaVideoCodec::kCodecHEVC: {
+      auto max_luma_samples = H265MaxLumaSamples(level);
+      if (!max_luma_samples) {
+        return absl::nullopt;
+      }
+      return static_cast<float>(*max_luma_samples) /
+             base::bits::AlignUp(coded_size.width(), 64) /
+             base::bits::AlignUp(coded_size.height(), 64);
+    }
+#endif
+    case MediaVideoCodec::kCodecAV1: {
+      auto max_display_rate = AV1MaxDisplayRate(level);
+      if (!max_display_rate) {
+        return absl::nullopt;
+      }
+      return static_cast<float>(*max_display_rate) / coded_size.width() /
+             coded_size.height();
+    }
+    default:
+      // TODO(vdwasm) Analyze need for other codec framerate calculation.
+      TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING)
+          << "Use default framerate for " << VideoCodecToCodecName(codec);
+      return absl::nullopt;
+  }
+}
+
+ri_rsc_category_e FindDecoderForResolution(
+    base::ResourceManager* manager,
+    const char* codec_name,
+    int32_t color_depth,
+    const gfx::Size& resolution,
+    uint32_t framerate,
+    ri_sampling_format sampling_format,
+    base::PreferTexturingSupport prefer_texturing_support) {
+  // Lists framerates thresholds for different resource manager decoder
+  // categories, e.g.:
+  // - RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+  // - RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P
+  constexpr uint32_t framerates[] = {0, 30, 60, 120};
+  auto it =
+      std::lower_bound(std::begin(framerates), std::end(framerates), framerate);
+  if (it == std::end(framerates))
+    --it;
+
+  uint32_t fps = framerate;
+  ri_rsc_category_e category_option = RI_CATEGORY_NONE;
+  for (; category_option <= RI_CATEGORY_NONE && *it > 0; --it) {
+    fps = *it;
+    category_option =
+        static_cast<ri_rsc_category_e>(manager->GetCapableVideoCategoryId(
+            codec_name, color_depth, resolution.width(), resolution.height(),
+            fps, sampling_format, prefer_texturing_support));
+    TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
+        << "codec: '" << codec_name << "'"
+        << " size: " << resolution.ToString() << " fps: " << fps
+        << " color_depth: " << color_depth
+        << " sampling_format: " << sampling_format
+        << " category: " << category_option;
+  }
+
+  if (category_option > RI_CATEGORY_NONE && fps != framerate) {
+    TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING)
+        << "codec: '" << codec_name << "'"
+        << " size: " << resolution.ToString() << " color_depth: " << color_depth
+        << " sampling_format: " << sampling_format
+        << " allocated category: " << category_option
+        << " using different framerate than requested,"
+        << " requested fps: " << framerate << " vs. actual fps: " << fps;
+  }
+
+  return category_option;
+}
+
+bool IsLarger(gfx::Size s1, gfx::Size s2) {
+  return s1.width() > s2.width() || s1.height() > s2.height();
+}
+
+gfx::Size RoundResolutionUp(gfx::Size coded_size) {
+  if (!IsLarger(coded_size, kFullHd)) {
+    return kFullHd;
+  } else if (!IsLarger(coded_size, kQHD)) {
+    return kQHD;
+  } else if (!IsLarger(coded_size, k4k)) {
+    return k4k;
+  } else {
+    return coded_size;
+  }
+}
+
+enum class UseHigherDecoder {
+  kNo,
+  kRecommended,
+  kRequired,
+};
+
+std::ostream& operator<<(std::ostream& stream, UseHigherDecoder value) {
+  switch (value) {
+    case UseHigherDecoder::kNo:
+      stream << "no";
+      break;
+    case UseHigherDecoder::kRecommended:
+      stream << "recommended";
+      break;
+    case UseHigherDecoder::kRequired:
+      stream << "required";
+      break;
+  }
+  return stream;
+}
+
+UseHigherDecoder ShouldUseHigherH264Decoder(
+    MediaVideoCodec codec,
+    VideoCodecLevel level,
+    gfx::Size coded_size,
+    LatencyMode latency,
+    const gpu::GpuDriverBugWorkarounds* workarounds) {
+  const bool use_h264_level50_workaround =
+      level >= 50 && !IsLarger(coded_size, kFullHd);
+  if (use_h264_level50_workaround) {
+    return UseHigherDecoder::kRequired;
+  }
+
+  if (latency == LatencyMode::kGameMode && workarounds &&
+      workarounds->ttvd_disable_faster_decoder_selection) {
+    TIZEN_MEDIA_LOG_NO_INSTANCE(INFO)
+        << "Disabling picking better decoder for game streaming";
+    return UseHigherDecoder::kNo;
+  }
+
+  return latency == LatencyMode::kGameMode ? UseHigherDecoder::kRecommended
+                                           : UseHigherDecoder::kNo;
+}
+
+ri_sampling_format ConvertChromaSampling(VideoChromaSampling sampling) {
+  switch (sampling) {
+    case VideoChromaSampling::k420:
+      return RI_SAMPLING_FORMAT_420;
+    case VideoChromaSampling::k422:
+      return RI_SAMPLING_FORMAT_422;
+    case VideoChromaSampling::k444:
+    case VideoChromaSampling::k400:
+      return RI_SAMPLING_FORMAT_OTHERS;
+    case VideoChromaSampling::kUnknown:
+      LOG(ERROR) << "Unknown chroma sampling";
+      return RI_SAMPLING_FORMAT_OTHERS;
+  }
+}
+}  // namespace
+
+absl::optional<uint32_t> DetectMaximalFramerate(MediaVideoCodec codec,
+                                                VideoCodecLevel level,
+                                                gfx::Size coded_size) {
+  auto maybe_framerate = GetMaximalFramerate(codec, level, coded_size);
+  if (!maybe_framerate) {
+    return absl::nullopt;
+  }
+  const auto framerate = *maybe_framerate;
+  TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE) << "Calculated framerate: " << framerate;
+
+  if (framerate <= 35.0f) {
+    return 30;
+  } else if (framerate <= 75.0f) {
+    return 60;
+  } else {
+    return 120;
+  }
+}
+
+ri_rsc_category_e SelectVideoDecoderCategory(
+    base::ResourceManager* resource_manager,
+    MediaVideoCodec codec,
+    VideoCodecLevel level,
+    gfx::Size coded_size,
+    VideoChromaSampling sampling,
+    size_t bit_depth,
+    LatencyMode latency,
+    const gpu::GpuDriverBugWorkarounds* workarounds) {
+  const char* codec_name = VideoCodecToCodecName(codec);
+  if (!codec_name) {
+    TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR)
+        << "Unsupported codec: " << static_cast<uint32_t>(codec);
+    return RI_CATEGORY_NONE;
+  }
+
+  // MJPEG has different path in Resource Manager.
+  if (codec == MediaVideoCodec::kCodecMJPEG) {
+    return static_cast<ri_rsc_category_e>(
+        resource_manager->GetJpegCategoryId(codec_name, coded_size.width()));
+  }
+
+  uint32_t framerate =
+      DetectMaximalFramerate(codec, level, RoundResolutionUp(coded_size))
+          .value_or(kDefaultFramerate);
+
+  // Ugly workaround for not supported profile by one of H264 decoder.
+  TIZEN_MEDIA_LOG_NO_INSTANCE(INFO)
+      << "Codec: '" << codec_name << "'"
+      << ", level: " << level << ", size: " << coded_size.ToString();
+  const auto use_h264_level50_workaround = ShouldUseHigherH264Decoder(
+      codec, level, coded_size, latency, workarounds);
+
+  const bool has_uhd_decoder = resource_manager->HasUHDVideoDecoder();
+  // Check if lowest possible configuration of HEVC is supported.
+  const bool has_hevc_decoder = resource_manager->IsCategorySupported(
+      RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P);
+  TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
+      << "use_h264_level50_workaround: " << use_h264_level50_workaround
+      << " has_uhd_decoder: " << has_uhd_decoder
+      << " has_hevc_decoder: " << has_hevc_decoder;
+
+  // When manual rendering is prefered, we should allocate decoder that
+  // supports texturing to be able to utilize software rendering mode.
+  const auto prefer_texturing_support =
+      workarounds && workarounds->ttvd_prefer_manual_rendering_for_low_latency
+          ? base::PreferTexturingSupport::kYes
+          : base::PreferTexturingSupport::kNo;
+
+  if (codec == MediaVideoCodec::kCodecH264 &&
+      use_h264_level50_workaround != UseHigherDecoder::kNo &&
+      (has_uhd_decoder || has_hevc_decoder)) {
+    const char* workaround_codec_name = codec_name;
+    gfx::Size workaround_coded_size = coded_size;
+    uint32_t workaround_framerate = framerate;
+
+    // Doing any of this might affect total bandwidth of resources, but there
+    // is no other way to do this. To ensure content is decoded without errors
+    // or latency is best affordable, we need to request higher category
+    // somehow.
+    if (has_uhd_decoder) {
+      // Request decoder for 4K resolution and calculate required framerate
+      // according to new size.
+      workaround_coded_size = k4k;
+      workaround_framerate =
+          DetectMaximalFramerate(codec, level, RoundResolutionUp(k4k))
+              .value_or(kDefaultFramerate);
+    } else if (has_hevc_decoder) {
+      // Keep the same resolution and framerate, just trick with codec,
+      // so DVDE is used.
+      workaround_codec_name =
+          VideoCodecToCodecName(MediaVideoCodec::kCodecHEVC);
+    }
+
+    auto result = FindDecoderForResolution(
+        resource_manager, workaround_codec_name, bit_depth,
+        workaround_coded_size, workaround_framerate,
+        ConvertChromaSampling(sampling), prefer_texturing_support);
+    if (result > 0) {
+      return result;
+    }
+  }
+
+  // Level 5.0 contents are not decodable using standard FullHD decoders, so
+  // do not allocate any resource in such case. Although in some cases it
+  // might work, in general it might lead to some weird errors or crashes.
+  // Note that for game streaming, we'll continue with original parameters
+  // allocation.
+  if (use_h264_level50_workaround == UseHigherDecoder::kRequired) {
+    return RI_CATEGORY_NONE;
+  }
+
+  // Try to allocate decoder using requested parameters, because either:
+  // - this codec doesn't need workaround above,
+  // - we can't apply workaround e.g. board doesn't have DVDE decoder,
+  // - we failed to allocate better decoder (DVDE), so as a fallback
+  //   try to use MFC.
+  return FindDecoderForResolution(
+      resource_manager, codec_name, bit_depth, coded_size, framerate,
+      ConvertChromaSampling(sampling), prefer_texturing_support);
+}
+
+}  // namespace media
diff --git a/media/filters/tizen/category_selector.h b/media/filters/tizen/category_selector.h
new file mode 100644 (file)
index 0000000..571bd9e
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_FILTERS_TIZEN_CATEGORY_SELECTOR_H_
+#define MEDIA_FILTERS_TIZEN_CATEGORY_SELECTOR_H_
+
+#include <ri-api.h>
+
+#include "absl/types/optional.h"
+#include "base/tizen/resource_manager.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "media/base/video_codecs.h"
+#include "media/base/video_types.h"
+#include "media/filters/tizen/latency_mode.h"
+#include "media/filters/tizen/media_video_codec.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace media {
+
+constexpr static const uint32_t kDefaultFramerate = 30;
+
+// Calculates maximal possible framerate of video in specified parameters.
+// Returns |absl::nullopt| in case it cannot be calculated (e.g codec does not
+// specify this).
+absl::optional<uint32_t> DetectMaximalFramerate(MediaVideoCodec codec,
+                                                VideoCodecLevel level,
+                                                gfx::Size coded_size);
+
+// Tries to select appropriate video decoder category to be used for hardware
+// accelerated decoding.
+ri_rsc_category_e SelectVideoDecoderCategory(
+    base::ResourceManager* resource_manager,
+    MediaVideoCodec codec,
+    VideoCodecLevel level,
+    gfx::Size coded_size,
+    VideoChromaSampling sampling,
+    size_t bit_depth,
+    LatencyMode latency,
+    const gpu::GpuDriverBugWorkarounds* workarounds);
+
+}  // namespace media
+
+#endif  // MEDIA_FILTERS_TIZEN_CATEGORY_SELECTOR_H_
index 0be4f847b6ef76c93bd4053b3a0d4099bd35d217..bc1df7983c40d1dd4641d81b6afafa91d4c1c409 100644 (file)
@@ -11,7 +11,6 @@
 
 #include "absl/types/optional.h"
 #include "base/auto_reset.h"
-#include "base/bits.h"
 #include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "media/base/media_switches.h"
 #include "media/base/tizen/logger/media_logger.h"
 #include "media/base/video_codecs.h"
-#include "media/filters/tizen/media_video_codec.h"
-#include "media/filters/tizen/resource_manager_utils.h"
-#include "media/video/h264_level_limits.h"
+#include "media/filters/tizen/category_selector.h"
 #include "tizen_src/chromium_impl/build/tizen_version.h"
 
 namespace media {
 
 namespace {
-constexpr static const uint32_t kDefaultFramerate = 30;
 constexpr static const uint32_t kMaxNDecodingFramerate = 30;
 
-constexpr const gfx::Size kFullHd(1920, 1080);
-constexpr const gfx::Size kQHD(2560, 1440);
-constexpr const gfx::Size k4k(3840, 2160);
-
-absl::optional<uint32_t> H264MaxLumaSamples(VideoCodecLevel level) {
-  constexpr static const uint32_t kMaxMacroblockSize = 16;
-  auto max_macroblocks = H264LevelToMaxMBPS(level);
-  if (!max_macroblocks) {
-    return absl::nullopt;
-  }
-  return max_macroblocks * kMaxMacroblockSize * kMaxMacroblockSize;
-}
-
-#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
-constexpr static const uint32_t kH265Level10 = 30;
-constexpr static const uint32_t kH265Level20 = 60;
-constexpr static const uint32_t kH265Level21 = 63;
-constexpr static const uint32_t kH265Level30 = 90;
-constexpr static const uint32_t kH265Level31 = 93;
-constexpr static const uint32_t kH265Level40 = 120;
-constexpr static const uint32_t kH265Level41 = 123;
-constexpr static const uint32_t kH265Level50 = 150;
-constexpr static const uint32_t kH265Level51 = 153;
-constexpr static const uint32_t kH265Level52 = 156;
-constexpr static const uint32_t kH265Level60 = 180;
-constexpr static const uint32_t kH265Level61 = 183;
-constexpr static const uint32_t kH265Level62 = 186;
-
-absl::optional<uint32_t> H265MaxLumaSamples(VideoCodecLevel level) {
-  switch (level) {
-    case kH265Level10:
-      return 552'960u;
-    case kH265Level20:
-      return 3'686'400u;
-    case kH265Level21:
-      return 7'372'800u;
-    case kH265Level30:
-      return 16'588'800u;
-    case kH265Level31:
-      return 33'177'600u;
-    case kH265Level40:
-      return 66'846'720u;
-    case kH265Level41:
-      return 133'693'440u;
-    case kH265Level50:
-      return 267'386'880u;
-    case kH265Level51:
-      return 534'773'760u;
-    case kH265Level52:
-      return 1'069'547'520u;
-    case kH265Level60:
-      return 1'069'547'520u;
-    case kH265Level61:
-      return 2'139'095'040u;
-    case kH265Level62:
-      return 4'278'190'080u;
-    default:
-      TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR) << "Invalid codec level: " << level;
-      return absl::nullopt;
-  }
-}
-#endif
-
-constexpr static const uint32_t kAV1Level20 = 0;
-constexpr static const uint32_t kAV1Level21 = 1;
-constexpr static const uint32_t kAV1Level22 = 2;
-constexpr static const uint32_t kAV1Level23 = 3;
-constexpr static const uint32_t kAV1Level30 = 4;
-constexpr static const uint32_t kAV1Level31 = 5;
-constexpr static const uint32_t kAV1Level32 = 6;
-constexpr static const uint32_t kAV1Level33 = 7;
-constexpr static const uint32_t kAV1Level40 = 8;
-constexpr static const uint32_t kAV1Level41 = 9;
-constexpr static const uint32_t kAV1Level42 = 10;
-constexpr static const uint32_t kAV1Level43 = 11;
-constexpr static const uint32_t kAV1Level50 = 12;
-constexpr static const uint32_t kAV1Level51 = 13;
-constexpr static const uint32_t kAV1Level52 = 14;
-constexpr static const uint32_t kAV1Level53 = 15;
-constexpr static const uint32_t kAV1Level60 = 16;
-constexpr static const uint32_t kAV1Level61 = 17;
-constexpr static const uint32_t kAV1Level62 = 18;
-constexpr static const uint32_t kAV1Level63 = 19;
-constexpr static const uint32_t kAV1Level70 = 20;
-constexpr static const uint32_t kAV1Level71 = 21;
-constexpr static const uint32_t kAV1Level72 = 22;
-constexpr static const uint32_t kAV1Level73 = 23;
-
-// AV1 Spec, Annex A, A.3. Levels
-absl::optional<uint32_t> AV1MaxDisplayRate(VideoCodecLevel level) {
-  switch (level) {
-    case kAV1Level73:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level72:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level71:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level70:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level63:
-      return 4'278'190'080u;
-    case kAV1Level62:
-      return 4'278'190'080u;
-    case kAV1Level61:
-      return 2'139'095'040u;
-    case kAV1Level60:
-      return 1'069'547'520u;
-    case kAV1Level53:
-      return 1'069'547'520u;
-    case kAV1Level52:
-      return 1'069'547'520u;
-    case kAV1Level51:
-      return 534'773'760u;
-    case kAV1Level50:
-      return 267'386'880u;
-    case kAV1Level43:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level42:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level41:
-      return 141'557'760u;
-    case kAV1Level40:
-      return 70'778'880u;
-    case kAV1Level33:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level32:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level31:
-      return 31'950'720u;
-    case kAV1Level30:
-      return 19'975'680u;
-    case kAV1Level23:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level22:  // limit not specified in AV1 spec
-      [[fallthrough]];
-    case kAV1Level21:
-      return 8'363'520u;
-    case kAV1Level20:
-      return 4'423'680u;
-    default:
-      TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR) << "Invalid codec level: " << level;
-      return absl::nullopt;
-  }
-}
-
-absl::optional<float> GetMaximalFramerate(MediaVideoCodec codec,
-                                          VideoCodecLevel level,
-                                          gfx::Size coded_size) {
-  if (level == kNoVideoCodecLevel) {
-    TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING) << "No video codec level";
-    return absl::nullopt;
-  }
-
-  switch (codec) {
-    case MediaVideoCodec::kCodecH264: {
-      auto max_luma_samples = H264MaxLumaSamples(level);
-      if (!max_luma_samples) {
-        return absl::nullopt;
-      }
-      return static_cast<float>(*max_luma_samples) / coded_size.width() /
-             coded_size.height();
-    }
-#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
-    case MediaVideoCodec::kCodecHEVC: {
-      auto max_luma_samples = H265MaxLumaSamples(level);
-      if (!max_luma_samples) {
-        return absl::nullopt;
-      }
-      return static_cast<float>(*max_luma_samples) /
-             base::bits::AlignUp(coded_size.width(), 64) /
-             base::bits::AlignUp(coded_size.height(), 64);
-    }
-#endif
-    case MediaVideoCodec::kCodecAV1: {
-      auto max_display_rate = AV1MaxDisplayRate(level);
-      if (!max_display_rate) {
-        return absl::nullopt;
-      }
-      return static_cast<float>(*max_display_rate) / coded_size.width() /
-             coded_size.height();
-    }
-    default:
-      // TODO(vdwasm) Analyze need for other codec framerate calculation.
-      TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING)
-          << "Use default framerate for " << VideoCodecToCodecName(codec);
-      return absl::nullopt;
-  }
-}
-
-absl::optional<uint32_t> DetectMaximalFramerate(MediaVideoCodec codec,
-                                                VideoCodecLevel level,
-                                                gfx::Size coded_size) {
-  auto maybe_framerate = GetMaximalFramerate(codec, level, coded_size);
-  if (!maybe_framerate) {
-    return absl::nullopt;
-  }
-  const auto framerate = *maybe_framerate;
-  TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE) << "Calculated framerate: " << framerate;
-
-  if (framerate <= 35.0f) {
-    return 30;
-  } else if (framerate <= 75.0f) {
-    return 60;
-  } else {
-    return 120;
-  }
-}
-
-ri_rsc_category_e FindDecoderForResolution(
-    base::ResourceManager* manager,
-    const char* codec_name,
-    int32_t color_depth,
-    const gfx::Size& resolution,
-    uint32_t framerate,
-    ri_sampling_format sampling_format,
-    base::PreferTexturingSupport prefer_texturing_support) {
-  // Lists framerates thresholds for different resource manager decoder
-  // categories, e.g.:
-  // - RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
-  // - RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P
-  constexpr uint32_t framerates[] = {0, 30, 60, 120};
-  auto it =
-      std::lower_bound(std::begin(framerates), std::end(framerates), framerate);
-  if (it == std::end(framerates))
-    --it;
-
-  uint32_t fps = framerate;
-  ri_rsc_category_e category_option = RI_CATEGORY_NONE;
-  for (; category_option <= RI_CATEGORY_NONE && *it > 0; --it) {
-    fps = *it;
-    category_option =
-        static_cast<ri_rsc_category_e>(manager->GetCapableVideoCategoryId(
-            codec_name, color_depth, resolution.width(), resolution.height(),
-            fps, sampling_format, prefer_texturing_support));
-    TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
-        << "codec: '" << codec_name << "'"
-        << " size: " << resolution.ToString() << " fps: " << fps
-        << " color_depth: " << color_depth
-        << " sampling_format: " << sampling_format
-        << " category: " << category_option;
-  }
-
-  if (category_option > RI_CATEGORY_NONE && fps != framerate) {
-    TIZEN_MEDIA_LOG_NO_INSTANCE(WARNING)
-        << "codec: '" << codec_name << "'"
-        << " size: " << resolution.ToString() << " color_depth: " << color_depth
-        << " sampling_format: " << sampling_format
-        << " allocated category: " << category_option
-        << " using different framerate than requested,"
-        << " requested fps: " << framerate << " vs. actual fps: " << fps;
-  }
-
-  return category_option;
-}
-
 bool CategoryIsNDecoding(int category) {
   if (category == RI_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P) {
     return true;
@@ -299,12 +40,12 @@ bool CategoryIsNDecoding(int category) {
   return false;
 }
 
-int MainPriority(DecoderPromotion::LatencyMode latency) {
-  if (latency == DecoderPromotion::LatencyMode::kGameMode) {
+int MainPriority(LatencyMode latency) {
+  if (latency == LatencyMode::kGameMode) {
     // We want WebRTC stream to have absolute priority before everything
     // else when game mode is set.
     return 3;
-  } else if (latency == DecoderPromotion::LatencyMode::kNormal) {
+  } else if (latency == LatencyMode::kNormal) {
     // For other purposes, prefer non-RTC players as they are less configurable
     // in terms of resolution and framerate.
     return 2;
@@ -313,8 +54,7 @@ int MainPriority(DecoderPromotion::LatencyMode latency) {
   }
 }
 
-int CalculatePriority(gfx::Size coded_size,
-                      DecoderPromotion::LatencyMode latency) {
+int CalculatePriority(gfx::Size coded_size, LatencyMode latency) {
   int main_priority = MainPriority(latency);
   int sub_priority = coded_size.GetArea();
 
@@ -324,19 +64,27 @@ int CalculatePriority(gfx::Size coded_size,
          (sub_priority & 0b1111'1111'1111'1111'1111'1111'1111);
 }
 
-ri_sampling_format ConvertChromaSampling(VideoChromaSampling sampling) {
-  switch (sampling) {
-    case VideoChromaSampling::k420:
-      return RI_SAMPLING_FORMAT_420;
-    case VideoChromaSampling::k422:
-      return RI_SAMPLING_FORMAT_422;
-    case VideoChromaSampling::k444:
-    case VideoChromaSampling::k400:
-      return RI_SAMPLING_FORMAT_OTHERS;
-    case VideoChromaSampling::kUnknown:
-      LOG(ERROR) << "Unknown chroma sampling";
-      return RI_SAMPLING_FORMAT_OTHERS;
-  }
+struct NDecodingDef {
+  gfx::Size max_resolution;
+  MediaVideoCodec codec;
+  int category;
+  size_t max_decoders;
+};
+
+constexpr static const std::array<NDecodingDef, 3> kNDecodings{{
+    {gfx::Size(1280, 720), MediaVideoCodec::kCodecH264,
+     RM_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P, 4},
+    {gfx::Size(1920, 1080), MediaVideoCodec::kCodecH264,
+     RM_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P, 2},
+    {gfx::Size(1024, 576), MediaVideoCodec::kCodecVP8,
+     RM_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P, 4},
+}};
+
+bool IsNDecodingEnabled() {
+  static const bool is_enabled =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableNDecoding);
+  return is_enabled;
 }
 }  // namespace
 
@@ -647,23 +395,6 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
   return new_decoder;
 }
 
-namespace {
-struct NDecodingDef {
-  gfx::Size max_resolution;
-  MediaVideoCodec codec;
-  int category;
-  size_t max_decoders;
-};
-constexpr static const std::array<NDecodingDef, 3> kNDecodings{{
-    {gfx::Size(1280, 720), MediaVideoCodec::kCodecH264,
-     RM_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P, 4},
-    {gfx::Size(1920, 1080), MediaVideoCodec::kCodecH264,
-     RM_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P, 2},
-    {gfx::Size(1024, 576), MediaVideoCodec::kCodecVP8,
-     RM_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P, 4},
-}};
-}  // namespace
-
 absl::optional<AllocatedDecoder> DecoderPromotion::ExtendNDecoding(
     MediaVideoCodec codec,
     VideoCodecLevel level,
@@ -717,31 +448,6 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
   return absl::nullopt;
 }
 
-namespace {
-bool IsLarger(gfx::Size s1, gfx::Size s2) {
-  return s1.width() > s2.width() || s1.height() > s2.height();
-}
-
-gfx::Size RoundResolutionUp(gfx::Size coded_size) {
-  if (!IsLarger(coded_size, kFullHd)) {
-    return kFullHd;
-  } else if (!IsLarger(coded_size, kQHD)) {
-    return kQHD;
-  } else if (!IsLarger(coded_size, k4k)) {
-    return k4k;
-  } else {
-    return coded_size;
-  }
-}
-
-bool IsNDecodingEnabled() {
-  static const bool is_enabled =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableNDecoding);
-  return is_enabled;
-}
-}  // namespace
-
 absl::optional<AllocatedDecoder> DecoderPromotion::SelectDecoder(
     MediaVideoCodec codec,
     VideoCodecLevel level,
@@ -762,109 +468,9 @@ absl::optional<AllocatedDecoder> DecoderPromotion::SelectDecoder(
 
   DumpAllocationStateLocked();
 
-  uint32_t framerate =
-      DetectMaximalFramerate(codec, level, RoundResolutionUp(coded_size))
-          .value_or(kDefaultFramerate);
-
-  const char* codec_name = VideoCodecToCodecName(codec);
-  if (!codec_name) {
-    TIZEN_MEDIA_LOG(ERROR) << "Unsupported codec: "
-                           << static_cast<uint32_t>(codec);
-    return absl::nullopt;
-  }
-
-  // MJPEG has different path in Resource Manager.
-  ri_rsc_category_e category_option = RI_CATEGORY_NONE;
-  if (codec == MediaVideoCodec::kCodecMJPEG) {
-    category_option =
-        static_cast<ri_rsc_category_e>(GetResourceManager()->GetJpegCategoryId(
-            codec_name, coded_size.width()));
-  } else {
-    // Ugly workaround for not supported profile by one of H264 decoder.
-    TIZEN_MEDIA_LOG(INFO) << "Codec: '" << codec_name << "'"
-                          << ", level: " << level
-                          << ", size: " << coded_size.ToString();
-    const bool use_h264_level50_workaround =
-        level >= 50 && !IsLarger(coded_size, kFullHd);
-    const bool has_udh_decoder = GetResourceManager()->HasUDHVideoDecoder();
-    // Check if lowest possible configuration of HEVC is supported.
-    const bool has_hevc_decoder = GetResourceManager()->IsCategorySupported(
-        RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P);
-    TIZEN_MEDIA_LOG(VERBOSE)
-        << "use_h264_level50_workaround: " << use_h264_level50_workaround
-        << " has_udh_decoder: " << has_udh_decoder
-        << " has_hevc_decoder: " << has_hevc_decoder;
-
-    bool should_use_faster_decoder_for_game_streaming =
-        latency == LatencyMode::kGameMode;
-
-    if (should_use_faster_decoder_for_game_streaming && workarounds &&
-        workarounds->ttvd_disable_faster_decoder_selection) {
-      should_use_faster_decoder_for_game_streaming = false;
-      TIZEN_MEDIA_LOG(INFO)
-          << "Disabling picking better decoder for game streaming";
-    }
-
-    // When manual rendering is prefered, we should allocate decoder that
-    // supports texturing to be able to utilize software rendering mode.
-    const auto prefer_texturing_support =
-        workarounds && workarounds->ttvd_prefer_manual_rendering_for_low_latency
-            ? base::PreferTexturingSupport::kYes
-            : base::PreferTexturingSupport::kNo;
-
-    if (codec == MediaVideoCodec::kCodecH264 &&
-        (use_h264_level50_workaround ||
-         should_use_faster_decoder_for_game_streaming) &&
-        (has_udh_decoder || has_hevc_decoder)) {
-      const char* workaround_codec_name = codec_name;
-      gfx::Size workaround_coded_size = coded_size;
-      uint32_t workaround_framerate = framerate;
-
-      // Doing any of this might affect total bandwidth of resources, but there
-      // is no other way to do this. To ensure content is decoded without errors
-      // or latency is best affordable, we need to request higher category
-      // somehow.
-      if (has_udh_decoder) {
-        // Request decoder for 4K resolution and calculate required framerate
-        // according to new size.
-        workaround_coded_size = k4k;
-        workaround_framerate =
-            DetectMaximalFramerate(codec, level, RoundResolutionUp(k4k))
-                .value_or(kDefaultFramerate);
-      } else if (has_hevc_decoder) {
-        // Keep the same resolution and framerate, just trick with codec,
-        // so DVDE is used.
-        workaround_codec_name =
-            VideoCodecToCodecName(MediaVideoCodec::kCodecHEVC);
-      }
-
-      category_option = FindDecoderForResolution(
-          GetResourceManager(), workaround_codec_name, bit_depth,
-          workaround_coded_size, workaround_framerate,
-          ConvertChromaSampling(sampling), prefer_texturing_support);
-    }
-
-    // Level 5.0 contents are not decodable using standard FullHD decoders, so
-    // do not allocate any resource in such case. Although in some cases it
-    // might work, in general it might lead to some weird errors or crashes.
-    // Note that for game streaming, we'll continue with original parameters
-    // allocation.
-    if (category_option <= 0 && use_h264_level50_workaround) {
-      return absl::nullopt;
-    }
-
-    if (category_option <= 0) {
-      // Try to allocate decoder using requested parameters, because either:
-      // - this codec doesn't need workaround above,
-      // - we can't apply workaround e.g. board doesn't have DVDE decoder,
-      // - we failed to allocate better decoder (DVDE), so as a fallback
-      //   try to use MFC.
-      category_option = FindDecoderForResolution(
-          GetResourceManager(), codec_name, bit_depth, coded_size, framerate,
-          ConvertChromaSampling(sampling), prefer_texturing_support);
-    }
-  }
-
+  ri_rsc_category_e category_option =
+      SelectVideoDecoderCategory(GetResourceManager(), codec, level, coded_size,
+                                 sampling, bit_depth, latency, workarounds);
   if (category_option <= 0) {
     TIZEN_MEDIA_LOG(ERROR) << "Failed on ri_get_capable_video_category_id: "
                            << category_option;
index d8cb547ff6b837b8de3d4ae784583110c0e2cec9..39bf8eeee16c78eb1f9bb445d4039b994f71a14e 100644 (file)
@@ -17,6 +17,7 @@
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "media/base/video_types.h"
 #include "media/filters/tizen/decoding_mode.h"
+#include "media/filters/tizen/latency_mode.h"
 #include "media/filters/tizen/media_video_codec.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -84,12 +85,6 @@ struct AllocationCallbacks {
 
 class DecoderPromotion {
  public:
-  enum class LatencyMode {
-    kNormal,
-    kLow,
-    kGameMode,
-  };
-
   // Returns the DecoderPromotion singleton.
   static DecoderPromotion* GetInstance() {
     return base::Singleton<DecoderPromotion>::get();
index 9bc36b6041eb4a569813f153522df6a3723032e8..1cc2f94037579dbbcceee02f05b6004d6938e871 100644 (file)
@@ -36,7 +36,7 @@ class FakeResourceManager : public base::ResourceManager {
   bool CanAllocate(int, int) override { return true; }
   bool SetPriority(int) override { return true; }
   bool IsCategorySupported(int) override { return true; }
-  bool HasUDHVideoDecoder() override { return true; }
+  bool HasUHDVideoDecoder() override { return true; }
   void ReleaseDevice() {
     auto token_cb = release_cb_.Run();
     base::IgnoreResult(std::move(token_cb).Run());
@@ -62,7 +62,6 @@ class FakeResourceManager : public base::ResourceManager {
 };
 
 TEST(DecoderPromotionTest, ReleaseWhileHandlingConflict) {
-  using LatencyMode = media::DecoderPromotion::LatencyMode;
   FakeResourceManager fake_resource_manager;
   DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
   decoder_promotion->SetResourceManagerForTesting(&fake_resource_manager);
@@ -121,7 +120,6 @@ TEST(DecoderPromotionTest, ReleaseWhileHandlingConflict) {
 }
 
 TEST(DecoderPromotionTest, HandleConflictAfterReleasing) {
-  using LatencyMode = media::DecoderPromotion::LatencyMode;
   FakeResourceManager fake_resource_manager;
   DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
   decoder_promotion->SetResourceManagerForTesting(&fake_resource_manager);
diff --git a/media/filters/tizen/latency_mode.h b/media/filters/tizen/latency_mode.h
new file mode 100644 (file)
index 0000000..08960ff
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2024 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_FILTERS_TIZEN_LATENCY_MODE_H_
+#define MEDIA_FILTERS_TIZEN_LATENCY_MODE_H_
+
+namespace media {
+
+enum class LatencyMode {
+  kNormal,
+  kLow,
+  kGameMode,
+};
+
+}  // namespace media
+
+#endif  // MEDIA_FILTERS_TIZEN_LATENCY_MODE_H_
index 92917a2216ae1a170ab2bb2916342f085428c5ce..d46b0db157e87ceecb0ace42616f75b2587e5fe8 100644 (file)
@@ -74,8 +74,8 @@ void TTvdVideoDecoderBase::Initialize(MediaVideoCodec codec,
       [](AllocatedDecoder decoder) { LOG(ERROR) << "To be implemented!"; });
 
   auto decoder = DecoderPromotion::GetInstance()->SelectDecoder(
-      codec, level, coded_size, sampling, bit_depth,
-      DecoderPromotion::LatencyMode::kNormal, std::move(callbacks));
+      codec, level, coded_size, sampling, bit_depth, LatencyMode::kNormal,
+      std::move(callbacks));
   if (!decoder) {
     LOG(ERROR) << "No decoder allocated";
     std::move(init_cb).Run(DecoderStatus::Codes::kFailedToCreateDecoder);
index e4210f5d750dd6733495fc47b34d709f768a6ea9..b89ad19f73afa397c7e82cf692b3a5068b2f50c7 100644 (file)
@@ -993,7 +993,6 @@ bool TTvdVideoDecoderImpl::AllocateDecoder() {
   // return that valid resolutions (e.g 3840x2176) are not supported on
   // several boards.
   auto latency = [&]() {
-    using LatencyMode = DecoderPromotion::LatencyMode;
     if (IsForGameStreaming())
       return LatencyMode::kGameMode;
     if (config_.is_rtc())
index cbad248c3218ba650e31637d5c428965daf882a2..bd1b741490855debebad0b8e6014543be17bf2c7 100644 (file)
@@ -384,7 +384,7 @@ int ResourceManager::GetCapableVideoCategoryId(
   return category;
 }
 
-bool ResourceManager::HasUDHVideoDecoder() {
+bool ResourceManager::HasUHDVideoDecoder() {
   // Our TVs doesn't support decoder hot-swap, so it is safe to cache this
   // value here, to avoid repetitive allocations of resource list.
   static const bool has_uhd_decoder =
index 5060674fe59ed67071e4cf5373458bc87e6d3664..222540009d636b128cbc886e581baf7e77551a6f 100644 (file)
@@ -159,7 +159,7 @@ class ResourceManager : public suspend_resume::SuspendResumeClient {
 
   // Checks if on the TV board there is physically present decoder capable
   // of decoding UHD (4K) content (aka DVDE).
-  virtual bool HasUDHVideoDecoder();
+  virtual bool HasUHDVideoDecoder();
 
   enum Decoder {
     kMinValue = 0,