[TTVD] Store selected video category capabilities 51/320551/5 submit/tizen/20241118.160014
authorJakub Gajownik <j.gajownik2@samsung.com>
Mon, 28 Oct 2024 09:28:16 +0000 (10:28 +0100)
committerBot Blink <blinkbot@samsung.com>
Mon, 18 Nov 2024 14:42:21 +0000 (14:42 +0000)
This patch adds information about capabilities of selected
video category (resolution, framerate, etc.) instead of
returning category only. They might differ from the
requested ones (support wider configurations) and might
be later used to improve decoder reselection mechanism.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-615
Change-Id: I6249e1690c2d45271a52be23b8b08c15e83578fb
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
media/filters/tizen/category_selector.cc
media/filters/tizen/category_selector.h
media/filters/tizen/decoder_promotion.cc
media/filters/tizen/decoder_promotion.h

index 0ce8e4d7220217ff7113ffc6f0c9700bff22f2a3..d5f2e96af80f72a5988c62c626f76f7b22a7b4e9 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "media/filters/tizen/category_selector.h"
 
+#include <ri-api.h>
+
 #include "base/bits.h"
 #include "media/base/tizen/logger/media_logger.h"
 #include "media/filters/tizen/resource_manager_utils.h"
@@ -201,6 +203,10 @@ absl::optional<float> GetMaximalFramerate(MediaVideoCodec codec,
   }
 }
 
+bool IsValidCategory(ri_rsc_category_e category) {
+  return category > 0;
+}
+
 ri_rsc_category_e FindDecoderForResolution(
     base::ResourceManager* manager,
     const char* codec_name,
@@ -368,20 +374,29 @@ absl::optional<uint32_t> DetectMaximalFramerate(MediaVideoCodec codec,
   }
 }
 
