Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  reconintra_neon_i8mm.c

  Sprache: C
 

/*
 * Copyright (c) 2025, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */


#include <arm_neon.h>
#include <assert.h>

#include "config/aom_config.h"
#include "config/av1_rtcd.h"

#include "aom_dsp/arm/mem_neon.h"

#define FILTER_INTRA_SCALE_BITS 4

// The input arrays are reordered compared to the C implementation: the first
// four vectors contain the lower elements of the original filter, the next four
// vectors contain the upper elements. This layout allows all 8 multiplications
// to accumulate into a single element using USDOT instructions, instead of
// having two partial sums in adjacent vector elements and needing to combine
// them with an additional pairwise add.
DECLARE_ALIGNED(16static const int8_t,
                av1_filter_intra_taps_neon_i8mm[FILTER_INTRA_MODES][8][8]) = {
  {
      { -61000, -52100 },
      { -31110, -3112 },
      { -4600, -3260 },
      { -3226, -3122 },
      { 012000900 },
      { 070010500 },
      { 021200290 },
      { 02706350 },
  },
  {
      { -101600, -60160 },
      { -40016, -2000 },
      { -101600, -60160 },
      { -40016, -2000 },
      { 010000600 },
      { 040016200 },
      { 001000060 },
      { 004016020 },
  },
  {
      { -8800, -8080 },
      { -8008, -8000 },
      { -4400, -4040 },
      { -4004, -4000 },
      { 0160001600 },
      { 0160081600 },
      { 0016000160 },
      { 0016040160 },
  },
  {
      { -2800, -1380 },
      { -12380123 },
      { -1400, -1340 },
      { -1234, -1223 },
      { 010000600 },
      { 04008200 },
      { 031000460 },
      { 04404330 },
  },
  {
      { -121400, -100140 },
      { -90014, -8000 },
      { -101200, -91120 },
      { -80012, -7001 },
      { 0140001200 },
      { 01100141000 },
      { 0014000120 },
      { 0111012190 },
  },
};

static inline uint8x8_t filter_intra_predictor(uint8x16_t p_lo, uint8x16_t p_hi,
                                               const int8x16_t f01,
                                               const int8x16_t f23,
                                               const int8x16_t f45,
                                               const int8x16_t f67) {
  int32x4_t acc_0123 = vusdotq_s32(vdupq_n_s32(0), p_lo, f01);
  acc_0123 = vusdotq_s32(acc_0123, p_hi, f23);

  int32x4_t acc_4567 = vusdotq_s32(vdupq_n_s32(0), p_lo, f45);
  acc_4567 = vusdotq_s32(acc_4567, p_hi, f67);

  const int16x8_t acc = vcombine_s16(vmovn_s32(acc_0123), vmovn_s32(acc_4567));

  return vqrshrun_n_s16(acc, FILTER_INTRA_SCALE_BITS);
}

void av1_filter_intra_predictor_neon_i8mm(uint8_t *dst, ptrdiff_t stride,
                                          TX_SIZE tx_size, const uint8_t *above,
                                          const uint8_t *left, int mode) {
  const int bw = tx_size_wide[tx_size];
  const int bh = tx_size_high[tx_size];

  if (bw == 4 || (bw == 8 && bh < 16) || (bw == 16 && bh <= 4) || bw == 32) {
    av1_filter_intra_predictor_neon(dst, stride, tx_size, above, left, mode);
    return;
  }

  assert(bw <= 32 && bh <= 32);

  const int8x16_t f01 = vld1q_s8(av1_filter_intra_taps_neon_i8mm[mode][0]);
  const int8x16_t f45 = vld1q_s8(av1_filter_intra_taps_neon_i8mm[mode][2]);
  const int8x16_t f23 = vld1q_s8(av1_filter_intra_taps_neon_i8mm[mode][4]);
  const int8x16_t f67 = vld1q_s8(av1_filter_intra_taps_neon_i8mm[mode][6]);

  // indexes : 0, 19, 23, -1
  uint8x16_t p_hi_idx = vreinterpretq_u8_u32(vdupq_n_u32(0xFF171300));

  uint64_t l01 = ((uint64_t)left[0] << 24) | ((uint64_t)left[1] << 56);
  uint8x16_t l = vreinterpretq_u8_u64(vdupq_n_u64(l01));

  int c = 0;
  do {
    const uint8_t *ptr = above + c - 1;
    uint32_t lo =
        ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | ((uint32_t)ptr[3] << 24);
    uint8x16_t p_lo = vreinterpretq_u8_u32(vdupq_n_u32(lo));

    uint8x16x2_t hi;
    hi.val[0] = vdupq_n_u8(ptr[4]);
    hi.val[1] = l;
    uint8x16_t p_hi = vqtbl2q_u8(hi, p_hi_idx);

    const uint8x8_t res =
        filter_intra_predictor(p_lo, p_hi, f01, f23, f45, f67);

    store_u8x4_strided_x2(dst + c, stride, res);

    l = vcombine_u8(res, res);

    c += 4;
  } while (c < bw);

  dst += 2 * stride;
  int r = 2;
  while (r < bh) {
    const uint8_t *ptr = dst - stride;
    uint32_t lo =
        left[r - 1] | (ptr[0] << 8) | (ptr[1] << 16) | ((uint32_t)ptr[2] << 24);
    uint32_t hi = ptr[3] | (left[r] << 8) | (left[r + 1] << 16);
    uint8x16_t p_lo = vreinterpretq_u8_u32(vdupq_n_u32(lo));
    uint8x16_t p_hi = vreinterpretq_u8_u32(vdupq_n_u32(hi));

    uint8x8_t res = filter_intra_predictor(p_lo, p_hi, f01, f23, f45, f67);

    store_u8x4_strided_x2(dst, stride, res);

    l = vcombine_u8(res, res);

    c = 4;
    while (c < bw) {
      ptr = dst - stride + c - 1;
      lo = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | ((uint32_t)ptr[3] << 24);
      p_lo = vreinterpretq_u8_u32(vdupq_n_u32(lo));

      uint8x16x2_t hi_v;
      hi_v.val[0] = vdupq_n_u8(ptr[4]);
      hi_v.val[1] = l;
      p_hi = vqtbl2q_u8(hi_v, p_hi_idx);

      res = filter_intra_predictor(p_lo, p_hi, f01, f23, f45, f67);

      store_u8x4_strided_x2(dst + c, stride, res);

      l = vcombine_u8(res, res);
      c += 4;
    }

    r += 2;
    dst += 2 * stride;
  }
}

Messung V0.5 in Prozent
C=96 H=70 G=83

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=434850
#Domains=655579