File: fix-rk3588-v4l2-av1-decoder.patch

package info (click to toggle)
chromium 143.0.7499.169-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,786,920 kB
  • sloc: cpp: 35,784,218; ansic: 7,477,365; javascript: 3,962,116; python: 1,480,523; xml: 764,832; asm: 710,816; pascal: 188,028; sh: 88,717; perl: 88,692; objc: 79,984; sql: 57,625; cs: 42,265; fortran: 24,101; makefile: 22,509; tcl: 15,277; php: 14,018; yacc: 9,043; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,330; ada: 727; jsp: 228; sed: 36
file content (122 lines) | stat: -rw-r--r-- 5,300 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
From 0a4165c181d6b65e753be675d46aff79748d4526 Mon Sep 17 00:00:00 2001
From: Jianfeng Liu <liujianfeng1994@gmail.com>
Date: Mon, 1 Dec 2025 18:30:31 -0800
Subject: [PATCH] media/gpu/v4l2: Add AV1 |{width,height}_in_sbs_minus_1| to
 tile info

|{width,height}_in_sbs_minus_1| are necessary for verisilicon av1
decoder driver supported by mainline kernel since v6.5 for RK3588 SoC.

libgav1 doesn't have |tile_{column_width,row_height}_in_superblocks|
values when uniform_spacing is enabled, so we have to calculate the
values of |{width,height}_in_sbs_minus_1| from info of
|tile_{columns,rows}|.

Bug: 464638992
Change-Id: I65a84d8f7d1e2baa3d5fd479bec57d76e347d0c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7212655
Reviewed-by: Fritz Koenig <frkoenig@chromium.org>
Reviewed-by: Nathan Hebert <nhebert@chromium.org>
Commit-Queue: Fritz Koenig <frkoenig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1552534}
---
 .../v4l2/v4l2_video_decoder_delegate_av1.cc   | 72 +++++++++++++++----
 1 file changed, 58 insertions(+), 14 deletions(-)

diff --git a/media/gpu/v4l2/v4l2_video_decoder_delegate_av1.cc b/media/gpu/v4l2/v4l2_video_decoder_delegate_av1.cc
index 7ae87a31b62b86..08fc20b2542fba 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_delegate_av1.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_delegate_av1.cc
@@ -253,16 +253,22 @@ struct v4l2_av1_tile_info FillTileInfo(const libgav1::TileInfo& ti) {
         base::checked_cast<uint32_t>(ti.tile_row_start[i]);
   }
 
+  // Confirmed that |kMaxTileColumns| is enough size for
+  // |width_in_sbs_minus_1| and |kMaxTileRows| is enough size for
+  // |height_in_sbs_minus_1|
+  // https://b.corp.google.com/issues/187828854#comment19
+  static_assert(
+      std::size(decltype(v4l2_ti.width_in_sbs_minus_1){}) ==
+          libgav1::kMaxTileColumns,
+      "Size of |width_in_sbs_minus_1| array in |v4l2_av1_tile_info| struct "
+      "does not match libgav1 expectation");
+  static_assert(
+      std::size(decltype(v4l2_ti.height_in_sbs_minus_1){}) ==
+          libgav1::kMaxTileRows,
+      "Size of |height_in_sbs_minus_1| array in |v4l2_av1_tile_info| struct "
+      "does not match libgav1 expectation");
+
   if (!ti.uniform_spacing) {
-    // Confirmed that |kMaxTileColumns| is enough size for
-    // |width_in_sbs_minus_1| and |kMaxTileRows| is enough size for
-    // |height_in_sbs_minus_1|
-    // https://b.corp.google.com/issues/187828854#comment19
-    static_assert(
-        std::size(decltype(v4l2_ti.width_in_sbs_minus_1){}) ==
-            libgav1::kMaxTileColumns,
-        "Size of |width_in_sbs_minus_1| array in |v4l2_av1_tile_info| struct "
-        "does not match libgav1 expectation");
     for (size_t i = 0; i < libgav1::kMaxTileColumns; i++) {
       if (ti.tile_column_width_in_superblocks[i] >= 1) {
         v4l2_ti.width_in_sbs_minus_1[i] = base::checked_cast<uint32_t>(
@@ -270,17 +276,55 @@ struct v4l2_av1_tile_info FillTileInfo(const libgav1::TileInfo& ti) {
       }
     }
 
-    static_assert(
-        std::size(decltype(v4l2_ti.height_in_sbs_minus_1){}) ==
-            libgav1::kMaxTileRows,
-        "Size of |height_in_sbs_minus_1| array in |v4l2_av1_tile_info| struct "
-        "does not match libgav1 expectation");
     for (size_t i = 0; i < libgav1::kMaxTileRows; i++) {
       if (ti.tile_row_height_in_superblocks[i] >= 1) {
         v4l2_ti.height_in_sbs_minus_1[i] = base::checked_cast<uint32_t>(
             ti.tile_row_height_in_superblocks[i] - 1);
       }
     }
+  } else {
+    // libgav1 doesn't provide tile_column_width_in_superblocks and
+    // tile_row_height_in_superblocks values when uniform_spacing is set,
+    // so we have to calculate width and height of superblocks via
+    // other column/row info.
+    const uint32_t cols4x4 =
+        base::checked_cast<uint32_t>(ti.tile_column_start[ti.tile_columns]);
+    const uint32_t sb_cols = base::checked_cast<uint32_t>(ti.sb_columns);
+    const uint32_t sb_cols_64 = (cols4x4 + 15) >> 4;
+    const uint32_t sb_cols_128 = (cols4x4 + 31) >> 5;
+    uint32_t sb_shift = 0;
+    if (sb_cols_64 == sb_cols) {
+      sb_shift = 4;
+    } else {
+      DCHECK_EQ(sb_cols_128, sb_cols);
+      sb_shift = 5;
+    }
+
+    const uint32_t sb_size_mi = 1u << sb_shift;
+
+    for (size_t i = 0; i < static_cast<uint32_t>(ti.tile_columns); ++i) {
+      const uint32_t mi_start =
+          base::checked_cast<uint32_t>(ti.tile_column_start[i]);
+      const uint32_t mi_end =
+          base::checked_cast<uint32_t>(ti.tile_column_start[i + 1]);
+      const uint32_t mi_width = mi_end - mi_start;
+
+      const uint32_t sb_w = (mi_width + sb_size_mi - 1) >> sb_shift;
+      DCHECK_GE(sb_w, 1u);
+      v4l2_ti.width_in_sbs_minus_1[i] = sb_w - 1;
+    }
+
+    for (size_t i = 0; i < static_cast<uint32_t>(ti.tile_rows); ++i) {
+      const uint32_t mi_start =
+          base::checked_cast<uint32_t>(ti.tile_row_start[i]);
+      const uint32_t mi_end =
+          base::checked_cast<uint32_t>(ti.tile_row_start[i + 1]);
+      const uint32_t mi_height = mi_end - mi_start;
+
+      const uint32_t sb_h = (mi_height + sb_size_mi - 1) >> sb_shift;
+      DCHECK_GE(sb_h, 1u);
+      v4l2_ti.height_in_sbs_minus_1[i] = sb_h - 1;
+    }
   }
 
   v4l2_ti.tile_size_bytes = ti.tile_size_bytes;