-ri_rsc_category_e SelectVideoDecoderCategory(
+absl::optional<CategorySelectionResult> SelectVideoDecoderCategory(
     base::ResourceManager* resource_manager,
     const VideoDecoderSelectionOpts& options) {
   const char* codec_name = VideoCodecToCodecName(options.codec);
   if (!codec_name) {
     TIZEN_MEDIA_LOG_NO_INSTANCE(ERROR)
         << "Unsupported codec: " << static_cast<uint32_t>(options.codec);
-    return RI_CATEGORY_NONE;
+    return absl::nullopt;
   }
 
   // MJPEG has different path in Resource Manager.
   if (options.codec == MediaVideoCodec::kCodecMJPEG) {
-    return static_cast<ri_rsc_category_e>(resource_manager->GetJpegCategoryId(
-        codec_name, options.coded_size.width()));
+    const auto category =
+        static_cast<ri_rsc_category_e>(resource_manager->GetJpegCategoryId(
+            codec_name, options.coded_size.width()));
+    if (!IsValidCategory(category)) {
+      return absl::nullopt;
+    }
+    return CategorySelectionResult{.category = category,
+                                   .coded_size = options.coded_size,
+                                   .framerate = kDefaultFramerate,
+                                   .sampling = options.sampling,
+                                   .bit_depth = options.bit_depth};
   }
 
   uint32_t framerate =
@@ -444,8 +459,12 @@ ri_rsc_category_e SelectVideoDecoderCategory(
         resource_manager, workaround_codec_name, options.bit_depth,
         workaround_coded_size, workaround_framerate,
         ConvertChromaSampling(options.sampling), prefer_texturing_support);
-    if (result > 0) {
-      return result;
+    if (IsValidCategory(result)) {
+      return CategorySelectionResult{.category = result,
+                                     .coded_size = workaround_coded_size,
+                                     .framerate = workaround_framerate,
+                                     .sampling = options.sampling,
+                                     .bit_depth = options.bit_depth};
     }
   }
 
@@ -455,7 +474,7 @@ ri_rsc_category_e SelectVideoDecoderCategory(
   // Note that for game streaming, we'll continue with original parameters
   // allocation.
   if (use_h264_level50_workaround == UseHigherDecoder::kRequired) {
-    return RI_CATEGORY_NONE;
+    return absl::nullopt;
   }
 
   // Try to allocate decoder using requested parameters, because either:
@@ -463,10 +482,18 @@ ri_rsc_category_e SelectVideoDecoderCategory(
   // - 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(
+  auto result = FindDecoderForResolution(
       resource_manager, codec_name, options.bit_depth, options.coded_size,
       framerate, ConvertChromaSampling(options.sampling),
       prefer_texturing_support);
+  if (!IsValidCategory(result)) {
+    return absl::nullopt;
+  }
+  return CategorySelectionResult{.category = result,
+                                 .coded_size = options.coded_size,
+                                 .framerate = framerate,
+                                 .sampling = options.sampling,
+                                 .bit_depth = options.bit_depth};
 }
 
 }  // namespace media
index eb929afba2ca0069a2da0b54eb1dcb30e4d09f8e..e5281cc5e4f4f261b76b3feada31b66eaedf2146 100644 (file)
@@ -5,8 +5,6 @@
 #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"
@@ -28,9 +26,17 @@ 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(
+struct CategorySelectionResult {
+  int category;
+  gfx::Size coded_size;
+  size_t framerate;
+  VideoChromaSampling sampling;
+  size_t bit_depth;
+};
+
+// Tries to select appropriate video decoder configuration to be used for
+// hardware accelerated decoding.
+absl::optional<CategorySelectionResult> SelectVideoDecoderCategory(
     base::ResourceManager* resource_manager,
     const VideoDecoderSelectionOpts& options);
 
index 04c9a9d06ab28c87ffca25a1a1fae4d9affb5620..904871d29c03b793f92b39254d4228d42c23c434 100644 (file)
@@ -149,7 +149,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::StandardAllocation(
     VideoCodecLevel level,
     gfx::Size coded_size,
     LatencyMode latency,
-    int category,
+    CategorySelectionResult selection_result,
     AllocationCallbacks callbacks) {
   // To avoid taking resources from this process, firstly check
   // whether there are:
@@ -195,7 +195,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::StandardAllocation(
     base::AutoReset allocation_state(&during_allocation_, true);
     base::AutoUnlock auto_lock(lock_);
     maybe_resource = resource_manager->AllocateResource(
-        category_id, category,
+        category_id, selection_result.category,
         base::BindRepeating(&DecoderPromotion::ResourceConflict,
                             base::Unretained(this), decoder_id));
   }
@@ -218,16 +218,11 @@ absl::optional<AllocatedDecoder> DecoderPromotion::StandardAllocation(
 
   maybe_resource->token.PassOwnership(std::move(holder));
 
-  uint32_t framerate = DetectMaximalFramerate(codec, level, coded_size)
-                           .value_or(kDefaultFramerate);
-
   Entry entry;
   entry.codec = codec;
-  entry.level = level;
   entry.coded_size = coded_size;
   entry.latency = latency;
-  entry.category = category;
-  entry.framerate = framerate;
+  entry.allocation = selection_result;
   entry.component_id = maybe_resource->device_id;
   entry.component_name = maybe_resource->component_name;
   entry.resource_manager = resource_manager;
@@ -239,11 +234,13 @@ absl::optional<AllocatedDecoder> DecoderPromotion::StandardAllocation(
   DecodingMode decoding_mode = DecodingMode::kDecodingNormal;
 
 #if TIZEN_VERSION_AT_LEAST(6, 5, 0)
-  if (category == RI_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P) {
+  if (selection_result.category == RI_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P) {
     decoding_mode = DecodingMode::kDecodingMultiH264_720p;
-  } else if (category == RM_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P) {
+  } else if (selection_result.category ==
+             RM_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P) {
     decoding_mode = DecodingMode::kDecodingMultiH264_1080p;
-  } else if (category == RM_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P) {
+  } else if (selection_result.category ==
+             RM_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P) {
     decoding_mode = DecodingMode::kDecodingMultiVP8_576p;
   }
 #endif
@@ -273,11 +270,10 @@ void DecoderPromotion::DumpAllocationStateLocked() {
     TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE) << "Decoder id:" << decoder.first;
     TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
         << " * " << decoder.second.component_name;
-    TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE) << " * " << decoder.second.category;
     TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
-        << " * " << decoder.second.coded_size.ToString();
+        << " * " << decoder.second.allocation.category;
     TIZEN_MEDIA_LOG_NO_INSTANCE(VERBOSE)
-        << " * " << decoder.second.framerate << " fps";
+        << " * " << decoder.second.coded_size.ToString();
   }
 }
 
@@ -312,7 +308,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
   }
 
   for (const auto& decoder : video_decoders_) {
-    if (CategoryIsNDecoding(decoder.second.category)) {
+    if (CategoryIsNDecoding(decoder.second.allocation.category)) {
       continue;
     }
 
@@ -324,10 +320,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
     // ndecoding configuration.
     if (decoder.second.coded_size.width() <= max_decoding_resolution.width() &&
         decoder.second.coded_size.height() <=
-            max_decoding_resolution.height() &&
-        DetectMaximalFramerate(decoder.second.codec, decoder.second.level,
-                               max_decoding_resolution)
-                .value_or(kDefaultFramerate) <= kMaxNDecodingFramerate) {
+            max_decoding_resolution.height()) {
       decoders_to_merge.push_back(decoder.first);
     }
   }
@@ -372,14 +365,21 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
     TIZEN_MEDIA_LOG(VERBOSE) << "Token obtained";
   }
 
+  CategorySelectionResult selection_result{
+      .category = category,
+      .coded_size = max_decoding_resolution,
+      .framerate = kDefaultFramerate,
+      .sampling = VideoChromaSampling::k420,
+      .bit_depth = 8};
+
   // Provide new resources for switching process and pass them to
   // holders that previously returned their resources.
   for (std::size_t i = 0; i < pairs.size(); ++i) {
     ID id = decoders_to_merge[i];
     TIZEN_MEDIA_LOG(INFO) << "Try switching decoder for decoder: " << id;
     auto new_decoder =
-        StandardAllocation(codec, level, coded_size, pairs[i].latency, category,
-                           pairs[i].callbacks);
+        StandardAllocation(codec, level, coded_size, pairs[i].latency,
+                           selection_result, pairs[i].callbacks);
     if (new_decoder) {
       pairs[i].callbacks.switch_cb.Run(std::move(new_decoder.value()));
     } else {
@@ -391,7 +391,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::TryMergeNDecoding(
   // original resource allocation request.
   TIZEN_MEDIA_LOG(VERBOSE) << "Try allocate new decoder for result";
   auto new_decoder = StandardAllocation(codec, level, coded_size, latency,
-                                        category, callbacks);
+                                        selection_result, callbacks);
   return new_decoder;
 }
 
@@ -408,7 +408,7 @@ absl::optional<AllocatedDecoder> DecoderPromotion::ExtendNDecoding(
 
   for (const auto& decoder : video_decoders_) {
     for (size_t i = 0; i < already_allocated.size(); ++i) {
-      if (decoder.second.category == kNDecodings[i].category) {
+      if (decoder.second.allocation.category == kNDecodings[i].category) {
         already_allocated[i]++;
       }
     }
@@ -417,8 +417,14 @@ absl::optional<AllocatedDecoder> DecoderPromotion::ExtendNDecoding(
   for (size_t i = 0; i < already_allocated.size(); ++i) {
     if (already_allocated[i] > 0 &&
         already_allocated[i] < kNDecodings[i].max_decoders) {
+      CategorySelectionResult selection_result{
+          .category = kNDecodings[i].category,
+          .coded_size = kNDecodings[i].max_resolution,
+          .framerate = kDefaultFramerate,
+          .sampling = VideoChromaSampling::k420,
+          .bit_depth = 8};
       auto opt_decoder = StandardAllocation(codec, level, coded_size, latency,
-                                            kNDecodings[i].category, callbacks);
+                                            selection_result, callbacks);
       if (opt_decoder) {
         return opt_decoder;
       }
@@ -462,14 +468,6 @@ absl::optional<AllocatedDecoder> DecoderPromotion::SelectDecoder(
 
   DumpAllocationStateLocked();
 
-  ri_rsc_category_e category_option =
-      SelectVideoDecoderCategory(GetResourceManager(), options);
-  if (category_option <= 0) {
-    TIZEN_MEDIA_LOG(ERROR) << "Failed on ri_get_capable_video_category_id: "
-                           << category_option;
-    return absl::nullopt;
-  }
-
   // Check if any ndecoding session is created and not all decoders are taken
   auto opt_decoder =
       ExtendNDecoding(options.codec, options.level, options.coded_size,
@@ -478,10 +476,17 @@ absl::optional<AllocatedDecoder> DecoderPromotion::SelectDecoder(
     return opt_decoder;
   }
 
+  auto maybe_selection_result =
+      SelectVideoDecoderCategory(GetResourceManager(), options);
+  if (!maybe_selection_result) {
+    TIZEN_MEDIA_LOG(ERROR) << "Selection video decoder category failed";
+    return absl::nullopt;
+  }
+
   // Try standard decoder allocation
   opt_decoder =
       StandardAllocation(options.codec, options.level, options.coded_size,
-                         options.latency, category_option, callbacks);
+                         options.latency, *maybe_selection_result, callbacks);
   if (opt_decoder) {
     return opt_decoder;
   }
@@ -512,8 +517,14 @@ bool DecoderPromotion::NeedsDecoderReselection(
       });
   TIZEN_MEDIA_LOG_ASSERT(decoder_it != video_decoders_.end())
       << "Decoder used for reselection has to be currently allocated";
-  auto new_category = SelectVideoDecoderCategory(GetResourceManager(), options);
-  return new_category != decoder_it->second.category;
+
+  auto maybe_selection_result =
+      SelectVideoDecoderCategory(GetResourceManager(), options);
+  if (!maybe_selection_result) {
+    return true;
+  }
+  return maybe_selection_result->category !=
+         decoder_it->second.allocation.category;
 }
 
 absl::optional<AllocatedDecoder> DecoderPromotion::SelectAudioDecoder(
index ab81014f58f606183830a33e72569f712a7b0df8..a18a64bbf39b6edd5620e929559f659014078a62 100644 (file)
@@ -16,6 +16,7 @@
 #include "base/tizen/resource_manager.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "media/base/video_types.h"
+#include "media/filters/tizen/category_selector.h"
 #include "media/filters/tizen/decoding_mode.h"
 #include "media/filters/tizen/latency_mode.h"
 #include "media/filters/tizen/media_video_codec.h"
@@ -149,7 +150,7 @@ class DecoderPromotion {
       VideoCodecLevel level,
       gfx::Size coded_size,
       LatencyMode latency,
-      int category,
+      CategorySelectionResult selection_result,
       AllocationCallbacks callbacks) EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   // Tries to allocate decoder instance, but might merge several
@@ -187,12 +188,15 @@ class DecoderPromotion {
   ~DecoderPromotion() = default;
 
   struct Entry {
+    // From original decoder allocation request.
     MediaVideoCodec codec;
-    VideoCodecLevel level;
     gfx::Size coded_size;
     LatencyMode latency;
-    uint32_t framerate;
-    int category;
+
+    // Values used for category selection and actual allocation, i.e
+    // capabilities of allocated resource.
+    CategorySelectionResult allocation;
+
     int component_id;
     std::string component_name;
     base::ResourceManager* resource_manager;