Skip to content

Commit b78dc72

Browse files
committed
av1: Fix uniform tile dimensions
Chromium, and possibly other clients, do not fill out the superblock dimensions arrays if the bitstream is set for uniform tile dimensions. Take a note from Mesa, and intel media driver, and go a step further: Calculate the rounded tile dimensions for most of the columns, then calculate the remainder for the last column. This finally fixes AV1 in Chromium and all Chrome derived browsers.
1 parent 09b69ab commit b78dc72

File tree

1 file changed

+57
-5
lines changed

1 file changed

+57
-5
lines changed

src/av1.c

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ static int get_relative_dist(CUVIDAV1PICPARAMS *pps, int ref_hint, int order_hin
1111
return (diff & (m - 1)) - (diff & m);
1212
}
1313

14+
static uint32_t CalcAv1TileLog2(uint32_t blockSize, uint32_t target)
15+
{
16+
uint32_t k;
17+
for (k = 0; (blockSize << k) < target; k++) {}
18+
return k;
19+
}
20+
1421
static void copyAV1PicParam(NVContext *ctx, NVBuffer* buffer, CUVIDPICPARAMS *picParams) {
1522
static const int bit_depth_map[] = {0, 2, 4}; //8-bpc, 10-bpc, 12-bpc
1623

@@ -209,11 +216,56 @@ static void copyAV1PicParam(NVContext *ctx, NVBuffer* buffer, CUVIDPICPARAMS *pi
209216
pps->cr_luma_mult = buf->film_grain_info.cr_luma_mult;
210217
pps->cr_offset = buf->film_grain_info.cr_offset;
211218

212-
for (int i = 0; i < pps->num_tile_cols; i++) {
213-
pps->tile_widths[i] = 1 + buf->width_in_sbs_minus_1[i];
214-
}
215-
for (int i = 0; i < pps->num_tile_rows; i++) {
216-
pps->tile_heights[i] = 1 + buf->height_in_sbs_minus_1[i];
219+
if (!buf->pic_info_fields.bits.uniform_tile_spacing_flag) {
220+
for (int i = 0; i < pps->num_tile_cols; i++) {
221+
pps->tile_widths[i] = 1 + buf->width_in_sbs_minus_1[i];
222+
}
223+
for (int i = 0; i < pps->num_tile_rows; i++) {
224+
pps->tile_heights[i] = 1 + buf->height_in_sbs_minus_1[i];
225+
}
226+
} else {
227+
// FUN!
228+
#define MOS_ALIGN_CEIL(_a, _alignment) (((_a) + ((_alignment)-1)) & (~((_alignment)-1)))
229+
uint32_t widthMinus1 = buf->frame_width_minus1;
230+
if (buf->pic_info_fields.bits.use_superres &&
231+
buf->superres_scale_denominator != 8) { // av1ScaleNumerator
232+
uint32_t dsWidth = ((widthMinus1 + 1) * 8 + buf->superres_scale_denominator / 2)
233+
/ buf->superres_scale_denominator;
234+
widthMinus1 = dsWidth - 1;
235+
}
236+
237+
const uint32_t maxMibSizeLog2 = 5;
238+
const uint32_t minMibSizeLog2 = 4;
239+
const uint32_t miSizeLog2 = 2;
240+
int32_t mibSizeLog2 = buf->seq_info_fields.fields.use_128x128_superblock ? maxMibSizeLog2 : minMibSizeLog2;
241+
int32_t miCols = MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(widthMinus1 + 1, 8) >> miSizeLog2, 1 << mibSizeLog2);
242+
int32_t miRows = MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(buf->frame_height_minus1 + 1, 8) >> miSizeLog2, 1 << mibSizeLog2);
243+
int32_t sbCols = miCols >> mibSizeLog2;
244+
int32_t sbRows = miRows >> mibSizeLog2;
245+
246+
uint32_t tileColsLog2 = CalcAv1TileLog2(1, pps->num_tile_cols);
247+
uint32_t tileRowsLog2 = CalcAv1TileLog2(1, pps->num_tile_rows);
248+
249+
uint32_t sizeSb = MOS_ALIGN_CEIL(sbCols, 1 << tileColsLog2);
250+
sizeSb >>= tileColsLog2;
251+
uint32_t sizeSbRemain = sbCols % sizeSb;
252+
if (!sizeSbRemain) sizeSbRemain = sizeSb;
253+
254+
int i;
255+
for (i = 0; i < pps->num_tile_cols - 1; i++) {
256+
pps->tile_widths[i] = sizeSb;
257+
}
258+
pps->tile_widths[i] = sizeSbRemain;
259+
260+
sizeSb = MOS_ALIGN_CEIL(sbRows, 1 << tileRowsLog2);
261+
sizeSb >>= tileRowsLog2;
262+
sizeSbRemain = sbRows % sizeSb;
263+
if (!sizeSbRemain) sizeSbRemain = sizeSb;
264+
265+
for (i = 0; i < pps->num_tile_rows - 1; i++) {
266+
pps->tile_heights[i] = sizeSb;
267+
}
268+
pps->tile_heights[i] = sizeSbRemain;
217269
}
218270

219271
for (int i = 0; i < (1<<pps->cdef_bits); i++) {

0 commit comments

Comments
 (0)