cb3aef3dac
Follows PR #26 (Intra_4x4 luma) with the same promotion pattern for the rest of the intra prediction primitive set: Intra_16x16 luma (4 modes, PR #13) — V/H/DC/Plane Intra_8x8 chroma (4 modes, PR #14) — DC/H/V/Plane (4:2:0) Intra_8x8 luma (9 modes, PRs #21 + #22) — High profile, with 1-2-1 pre-filter 3 file moves via `git mv`, ~17 function renames stripping the `_ref` suffix. Test binaries rewired to link daedalus_core instead of compiling the (now moved) ref files directly. No code change — pure plumbing for substitution-arc consumers. 26 intra prediction modes total now in the public API after this PR. Verified on hertz: test_intra_pred_16x16: 5/5 PASS test_intra_pred_chroma8x8: 5/5 PASS test_intra_pred_8x8_luma: 11/11 PASS All via public symbols (test binaries linked against daedalus_core). Unblocks marfrit-packages substitution arc patch 0014 — wires H264PredContext.pred4x4[], pred16x16[], pred8x8[], pred8x8l[] through daedalus alongside the existing IDCT / deblock / qpel / DC Hadamard substitutions. After 0014 lands, the libavcodec.so built by marfrit-packages will have EVERY hot-path pixel-math kernel of an H.264 8-bit 4:2:0 decode routing through daedalus — the substitution arc is feature- complete for the campaign target (Pi 5 Firefox YouTube playback).
306 lines
14 KiB
C
306 lines
14 KiB
C
/*
|
|
* Standalone bit-exact C reference for H.264 luma Intra_8x8
|
|
* prediction modes (per H.264 spec §8.3.2.1). High-profile-only
|
|
* MB type — Baseline/Main/Extended profiles don't see Intra_8x8.
|
|
*
|
|
* Distinct from Intra_4x4 in two ways:
|
|
*
|
|
* 1. REFERENCE SAMPLE FILTERING (§8.3.2.1.1). The 25 raw
|
|
* neighbour samples are pre-filtered with a 1-2-1 smoothing
|
|
* filter BEFORE prediction. The filtering has spec-defined
|
|
* boundary handling at the corners and the right-edge of the
|
|
* top-row extension.
|
|
*
|
|
* 2. SCALE. All 9 prediction modes operate at 8x8 with the
|
|
* filtered samples (Intra_4x4 operates at 4x4 with the raw
|
|
* samples).
|
|
*
|
|
* This PR implements the filter + the 3 simple modes (Vertical,
|
|
* Horizontal, DC). The 6 directional modes (DDL, DDR, VR, HD, VL,
|
|
* HU at 8x8) follow in a separate PR — same template, different
|
|
* formulas per spec sections §8.3.2.1.4..§8.3.2.1.9.
|
|
*
|
|
* Calling convention (FFmpeg-style):
|
|
* pred_8x8_<mode>_ref(uint8_t *dst, ptrdiff_t stride)
|
|
*
|
|
* `dst` points at row 0 col 0 of the 8x8 output block. Reads from
|
|
* top[0..15] = dst[-stride + 0..15]
|
|
* top-left = dst[-stride - 1]
|
|
* left[0..7] = dst[ 0*stride - 1 .. 7*stride - 1]
|
|
*
|
|
* AVAILABILITY: assumes all neighbours valid (interior-MB case).
|
|
*
|
|
* License: BSD-2-Clause.
|
|
*/
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
static inline int clip_u8(int v) { return v < 0 ? 0 : v > 255 ? 255 : v; }
|
|
|
|
/* H.264 §8.3.2.1.1 reference sample filtering. Filters the 25 raw
|
|
* samples around the 8x8 block into a `filt` array with the same
|
|
* indices. When called against an "all neighbours available" tile,
|
|
* the filtered output uses these spec-defined formulas:
|
|
*
|
|
* filt[top -1] (= filtered top-left) = (top[0] + 2*tl + left[0] + 2) >> 2
|
|
*
|
|
* filt[top 0] = (tl + 2*top[0] + top[1] + 2) >> 2
|
|
* filt[top i] for 1<=i<=14 = (top[i-1] + 2*top[i] + top[i+1] + 2) >> 2
|
|
* filt[top 15] = (top[14] + 3*top[15] + 2) >> 2 (boundary)
|
|
*
|
|
* filt[left 0] = (tl + 2*left[0] + left[1] + 2) >> 2
|
|
* filt[left j] for 1<=j<=6 = (left[j-1] + 2*left[j] + left[j+1] + 2) >> 2
|
|
* filt[left 7] = (left[6] + 3*left[7] + 2) >> 2 (boundary)
|
|
*
|
|
* Reads neighbours from the dst buffer; writes filtered values to
|
|
* a caller-provided 26-element array indexed as:
|
|
* filt[0] = filtered top-left
|
|
* filt[1..16] = filtered top[0..15]
|
|
* filt[17..24] = filtered left[0..7]
|
|
*/
|
|
static void filter_refs(const uint8_t *dst, ptrdiff_t stride,
|
|
uint8_t filt[25])
|
|
{
|
|
int tl = dst[-stride - 1];
|
|
int t[16];
|
|
for (int i = 0; i < 16; i++) t[i] = dst[-stride + i];
|
|
int l[8];
|
|
for (int j = 0; j < 8; j++) l[j] = dst[j * stride - 1];
|
|
|
|
/* Filtered top-left. */
|
|
filt[0] = (uint8_t)((t[0] + 2*tl + l[0] + 2) >> 2);
|
|
|
|
/* Filtered top. */
|
|
filt[1] = (uint8_t)((tl + 2*t[0] + t[1] + 2) >> 2);
|
|
for (int i = 1; i <= 14; i++)
|
|
filt[1 + i] = (uint8_t)((t[i-1] + 2*t[i] + t[i+1] + 2) >> 2);
|
|
filt[1 + 15] = (uint8_t)((t[14] + 3*t[15] + 2) >> 2);
|
|
|
|
/* Filtered left. */
|
|
filt[17 + 0] = (uint8_t)((tl + 2*l[0] + l[1] + 2) >> 2);
|
|
for (int j = 1; j <= 6; j++)
|
|
filt[17 + j] = (uint8_t)((l[j-1] + 2*l[j] + l[j+1] + 2) >> 2);
|
|
filt[17 + 7] = (uint8_t)((l[6] + 3*l[7] + 2) >> 2);
|
|
}
|
|
|
|
/* Convenience macros for accessing the filt[] array by spec-style index. */
|
|
#define FT(i) filt[1 + (i)] /* filtered top[i], i in 0..15 */
|
|
#define FL(j) filt[17 + (j)] /* filtered left[j], j in 0..7 */
|
|
#define FTL filt[0] /* filtered top-left */
|
|
|
|
/* Mode 0 Vertical (§8.3.2.1.2): pred[r,c] = filt_top[c]. */
|
|
void daedalus_h264_pred_8x8l_vertical(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
for (int r = 0; r < 8; r++)
|
|
for (int c = 0; c < 8; c++) dst[r * stride + c] = FT(c);
|
|
}
|
|
|
|
/* Mode 1 Horizontal (§8.3.2.1.3): pred[r,c] = filt_left[r]. */
|
|
void daedalus_h264_pred_8x8l_horizontal(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
for (int r = 0; r < 8; r++)
|
|
for (int c = 0; c < 8; c++) dst[r * stride + c] = FL(r);
|
|
}
|
|
|
|
/* Mode 2 DC (§8.3.2.1.4): ((sum_filt_top[0..7] + sum_filt_left[0..7]
|
|
* + 8) >> 4) broadcast. Note the +8 (not +4 like 4x4): there are
|
|
* 16 samples summed total, so >> 4 with half-step rounding +8. */
|
|
void daedalus_h264_pred_8x8l_dc(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
int sum = 8;
|
|
for (int i = 0; i < 8; i++) sum += FT(i);
|
|
for (int j = 0; j < 8; j++) sum += FL(j);
|
|
uint8_t v = (uint8_t)(sum >> 4);
|
|
for (int r = 0; r < 8; r++)
|
|
for (int c = 0; c < 8; c++) dst[r * stride + c] = v;
|
|
}
|
|
|
|
/* --- 6 directional modes for Intra_8x8 (H.264 §8.3.2.1.5..§8.3.2.1.10).
|
|
* Transcribed from FFmpeg libavcodec/h264pred_template.c
|
|
* pred8x8l_{down_left, down_right, vertical_right, horizontal_down,
|
|
* vertical_left, horizontal_up} (LGPL-2.1+ in the original; algorithm
|
|
* reproduced here for test purposes).
|
|
*
|
|
* All 6 use the same FILTERED reference samples produced by
|
|
* filter_refs() above. Mapping from FFmpeg's t0..t15 / l0..l7 / lt
|
|
* notation:
|
|
* tN = FT(N) for N in 0..15
|
|
* lN = FL(N) for N in 0..7
|
|
* lt = FTL
|
|
*
|
|
* SRC(x,y) maps to dst[y*stride + x] (col x, row y).
|
|
*/
|
|
#define SRC(x, y) dst[(y) * stride + (x)]
|
|
#define T(i) FT(i)
|
|
#define L(j) FL(j)
|
|
#define LT FTL
|
|
|
|
/* Mode 3 DDL (Diagonal_Down_Left) — uses TOP + TOP_RIGHT, no LEFT. */
|
|
void daedalus_h264_pred_8x8l_ddl(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,0)= (T(0) + 2*T(1) + T(2) + 2) >> 2;
|
|
SRC(0,1)=SRC(1,0)= (T(1) + 2*T(2) + T(3) + 2) >> 2;
|
|
SRC(0,2)=SRC(1,1)=SRC(2,0)= (T(2) + 2*T(3) + T(4) + 2) >> 2;
|
|
SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (T(3) + 2*T(4) + T(5) + 2) >> 2;
|
|
SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (T(4) + 2*T(5) + T(6) + 2) >> 2;
|
|
SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (T(5) + 2*T(6) + T(7) + 2) >> 2;
|
|
SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (T(6) + 2*T(7) + T(8) + 2) >> 2;
|
|
SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (T(7) + 2*T(8) + T(9) + 2) >> 2;
|
|
SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (T(8) + 2*T(9) + T(10) + 2) >> 2;
|
|
SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (T(9) + 2*T(10) + T(11) + 2) >> 2;
|
|
SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (T(10) + 2*T(11) + T(12) + 2) >> 2;
|
|
SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (T(11) + 2*T(12) + T(13) + 2) >> 2;
|
|
SRC(5,7)=SRC(6,6)=SRC(7,5)= (T(12) + 2*T(13) + T(14) + 2) >> 2;
|
|
SRC(6,7)=SRC(7,6)= (T(13) + 2*T(14) + T(15) + 2) >> 2;
|
|
SRC(7,7)= (T(14) + 3*T(15) + 2) >> 2;
|
|
}
|
|
|
|
/* Mode 4 DDR (Diagonal_Down_Right). */
|
|
void daedalus_h264_pred_8x8l_ddr(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,7)= (L(7) + 2*L(6) + L(5) + 2) >> 2;
|
|
SRC(0,6)=SRC(1,7)= (L(6) + 2*L(5) + L(4) + 2) >> 2;
|
|
SRC(0,5)=SRC(1,6)=SRC(2,7)= (L(5) + 2*L(4) + L(3) + 2) >> 2;
|
|
SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (L(4) + 2*L(3) + L(2) + 2) >> 2;
|
|
SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (L(3) + 2*L(2) + L(1) + 2) >> 2;
|
|
SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (L(2) + 2*L(1) + L(0) + 2) >> 2;
|
|
SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (L(1) + 2*L(0) + LT + 2) >> 2;
|
|
SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (L(0) + 2*LT + T(0) + 2) >> 2;
|
|
SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (LT + 2*T(0) + T(1) + 2) >> 2;
|
|
SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (T(0) + 2*T(1) + T(2) + 2) >> 2;
|
|
SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (T(1) + 2*T(2) + T(3) + 2) >> 2;
|
|
SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (T(2) + 2*T(3) + T(4) + 2) >> 2;
|
|
SRC(5,0)=SRC(6,1)=SRC(7,2)= (T(3) + 2*T(4) + T(5) + 2) >> 2;
|
|
SRC(6,0)=SRC(7,1)= (T(4) + 2*T(5) + T(6) + 2) >> 2;
|
|
SRC(7,0)= (T(5) + 2*T(6) + T(7) + 2) >> 2;
|
|
}
|
|
|
|
/* Mode 5 VR (Vertical_Right). */
|
|
void daedalus_h264_pred_8x8l_vr(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,6)= (L(5) + 2*L(4) + L(3) + 2) >> 2;
|
|
SRC(0,7)= (L(6) + 2*L(5) + L(4) + 2) >> 2;
|
|
SRC(0,4)=SRC(1,6)= (L(3) + 2*L(2) + L(1) + 2) >> 2;
|
|
SRC(0,5)=SRC(1,7)= (L(4) + 2*L(3) + L(2) + 2) >> 2;
|
|
SRC(0,2)=SRC(1,4)=SRC(2,6)= (L(1) + 2*L(0) + LT + 2) >> 2;
|
|
SRC(0,3)=SRC(1,5)=SRC(2,7)= (L(2) + 2*L(1) + L(0) + 2) >> 2;
|
|
SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (L(0) + 2*LT + T(0) + 2) >> 2;
|
|
SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (LT + T(0) + 1) >> 1;
|
|
SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (LT + 2*T(0) + T(1) + 2) >> 2;
|
|
SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (T(0) + T(1) + 1) >> 1;
|
|
SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (T(0) + 2*T(1) + T(2) + 2) >> 2;
|
|
SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (T(1) + T(2) + 1) >> 1;
|
|
SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (T(1) + 2*T(2) + T(3) + 2) >> 2;
|
|
SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (T(2) + T(3) + 1) >> 1;
|
|
SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (T(2) + 2*T(3) + T(4) + 2) >> 2;
|
|
SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (T(3) + T(4) + 1) >> 1;
|
|
SRC(5,1)=SRC(6,3)=SRC(7,5)= (T(3) + 2*T(4) + T(5) + 2) >> 2;
|
|
SRC(5,0)=SRC(6,2)=SRC(7,4)= (T(4) + T(5) + 1) >> 1;
|
|
SRC(6,1)=SRC(7,3)= (T(4) + 2*T(5) + T(6) + 2) >> 2;
|
|
SRC(6,0)=SRC(7,2)= (T(5) + T(6) + 1) >> 1;
|
|
SRC(7,1)= (T(5) + 2*T(6) + T(7) + 2) >> 2;
|
|
SRC(7,0)= (T(6) + T(7) + 1) >> 1;
|
|
}
|
|
|
|
/* Mode 6 HD (Horizontal_Down). */
|
|
void daedalus_h264_pred_8x8l_hd(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,7)= (L(6) + L(7) + 1) >> 1;
|
|
SRC(1,7)= (L(5) + 2*L(6) + L(7) + 2) >> 2;
|
|
SRC(0,6)=SRC(2,7)= (L(5) + L(6) + 1) >> 1;
|
|
SRC(1,6)=SRC(3,7)= (L(4) + 2*L(5) + L(6) + 2) >> 2;
|
|
SRC(0,5)=SRC(2,6)=SRC(4,7)= (L(4) + L(5) + 1) >> 1;
|
|
SRC(1,5)=SRC(3,6)=SRC(5,7)= (L(3) + 2*L(4) + L(5) + 2) >> 2;
|
|
SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (L(3) + L(4) + 1) >> 1;
|
|
SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (L(2) + 2*L(3) + L(4) + 2) >> 2;
|
|
SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (L(2) + L(3) + 1) >> 1;
|
|
SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (L(1) + 2*L(2) + L(3) + 2) >> 2;
|
|
SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (L(1) + L(2) + 1) >> 1;
|
|
SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (L(0) + 2*L(1) + L(2) + 2) >> 2;
|
|
SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (L(0) + L(1) + 1) >> 1;
|
|
SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (LT + 2*L(0) + L(1) + 2) >> 2;
|
|
SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (LT + L(0) + 1) >> 1;
|
|
SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (L(0) + 2*LT + T(0) + 2) >> 2;
|
|
SRC(2,0)=SRC(4,1)=SRC(6,2)= (T(1) + 2*T(0) + LT + 2) >> 2;
|
|
SRC(3,0)=SRC(5,1)=SRC(7,2)= (T(2) + 2*T(1) + T(0) + 2) >> 2;
|
|
SRC(4,0)=SRC(6,1)= (T(3) + 2*T(2) + T(1) + 2) >> 2;
|
|
SRC(5,0)=SRC(7,1)= (T(4) + 2*T(3) + T(2) + 2) >> 2;
|
|
SRC(6,0)= (T(5) + 2*T(4) + T(3) + 2) >> 2;
|
|
SRC(7,0)= (T(6) + 2*T(5) + T(4) + 2) >> 2;
|
|
}
|
|
|
|
/* Mode 7 VL (Vertical_Left) — uses TOP + TOP_RIGHT only. */
|
|
void daedalus_h264_pred_8x8l_vl(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,0)= (T(0) + T(1) + 1) >> 1;
|
|
SRC(0,1)= (T(0) + 2*T(1) + T(2) + 2) >> 2;
|
|
SRC(0,2)=SRC(1,0)= (T(1) + T(2) + 1) >> 1;
|
|
SRC(0,3)=SRC(1,1)= (T(1) + 2*T(2) + T(3) + 2) >> 2;
|
|
SRC(0,4)=SRC(1,2)=SRC(2,0)= (T(2) + T(3) + 1) >> 1;
|
|
SRC(0,5)=SRC(1,3)=SRC(2,1)= (T(2) + 2*T(3) + T(4) + 2) >> 2;
|
|
SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (T(3) + T(4) + 1) >> 1;
|
|
SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (T(3) + 2*T(4) + T(5) + 2) >> 2;
|
|
SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (T(4) + T(5) + 1) >> 1;
|
|
SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (T(4) + 2*T(5) + T(6) + 2) >> 2;
|
|
SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (T(5) + T(6) + 1) >> 1;
|
|
SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (T(5) + 2*T(6) + T(7) + 2) >> 2;
|
|
SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (T(6) + T(7) + 1) >> 1;
|
|
SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (T(6) + 2*T(7) + T(8) + 2) >> 2;
|
|
SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (T(7) + T(8) + 1) >> 1;
|
|
SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (T(7) + 2*T(8) + T(9) + 2) >> 2;
|
|
SRC(5,6)=SRC(6,4)=SRC(7,2)= (T(8) + T(9) + 1) >> 1;
|
|
SRC(5,7)=SRC(6,5)=SRC(7,3)= (T(8) + 2*T(9) + T(10) + 2) >> 2;
|
|
SRC(6,6)=SRC(7,4)= (T(9) + T(10) + 1) >> 1;
|
|
SRC(6,7)=SRC(7,5)= (T(9) + 2*T(10) + T(11) + 2) >> 2;
|
|
SRC(7,6)= (T(10) + T(11) + 1) >> 1;
|
|
SRC(7,7)= (T(10) + 2*T(11) + T(12) + 2) >> 2;
|
|
}
|
|
|
|
/* Mode 8 HU (Horizontal_Up) — uses LEFT only. */
|
|
void daedalus_h264_pred_8x8l_hu(uint8_t *dst, ptrdiff_t stride)
|
|
{
|
|
uint8_t filt[25];
|
|
filter_refs(dst, stride, filt);
|
|
SRC(0,0)= (L(0) + L(1) + 1) >> 1;
|
|
SRC(1,0)= (L(0) + 2*L(1) + L(2) + 2) >> 2;
|
|
SRC(0,1)=SRC(2,0)= (L(1) + L(2) + 1) >> 1;
|
|
SRC(1,1)=SRC(3,0)= (L(1) + 2*L(2) + L(3) + 2) >> 2;
|
|
SRC(0,2)=SRC(2,1)=SRC(4,0)= (L(2) + L(3) + 1) >> 1;
|
|
SRC(1,2)=SRC(3,1)=SRC(5,0)= (L(2) + 2*L(3) + L(4) + 2) >> 2;
|
|
SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (L(3) + L(4) + 1) >> 1;
|
|
SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (L(3) + 2*L(4) + L(5) + 2) >> 2;
|
|
SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (L(4) + L(5) + 1) >> 1;
|
|
SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (L(4) + 2*L(5) + L(6) + 2) >> 2;
|
|
SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (L(5) + L(6) + 1) >> 1;
|
|
SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (L(5) + 2*L(6) + L(7) + 2) >> 2;
|
|
SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (L(6) + L(7) + 1) >> 1;
|
|
SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (L(6) + 3*L(7) + 2) >> 2;
|
|
/* 20 positions all = L(7) per FFmpeg lines 1097-1100. */
|
|
SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)=
|
|
SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)=
|
|
SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)=
|
|
SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= L(7);
|
|
}
|
|
|
|
#undef SRC
|
|
#undef T
|
|
#undef L
|
|
#undef LT
|