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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
/*
* Copyright © 2020, VideoLAN and dav1d authors
* Copyright © 2020, Two Orioles, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DAV1D_SRC_REF_MVS_H
#define DAV1D_SRC_REF_MVS_H
#include <stdint.h>
#include "dav1d/headers.h"
#include "common/intops.h"
#include "src/intra_edge.h"
#include "src/tables.h"
#define INVALID_MV 0x80008000
PACKED(typedef struct refmvs_temporal_block {
mv mv;
int8_t ref;
}) refmvs_temporal_block;
typedef union refmvs_refpair {
int8_t ref[2]; // [0] = 0: intra=1, [1] = -1: comp=0
uint16_t pair;
} refmvs_refpair;
typedef union refmvs_mvpair {
mv mv[2];
uint64_t n;
} refmvs_mvpair;
PACKED(typedef struct refmvs_block {
refmvs_mvpair mv;
refmvs_refpair ref;
uint8_t bs, mf; // 1 = globalmv+affine, 2 = newmv
}) ALIGN(refmvs_block, 4);
typedef struct refmvs_frame {
const Dav1dFrameHeader *frm_hdr;
int iw4, ih4, iw8, ih8;
int sbsz;
int use_ref_frame_mvs;
uint8_t sign_bias[7], mfmv_sign[7];
int8_t pocdiff[7];
uint8_t mfmv_ref[3];
int mfmv_ref2cur[3];
int mfmv_ref2ref[3][7];
int n_mfmvs;
refmvs_temporal_block *rp;
/*const*/ refmvs_temporal_block *const *rp_ref;
refmvs_temporal_block *rp_proj;
ptrdiff_t rp_stride;
refmvs_block *r; // 35 x r_stride memory
ptrdiff_t r_stride;
int n_tile_rows, n_tile_threads, n_frame_threads;
} refmvs_frame;
typedef struct refmvs_tile {
const refmvs_frame *rf;
refmvs_block *r[32 + 5];
refmvs_temporal_block *rp_proj;
struct {
int start, end;
} tile_col, tile_row;
} refmvs_tile;
typedef struct refmvs_candidate {
refmvs_mvpair mv;
int weight;
} refmvs_candidate;
// initialize temporal MVs; this can be done in any configuration, e.g. one
// tile/sbrow at a time, where col_{start,end}8 are the tile boundaries; or
// it can just be for the whole frame's sbrow, where col_{start,end}8 are the
// frame boundaries. row_{start,end}8 are the superblock row boundaries.
#define decl_load_tmvs_fn(name) \
void (name)(const refmvs_frame *rf, int tile_row_idx, \
int col_start8, int col_end8, int row_start8, int row_end8)
typedef decl_load_tmvs_fn(*load_tmvs_fn);
#define decl_save_tmvs_fn(name) \
void (name)(refmvs_temporal_block *rp, const ptrdiff_t stride, \
refmvs_block *const *const rr, const uint8_t *const ref_sign, \
int col_end8, int row_end8, int col_start8, int row_start8)
typedef decl_save_tmvs_fn(*save_tmvs_fn);
#define decl_splat_mv_fn(name) \
void (name)(refmvs_block **rr, const refmvs_block *rmv, int bx4, int bw4, int bh4)
typedef decl_splat_mv_fn(*splat_mv_fn);
typedef struct Dav1dRefmvsDSPContext {
load_tmvs_fn load_tmvs;
save_tmvs_fn save_tmvs;
splat_mv_fn splat_mv;
} Dav1dRefmvsDSPContext;
// call once per frame thread
void dav1d_refmvs_init(refmvs_frame *rf);
void dav1d_refmvs_clear(refmvs_frame *rf);
// call once per frame
int dav1d_refmvs_init_frame(refmvs_frame *rf,
const Dav1dSequenceHeader *seq_hdr,
const Dav1dFrameHeader *frm_hdr,
const unsigned ref_poc[7],
refmvs_temporal_block *rp,
const unsigned ref_ref_poc[7][7],
/*const*/ refmvs_temporal_block *const rp_ref[7],
int n_tile_threads, int n_frame_threads);
// cache the current tile/sbrow (or frame/sbrow)'s projectable motion vectors
// into buffers for use in future frame's temporal MV prediction
static inline void dav1d_refmvs_save_tmvs(const Dav1dRefmvsDSPContext *const dsp,
const refmvs_tile *const rt,
const int col_start8, int col_end8,
const int row_start8, int row_end8)
{
const refmvs_frame *const rf = rt->rf;
assert(row_start8 >= 0);
assert((unsigned) (row_end8 - row_start8) <= 16U);
row_end8 = imin(row_end8, rf->ih8);
col_end8 = imin(col_end8, rf->iw8);
const ptrdiff_t stride = rf->rp_stride;
const uint8_t *const ref_sign = rf->mfmv_sign;
refmvs_temporal_block *rp = &rf->rp[row_start8 * stride];
dsp->save_tmvs(rp, stride, rt->r + 6, ref_sign,
col_end8, row_end8, col_start8, row_start8);
}
// initialize tile boundaries and refmvs_block pointers for one tile/sbrow
void dav1d_refmvs_tile_sbrow_init(refmvs_tile *rt, const refmvs_frame *rf,
int tile_col_start4, int tile_col_end4,
int tile_row_start4, int tile_row_end4,
int sby, int tile_row_idx, int pass);
// call for each block
void dav1d_refmvs_find(const refmvs_tile *rt,
refmvs_candidate mvstack[8], int *cnt,
int *ctx, const refmvs_refpair ref, enum BlockSize bs,
enum EdgeFlags edge_flags, int by4, int bx4);
void dav1d_refmvs_dsp_init(Dav1dRefmvsDSPContext *dsp);
void dav1d_refmvs_dsp_init_arm(Dav1dRefmvsDSPContext *dsp);
void dav1d_refmvs_dsp_init_x86(Dav1dRefmvsDSPContext *dsp);
#endif /* DAV1D_SRC_REF_MVS_H */
|