// SPDX-License-Identifier: GPL-2.0
/*
* Rockchip RK3288 VPU codec driver
*
* Copyright (c) 2014 Rockchip Electronics Co., Ltd.
* Hertz Wong <hertz.wong@rock-chips.com>
* Herman Chen <herman.chen@rock-chips.com>
*
* Copyright (C) 2014 Google, Inc.
* Tomasz Figa <tfiga@chromium.org>
*/
#include <linux/types.h>
#include <media/v4l2-h264.h>
#include <media/v4l2-mem2mem.h>
#include "hantro.h"
#include "hantro_hw.h"
/* Size with u32 units. */
#define CABAC_INIT_BUFFER_SIZE (
460 *
2 )
#define POC_BUFFER_SIZE
34
#define SCALING_LIST_SIZE (
6 *
16 +
2 *
64 )
/*
* For valid and long term reference marking, index are reversed, so bit 31
* indicates the status of the picture 0.
*/
#define REF_BIT(i) BIT(
32 -
1 - (i))
/* Data structure describing auxiliary buffer format. */
struct hantro_h264_dec_priv_tbl {
u32 cabac_table[CABAC_INIT_BUFFER_SIZE];
u32 poc[POC_BUFFER_SIZE];
u8 scaling_list[SCALING_LIST_SIZE];
};
/*
* Constant CABAC table.
* From drivers/media/platform/rk3288-vpu/rk3288_vpu_hw_h264d.c
* in https://chromium.googlesource.com/chromiumos/third_party/kernel,
* chromeos-3.14 branch.
*/
static const u32 h264_cabac_table[] = {
0 x14f10236,
0 x034a14f1,
0 x0236034a,
0 xe47fe968,
0 xfa35ff36,
0 x07330000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x00000000,
0 x0029003f,
0 x003f003f,
0 xf7530456,
0 x0061f948,
0 x0d29033e,
0 x000b0137,
0 x0045ef7f,
0 xf3660052,
0 xf94aeb6b,
0 xe57fe17f,
0 xe87fee5f,
0 xe57feb72,
0 xe27fef7b,
0 xf473f07a,
0 xf573f43f,
0 xfe44f154,
0 xf368fd46,
0 xf85df65a,
0 xe27fff4a,
0 xfa61f95b,
0 xec7ffc38,
0 xfb52f94c,
0 xea7df95d,
0 xf557fd4d,
0 xfb47fc3f,
0 xfc44f454,
0 xf93ef941,
0 x083d0538,
0 xfe420140,
0 x003dfe4e,
0 x01320734,
0 x0a23002c,
0 x0b26012d,
0 x002e052c,
0 x1f110133,
0 x07321c13,
0 x10210e3e,
0 xf36cf164,
0 xf365f35b,
0 xf45ef658,
0 xf054f656,
0 xf953f357,
0 xed5e0146,
0 x0048fb4a,
0 x123bf866,
0 xf164005f,
0 xfc4b0248,
0 xf54bfd47,
0 x0f2ef345,
0 x003e0041,
0 x1525f148,
0 x09391036,
0 x003e0c48,
0 x18000f09,
0 x08190d12,
0 x0f090d13,
0 x0a250c12,
0 x061d1421,
0 x0f1e042d,
0 x013a003e,
0 x073d0c26,
0 x0b2d0f27,
0 x0b2a0d2c,
0 x102d0c29,
0 x0a311e22,
0 x122a0a37,
0 x1133112e,
0 x00591aed,
0 x16ef1aef,
0 x1ee71cec,
0 x21e925e5,
0 x21e928e4,
0 x26ef21f5,
0 x28f129fa,
0 x26012911,
0 x1efa1b03,
0 x1a1625f0,
0 x23fc26f8,
0 x26fd2503,
0 x26052a00,
0 x23102716,
0 x0e301b25,
0 x153c0c44,
0 x0261fd47,
0 xfa2afb32,
0 xfd36fe3e,
0 x003a013f,
0 xfe48ff4a,
0 xf75bfb43,
0 xfb1bfd27,
0 xfe2c002e,
0 xf040f844,
0 xf64efa4d,
0 xf656f45c,
0 xf137f63c,
0 xfa3efc41,
0 xf449f84c,
0 xf950f758,
0 xef6ef561,
0 xec54f54f,
0 xfa49fc4a,
0 xf356f360,
0 xf561ed75,
0 xf84efb21,
0 xfc30fe35,
0 xfd3ef347,
0 xf64ff456,
0 xf35af261,
0 x0000fa5d,
0 xfa54f84f,
0 x0042ff47,
0 x003efe3c,
0 xfe3bfb4b,
0 xfd3efc3a,
0 xf742ff4f,
0 x00470344,
0 x0a2cf93e,
0 x0f240e28,
0 x101b0c1d,
0 x012c1424,
0 x1220052a,
0 x01300a3e,
0 x112e0940,
0 xf468f561,
0 xf060f958,
0 xf855f955,
0 xf755f358,
0 x0442fd4d,
0 xfd4cfa4c,
0 x0a3aff4c,
0 xff53f963,
0 xf25f025f,
0 x004cfb4a,
0 x0046f54b,
0 x01440041,
0 xf249033e,
0 x043eff44,
0 xf34b0b37,
0 x05400c46,
0 x0f060613,
0 x07100c0e,
0 x120d0d0b,
0 x0d0f0f10,
0 x0c170d17,
0 x0f140e1a,
0 x0e2c1128,
0 x112f1811,
0 x15151916,
0 x1f1b161d,
0 x13230e32,
0 x0a39073f,
0 xfe4dfc52,
0 xfd5e0945,
0 xf46d24dd,
0 x24de20e6,
0 x25e22ce0,
0 x22ee22f1,
0 x28f121f9,
0 x23fb2100,
0 x2602210d,
0 x17230d3a,
0 x1dfd1a00,
0 x161e1ff9,
0 x23f122fd,
0 x220324ff,
0 x2205200b,
0 x2305220c,
0 x270b1e1d,
0 x221a1d27,
0 x13421f15,
0 x1f1f1932,
0 xef78ec70,
0 xee72f555,
0 xf15cf259,
0 xe647f151,
0 xf2500044,
0 xf246e838,
0 xe944e832,
0 xf54a17f3,
0 x1af328f1,
0 x31f22c03,
0 x2d062c22,
0 x21361352,
0 xfd4bff17,
0 x0122012b,
0 x0036fe37,
0 x003d0140,
0 x0044f75c,
0 xf26af361,
0 xf15af45a,
0 xee58f649,
0 xf74ff256,
0 xf649f646,
0 xf645fb42,
0 xf740fb3a,
0 x023b15f6,
0 x18f51cf8,
0 x1cff1d03,
0 x1d092314,
0 x1d240e43,
0 x14f10236,
0 x034a14f1,
0 x0236034a,
0 xe47fe968,
0 xfa35ff36,
0 x07331721,
0 x17021500,
0 x01090031,
0 xdb760539,
0 xf34ef541,
0 x013e0c31,
0 xfc491132,
0 x1240092b,
0 x1d001a43,
0 x105a0968,
0 xd27fec68,
0 x0143f34e,
0 xf541013e,
0 xfa56ef5f,
0 xfa3d092d,
0 xfd45fa51,
0 xf5600637,
0 x0743fb56,
0 x0258003a,
0 xfd4cf65e,
0 x05360445,
0 xfd510058,
0 xf943fb4a,
0 xfc4afb50,
0 xf948013a,
0 x0029003f,
0 x003f003f,
0 xf7530456,
0 x0061f948,
0 x0d29033e,
0 x002dfc4e,
0 xfd60e57e,
0 xe462e765,
0 xe943e452,
0 xec5ef053,
0 xea6eeb5b,
0 xee66f35d,
0 xe37ff95c,
0 xfb59f960,
0 xf36cfd2e,
0 xff41ff39,
0 xf75dfd4a,
0 xf75cf857,
0 xe97e0536,
0 x063c063b,
0 x0645ff30,
0 x0044fc45,
0 xf858fe55,
0 xfa4eff4b,
0 xf94d0236,
0 x0532fd44,
0 x0132062a,
0 xfc51013f,
0 xfc460043,
0 x0239fe4c,
0 x0b230440,
0 x013d0b23,
0 x12190c18,
0 x0d1d0d24,
0 xf65df949,
0 xfe490d2e,
0 x0931f964,
0 x09350235,
0 x0535fe3d,
0 x00380038,
0 xf33ffb3c,
0 xff3e0439,
0 xfa450439,
0 x0e270433,
0 x0d440340,
0 x013d093f,
0 x07321027,
0 x052c0434,
0 x0b30fb3c,
0 xff3b003b,
0 x1621052c,
0 x0e2bff4e,
0 x003c0945,
0 x0b1c0228,
0 x032c0031,
0 x002e022c,
0 x0233002f,
0 x0427023e,
0 x062e0036,
0 x0336023a,
0 x043f0633,
0 x06390735,
0 x06340637,
0 x0b2d0e24,
0 x0835ff52,
0 x0737fd4e,
0 x0f2e161f,
0 xff541907,
0 x1ef91c03,
0 x1c042000,
0 x22ff1e06,
0 x1e062009,
0 x1f131a1b,
0 x1a1e2514,
0 x1c221146,
0 x0143053b,
0 x0943101e,
0 x12201223,
0 x161d181f,
0 x1726122b,
0 x14290b3f,
0 x093b0940,
0 xff5efe59,
0 xf76cfa4c,
0 xfe2c002d,
0 x0034fd40,
0 xfe3bfc46,
0 xfc4bf852,
0 xef66f74d,
0 x0318002a,
0 x00300037,
0 xfa3bf947,
0 xf453f557,
0 xe277013a,
0 xfd1dff24,
0 x0126022b,
0 xfa37003a,
0 x0040fd4a,
0 xf65a0046,
0 xfc1d051f,
0 x072a013b,
0 xfe3afd48,
0 xfd51f561,
0 x003a0805,
0 x0a0e0e12,
0 x0d1b0228,
0 x003afd46,
0 xfa4ff855,
0 x0000f36a,
0 xf06af657,
0 xeb72ee6e,
0 xf262ea6e,
0 xeb6aee67,
0 xeb6be96c,
0 xe670f660,
0 xf45ffb5b,
0 xf75dea5e,
0 xfb560943,
0 xfc50f655,
0 xff46073c,
0 x093a053d,
0 x0c320f32,
0 x12311136,
0 x0a29072e,
0 xff330731,
0 x08340929,
0 x062f0237,
0 x0d290a2c,
0 x06320535,
0 x0d31043f,
0 x0640fe45,
0 xfe3b0646,
0 x0a2c091f,
0 x0c2b0335,
0 x0e220a26,
0 xfd340d28,
0 x1120072c,
0 x07260d32,
0 x0a391a2b,
0 x0e0b0b0e,
0 x090b120b,
0 x150917fe,
0 x20f120f1,
0 x22eb27e9,
0 x2adf29e1,
0 x2ee426f4,
0 x151d2de8,
0 x35d330e6,
0 x41d52bed,
0 x27f61e09,
0 x121a141b,
0 x0039f252,
0 xfb4bed61,
0 xdd7d1b00,
0 x1c001ffc,
0 x1b062208,
0 x1e0a1816,
0 x21131620,
0 x1a1f1529,
0 x1a2c172f,
0 x10410e47,
0 x083c063f,
0 x11411518,
0 x17141a17,
0 x1b201c17,
0 x1c181728,
0 x18201c1d,
0 x172a1339,
0 x1635163d,
0 x0b560c28,
0 x0b330e3b,
0 xfc4ff947,
0 xfb45f746,
0 xf842f644,
0 xed49f445,
0 xf046f143,
0 xec3eed46,
0 xf042ea41,
0 xec3f09fe,
0 x1af721f7,
0 x27f929fe,
0 x2d033109,
0 x2d1b243b,
0 xfa42f923,
0 xf92af82d,
0 xfb30f438,
0 xfa3cfb3e,
0 xf842f84c,
0 xfb55fa51,
0 xf64df951,
0 xef50ee49,
0 xfc4af653,
0 xf747f743,
0 xff3df842,
0 xf242003b,
0 x023b15f3,
0 x21f227f9,
0 x2efe3302,
0 x3c063d11,
0 x37222a3e,
0 x14f10236,
0 x034a14f1,
0 x0236034a,
0 xe47fe968,
0 xfa35ff36,
0 x07331619,
0 x22001000,
0 xfe090429,
0 xe3760241,
0 xfa47f34f,
0 x05340932,
0 xfd460a36,
0 x1a221316,
0 x28003902,
0 x29241a45,
0 xd37ff165,
0 xfc4cfa47,
0 xf34f0534,
0 x0645f35a,
0 x0034082b,
0 xfe45fb52,
0 xf660023b,
0 x024bfd57,
0 xfd640138,
0 xfd4afa55,
0 x003bfd51,
0 xf956fb5f,
0 xff42ff4d,
0 x0146fe56,
0 xfb48003d,
0 x0029003f,
0 x003f003f,
0 xf7530456,
0 x0061f948,
0 x0d29033e,
0 x0d0f0733,
0 x0250d97f,
0 xee5bef60,
0 xe651dd62,
0 xe866e961,
0 xe577e863,
0 xeb6eee66,
0 xdc7f0050,
0 xfb59f95e,
0 xfc5c0027,
0 x0041f154,
0 xdd7ffe49,
0 xf468f75b,
0 xe17f0337,
0 x07380737,
0 x083dfd35,
0 x0044f94a,
0 xf758f367,
0 xf35bf759,
0 xf25cf84c,
0 xf457e96e,
0 xe869f64e,
0 xec70ef63,
0 xb27fba7f,
0 xce7fd27f,
0 xfc42fb4e,
0 xfc47f848,
0 x023bff37,
0 xf946fa4b,
0 xf859de77,
0 xfd4b2014,
0 x1e16d47f,
0 x0036fb3d,
0 x003aff3c,
0 xfd3df843,
0 xe754f24a,
0 xfb410534,
0 x0239003d,
0 xf745f546,
0 x1237fc47,
0 x003a073d,
0 x09291219,
0 x0920052b,
0 x092f002c,
0 x0033022e,
0 x1326fc42,
0 x0f260c2a,
0 x09220059,
0 x042d0a1c,
0 x0a1f21f5,
0 x34d5120f,
0 x1c0023ea,
0 x26e72200,
0 x27ee20f4,
0 x66a20000,
0 x38f121fc,
0 x1d0a25fb,
0 x33e327f7,
0 x34de45c6,
0 x43c12cfb,
0 x200737e3,
0 x20010000,
0 x1b2421e7,
0 x22e224e4,
0 x26e426e5,
0 x22ee23f0,
0 x22f220f8,
0 x25fa2300,
0 x1e0a1c12,
0 x1a191d29,
0 x004b0248,
0 x084d0e23,
0 x121f1123,
0 x151e112d,
0 x142a122d,
0 x1b1a1036,
0 x07421038,
0 x0b490a43,
0 xf674e970,
0 xf147f93d,
0 x0035fb42,
0 xf54df750,
0 xf754f657,
0 xde7feb65,
0 xfd27fb35,
0 xf93df54b,
0 xf14def5b,
0 xe76be76f,
0 xe47af54c,
0 xf62cf634,
0 xf639f73a,
0 xf048f945,
0 xfc45fb4a,
0 xf7560242,
0 xf7220120,
0 x0b1f0534,
0 xfe37fe43,
0 x0049f859,
0 x03340704,
0 x0a081108,
0 x10130325,
0 xff3dfb49,
0 xff46fc4e,
0 x0000eb7e,
0 xe97cec6e,
0 xe67ee77c,
0 xef69e579,
0 xe575ef66,
0 xe675e574,
0 xdf7af65f,
0 xf264f85f,
0 xef6fe472,
0 xfa59fe50,
0 xfc52f755,
0 xf851ff48,
0 x05400143,
0 x09380045,
0 x01450745,
0 xf945fa43,
0 xf04dfe40,
0 x023dfa43,
0 xfd400239,
0 xfd41fd42,
0 x003e0933,
0 xff42fe47,
0 xfe4bff46,
0 xf7480e3c,
0 x1025002f,
0 x12230b25,
0 x0c290a29,
0 x02300c29,
0 x0d29003b,
0 x03321328,
0 x03421232,
0 x13fa12fa,
0 x0e001af4,
0 x1ff021e7,
0 x21ea25e4,
0 x27e22ae2,
0 x2fd62ddc,
0 x31de29ef,
0 x200945b9,
0 x3fc142c0,
0 x4db636d9,
0 x34dd29f6,
0 x240028ff,
0 x1e0e1c1a,
0 x17250c37,
0 x0b4125df,
0 x27dc28db,
0 x26e22edf,
0 x2ae228e8,
0 x31e326f4,
0 x28f626fd,
0 x2efb1f14,
0 x1d1e192c,
0 x0c300b31,
0 x1a2d1616,
0 x17161b15,
0 x21141a1c,
0 x1e181b22,
0 x122a1927,
0 x12320c46,
0 x15360e47,
0 x0b531920,
0 x15311536,
0 xfb55fa51,
0 xf64df951,
0 xef50ee49,
0 xfc4af653,
0 xf747f743,
0 xff3df842,
0 xf242003b,
0 x023b11f6,
0 x20f32af7,
0 x31fb3500,
0 x4003440a,
0 x421b2f39,
0 xfb470018,
0 xff24fe2a,
0 xfe34f739,
0 xfa3ffc41,
0 xfc43f952,
0 xfd51fd4c,
0 xf948fa4e,
0 xf448f244,
0 xfd46fa4c,
0 xfb42fb3e,
0 x0039fc3d,
0 xf73c0136,
0 x023a11f6,
0 x20f32af7,
0 x31fb3500,
0 x4003440a,
0 x421b2f39,
0 x14f10236,
0 x034a14f1,
0 x0236034a,
0 xe47fe968,
0 xfa35ff36,
0 x07331d10,
0 x19000e00,
0 xf633fd3e,
0 xe5631a10,
0 xfc55e866,
0 x05390639,
0 xef490e39,
0 x1428140a,
0 x1d003600,
0 x252a0c61,
0 xe07fea75,
0 xfe4afc55,
0 xe8660539,
0 xfa5df258,
0 xfa2c0437,
0 xf559f167,
0 xeb741339,
0 x143a0454,
0 x0660013f,
0 xfb55f36a,
0 x053f064b,
0 xfd5aff65,
0 x0337fc4f,
0 xfe4bf461,
0 xf932013c,
0 x0029003f,
0 x003f003f,
0 xf7530456,
0 x0061f948,
0 x0d29033e,
0 x0722f758,
0 xec7fdc7f,
0 xef5bf25f,
0 xe754e756,
0 xf459ef5b,
0 xe17ff24c,
0 xee67f35a,
0 xdb7f0b50,
0 x054c0254,
0 x054efa37,
0 x043df253,
0 xdb7ffb4f,
0 xf568f55b,
0 xe27f0041,
0 xfe4f0048,
0 xfc5cfa38,
0 x0344f847,
0 xf362fc56,
0 xf458fb52,
0 xfd48fc43,
0 xf848f059,
0 xf745ff3b,
0 x05420439,
0 xfc47fe47,
0 x023aff4a,
0 xfc2cff45,
0 x003ef933,
0 xfc2ffa2a,
0 xfd29fa35,
0 x084cf74e,
0 xf5530934,
0 x0043fb5a,
0 x0143f148,
0 xfb4bf850,
0 xeb53eb40,
0 xf31fe740,
0 xe35e094b,
0 x113ff84a,
0 xfb23fe1b,
0 x0d5b0341,
0 xf945084d,
0 xf642033e,
0 xfd44ec51,
0 x001e0107,
0 xfd17eb4a,
0 x1042e97c,
0 x11252cee,
0 x32deea7f,
0 x0427002a,
0 x07220b1d,
0 x081f0625,
0 x072a0328,
0 x08210d2b,
0 x0d24042f,
0 x0337023a,
0 x063c082c,
0 x0b2c0e2a,
0 x07300438,
0 x04340d25,
0 x0931133a,
0 x0a300c2d,
0 x00451421,
0 x083f23ee,
0 x21e71cfd,
0 x180a1b00,
0 x22f234d4,
0 x27e81311,
0 x1f19241d,
0 x1821220f,
0 x1e141649,
0 x1422131f,
0 x1b2c1310,
0 x0f240f24,
0 x151c1915,
0 x1e141f0c,
0 x1b10182a,
0 x005d0e38,
0 x0f391a26,
0 xe87fe873,
0 xea52f73e,
0 x0035003b,
0 xf255f359,
0 xf35ef55c,
0 xe37feb64,
0 xf239f443,
0 xf547f64d,
0 xeb55f058,
0 xe968f162,
0 xdb7ff652,
0 xf830f83d,
0 xf842f946,
0 xf24bf64f,
0 xf753f45c,
0 xee6cfc4f,
0 xea45f04b,
0 xfe3a013a,
0 xf34ef753,
0 xfc51f363,
0 xf351fa26,
0 xf33efa3a,
0 xfe3bf049,
0 xf64cf356,
0 xf753f657,
0 x0000ea7f,
0 xe77fe778,
0 xe57fed72,
0 xe975e776,
0 xe675e871,
0 xe476e178,
0 xdb7cf65e,
0 xf166f663,
0 xf36ace7f,
0 xfb5c1139,
0 xfb56f35e,
0 xf45bfe4d,
0 x0047ff49,
0 x0440f951,
0 x05400f39,
0 x01430044,
0 xf6430144,
0 x004d0240,
0 x0044fb4e,
0 x0737053b,
0 x02410e36,
0 x0f2c053c,
0 x0246fe4c,
0 xee560c46,
0 x0540f446,
0 x0b370538,
0 x00450241,
0 xfa4a0536,
0 x0736fa4c,
0 xf552fe4d,
0 xfe4d192a,
0 x11f310f7,
0 x11f41beb,
0 x25e229d8,
0 x2ad730d1,
0 x27e02ed8,
0 x34cd2ed7,
0 x34d92bed,
0 x200b3dc9,
0 x38d23ece,
0 x51bd2dec,
0 x23fe1c0f,
0 x22012701,
0 x1e111426,
0 x122d0f36,
0 x004f24f0,
0 x25f225ef,
0 x2001220f,
0 x1d0f1819,
0 x22161f10,
0 x23121f1c,
0 x2129241c,
0 x1b2f153e,
0 x121f131a,
0 x24181817,
0 x1b10181e,
0 x1f1d1629,
0 x162a103c,
0 x0f340e3c,
0 x034ef07b,
0 x15351638,
0 x193d1521,
0 x1332113d,
0 xfd4ef84a,
0 xf748f648,
0 xee4bf447,
0 xf53ffb46,
0 xef4bf248,
0 xf043f835,
0 xf23bf734,
0 xf54409fe,
0 x1ef61ffc,
0 x21ff2107,
0 x1f0c2517,
0 x1f261440,
0 xf747f925,
0 xf82cf531,
0 xf638f43b,
0 xf83ff743,
0 xfa44f64f,
0 xfd4ef84a,
0 xf748f648,
0 xee4bf447,
0 xf53ffb46,
0 xef4bf248,
0 xf043f835,
0 xf23bf734,
0 xf54409fe,
0 x1ef61ffc,
0 x21ff2107,
0 x1f0c2517,
0 x1f261440
};
static void
assemble_scaling_list(
struct hantro_ctx *ctx)
{
const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
const struct v4l2_ctrl_h264_scaling_matrix *scaling = ctrls->scaling;
const struct v4l2_ctrl_h264_pps *pps = ctrls->pps;
const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4);
const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[
0 ]);
const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[
0 ]);
struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
u32 *dst = (u32 *)tbl->scaling_list;
const u32 *src;
int i, j;
if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
return ;
for (i =
0 ; i < num_list_4x4; i++) {
src = (u32 *)&scaling->scaling_list_4x4[i];
for (j =
0 ; j < list_len_4x4 /
4 ; j++)
*dst++ = swab32(src[j]);
}
/* Only Intra/Inter Y lists */
for (i =
0 ; i <
2 ; i++) {
src = (u32 *)&scaling->scaling_list_8x8[i];
for (j =
0 ; j < list_len_8x8 /
4 ; j++)
*dst++ = swab32(src[j]);
}
}
static void prepare_table(
struct hantro_ctx *ctx)
{
const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
const struct v4l2_ctrl_h264_sps *sps = ctrls->sps;
struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
u32 dpb_longterm =
0 ;
u32 dpb_valid =
0 ;
int i;
for (i =
0 ; i < HANTRO_H264_DPB_SIZE; ++i) {
tbl->poc[i *
2 ] = dpb[i].top_field_order_cnt;
tbl->poc[i *
2 +
1 ] = dpb[i].bottom_field_order_cnt;
if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
continue ;
/*
* Set up bit maps of valid and long term DPBs.
* NOTE: The bits are reversed, i.e. MSb is DPB 0. For frame
* decoding, bit 31 to 15 are used, while for field decoding,
* all bits are used, with bit 31 being a top field, 30 a bottom
* field and so on.
*/
if (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) {
if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF)
dpb_valid |= REF_BIT(i *
2 );
if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)
dpb_valid |= REF_BIT(i *
2 +
1 );
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) {
dpb_longterm |= REF_BIT(i *
2 );
dpb_longterm |= REF_BIT(i *
2 +
1 );
}
}
else {
dpb_valid |= REF_BIT(i);
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
dpb_longterm |= REF_BIT(i);
}
}
ctx->h264_dec.dpb_valid = dpb_valid;
ctx->h264_dec.dpb_longterm = dpb_longterm;
if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) ||
!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) {
tbl->poc[
32 ] = ctx->h264_dec.cur_poc;
tbl->poc[
33 ] =
0 ;
}
else {
tbl->poc[
32 ] = dec_param->top_field_order_cnt;
tbl->poc[
33 ] = dec_param->bottom_field_order_cnt;
}
assemble_scaling_list(ctx);
}
static bool dpb_entry_match(
const struct v4l2_h264_dpb_entry *a,
const struct v4l2_h264_dpb_entry *b)
{
return a->reference_ts == b->reference_ts;
}
static void update_dpb(
struct hantro_ctx *ctx)
{
const struct v4l2_ctrl_h264_decode_params *dec_param;
DECLARE_BITMAP(
new , ARRAY_SIZE(dec_param->dpb)) = {
0 , };
DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = {
0 , };
unsigned int i, j;
dec_param = ctx->h264_dec.ctrls.decode;
/* Disable all entries by default. */
for (i =
0 ; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
ctx->h264_dec.dpb[i].flags =
0 ;
/* Try to match new DPB entries with existing ones by their POCs. */
for (i =
0 ; i < ARRAY_SIZE(dec_param->dpb); i++) {
const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
continue ;
/*
* To cut off some comparisons, iterate only on target DPB
* entries which are not used yet.
*/
for_each_clear_bit(j, used, ARRAY_SIZE(ctx->h264_dec.dpb)) {
struct v4l2_h264_dpb_entry *cdpb;
cdpb = &ctx->h264_dec.dpb[j];
if (!dpb_entry_match(cdpb, ndpb))
continue ;
*cdpb = *ndpb;
__set_bit(j, used);
break ;
}
if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
__set_bit(i,
new );
}
/* For entries that could not be matched, use remaining free slots. */
for_each_set_bit(i,
new , ARRAY_SIZE(dec_param->dpb)) {
const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
struct v4l2_h264_dpb_entry *cdpb;
/*
* Both arrays are of the same sizes, so there is no way
* we can end up with no space in target array, unless
* something is buggy.
*/
j = find_first_zero_bit(used, ARRAY_SIZE(ctx->h264_dec.dpb));
if (WARN_ON(j >= ARRAY_SIZE(ctx->h264_dec.dpb)))
return ;
cdpb = &ctx->h264_dec.dpb[j];
*cdpb = *ndpb;
__set_bit(j, used);
}
}
dma_addr_t hantro_h264_get_ref_buf(
struct hantro_ctx *ctx,
unsigned int dpb_idx)
{
struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
dma_addr_t dma_addr =
0 ;
s32 cur_poc = ctx->h264_dec.cur_poc;
u32 flags;
if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts);
if (!dma_addr) {
struct vb2_v4l2_buffer *dst_buf;
struct vb2_buffer *buf;
/*
* If a DPB entry is unused or invalid, address of current
* destination buffer is returned.
*/
dst_buf = hantro_get_dst_buf(ctx);
buf = &dst_buf->vb2_buf;
dma_addr = hantro_get_dec_buf_addr(ctx, buf);
}
flags = dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD ?
0 x2 :
0 ;
flags |= abs(dpb[dpb_idx].top_field_order_cnt - cur_poc) <
abs(dpb[dpb_idx].bottom_field_order_cnt - cur_poc) ?
0 x1 :
0 ;
return dma_addr | flags;
}
u16 hantro_h264_get_ref_nbr(
struct hantro_ctx *ctx,
unsigned int dpb_idx)
{
const struct v4l2_h264_dpb_entry *dpb = &ctx->h264_dec.dpb[dpb_idx];
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
return 0 ;
return dpb->frame_num;
}
/*
* Removes all references with the same parity as the current picture from the
* reference list. The remaining list will have references with the opposite
* parity. This is effectively a deduplication of references since each buffer
* stores two fields. For this reason, each buffer is found twice in the
* reference list.
*
* This technique has been chosen through trial and error. This simple approach
* resulted in the highest conformance score. Note that this method may suffer
* worse quality in the case an opposite reference frame has been lost. If this
* becomes a problem in the future, it should be possible to add a preprocessing
* to identify un-paired fields and avoid removing them.
*/
static void deduplicate_reflist(
struct v4l2_h264_reflist_builder *b,
struct v4l2_h264_reference *reflist)
{
int write_idx =
0 ;
int i;
if (b->cur_pic_fields == V4L2_H264_FRAME_REF) {
write_idx = b->num_valid;
goto done;
}
for (i =
0 ; i < b->num_valid; i++) {
if (!(b->cur_pic_fields == reflist[i].fields)) {
reflist[write_idx++] = reflist[i];
continue ;
}
}
done:
/* Should not happen unless we have a bug in the reflist builder. */
if (WARN_ON(write_idx >
16 ))
write_idx =
16 ;
/* Clear the remaining, some streams fails otherwise */
for (; write_idx <
16 ; write_idx++)
reflist[write_idx].index =
15 ;
}
int hantro_h264_dec_prepare_run(
struct hantro_ctx *ctx)
{
struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec;
struct hantro_h264_dec_ctrls *ctrls = &h264_ctx->ctrls;
struct v4l2_h264_reflist_builder reflist_builder;
hantro_start_prepare_run(ctx);
ctrls->scaling =
hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
if (WARN_ON(!ctrls->scaling))
return -EINVAL;
ctrls->decode =
hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
if (WARN_ON(!ctrls->decode))
return -EINVAL;
ctrls->sps =
hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_SPS);
if (WARN_ON(!ctrls->sps))
return -EINVAL;
ctrls->pps =
hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_PPS);
if (WARN_ON(!ctrls->pps))
return -EINVAL;
/* Update the DPB with new refs. */
update_dpb(ctx);
/* Build the P/B{0,1} ref lists. */
v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode,
ctrls->sps, ctx->h264_dec.dpb);
h264_ctx->cur_poc = reflist_builder.cur_pic_order_count;
/* Prepare data in memory. */
prepare_table(ctx);
v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
h264_ctx->reflists.b1);
/*
* Reduce ref lists to at most 16 entries, Hantro hardware will deduce
* the actual picture lists in field through the dpb_valid,
* dpb_longterm bitmap along with the current frame parity.
*/
if (reflist_builder.cur_pic_fields != V4L2_H264_FRAME_REF) {
deduplicate_reflist(&reflist_builder, h264_ctx->reflists.p);
deduplicate_reflist(&reflist_builder, h264_ctx->reflists.b0);
deduplicate_reflist(&reflist_builder, h264_ctx->reflists.b1);
}
return 0 ;
}
void hantro_h264_dec_exit(
struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
struct hantro_aux_buf *priv = &h264_dec->priv;
dma_free_coherent(vpu->dev, priv->size, priv->cpu, priv->dma);
}
int hantro_h264_dec_init(
struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
struct hantro_aux_buf *priv = &h264_dec->priv;
struct hantro_h264_dec_priv_tbl *tbl;
priv->cpu = dma_alloc_coherent(vpu->dev,
sizeof (*tbl), &priv->dma,
GFP_KERNEL);
if (!priv->cpu)
return -ENOMEM;
priv->size =
sizeof (*tbl);
tbl = priv->cpu;
memcpy(tbl->cabac_table, h264_cabac_table,
sizeof (tbl->cabac_table));
return 0 ;
}
Messung V0.5 in Prozent C=94 H=86 G=89
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-04)
¤
*© Formatika GbR, Deutschland