1*c0909341SAndroid Build Coastguard Worker /*
2*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, VideoLAN and dav1d authors
3*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, Two Orioles, LLC
4*c0909341SAndroid Build Coastguard Worker * All rights reserved.
5*c0909341SAndroid Build Coastguard Worker *
6*c0909341SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
7*c0909341SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
8*c0909341SAndroid Build Coastguard Worker *
9*c0909341SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright notice, this
10*c0909341SAndroid Build Coastguard Worker * list of conditions and the following disclaimer.
11*c0909341SAndroid Build Coastguard Worker *
12*c0909341SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright notice,
13*c0909341SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
14*c0909341SAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
15*c0909341SAndroid Build Coastguard Worker *
16*c0909341SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*c0909341SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*c0909341SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*c0909341SAndroid Build Coastguard Worker * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20*c0909341SAndroid Build Coastguard Worker * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*c0909341SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*c0909341SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*c0909341SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*c0909341SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*c0909341SAndroid Build Coastguard Worker * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*c0909341SAndroid Build Coastguard Worker */
27*c0909341SAndroid Build Coastguard Worker
28*c0909341SAndroid Build Coastguard Worker #ifndef DAV1D_SRC_ENV_H
29*c0909341SAndroid Build Coastguard Worker #define DAV1D_SRC_ENV_H
30*c0909341SAndroid Build Coastguard Worker
31*c0909341SAndroid Build Coastguard Worker #include <stddef.h>
32*c0909341SAndroid Build Coastguard Worker #include <stdint.h>
33*c0909341SAndroid Build Coastguard Worker #include <stdlib.h>
34*c0909341SAndroid Build Coastguard Worker
35*c0909341SAndroid Build Coastguard Worker #include "src/levels.h"
36*c0909341SAndroid Build Coastguard Worker #include "src/refmvs.h"
37*c0909341SAndroid Build Coastguard Worker #include "src/tables.h"
38*c0909341SAndroid Build Coastguard Worker
39*c0909341SAndroid Build Coastguard Worker typedef struct BlockContext {
40*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(mode[32], 8);
41*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(lcoef[32], 8);
42*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(ccoef[2][32], 8);
43*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(seg_pred[32], 8);
44*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(skip[32], 8);
45*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(skip_mode[32], 8);
46*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(intra[32], 8);
47*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(comp_type[32], 8);
48*c0909341SAndroid Build Coastguard Worker int8_t ALIGN(ref[2][32], 8); // -1 means intra
49*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(filter[2][32], 8); // 3 means unset
50*c0909341SAndroid Build Coastguard Worker int8_t ALIGN(tx_intra[32], 8);
51*c0909341SAndroid Build Coastguard Worker int8_t ALIGN(tx[32], 8);
52*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(tx_lpf_y[32], 8);
53*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(tx_lpf_uv[32], 8);
54*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(partition[16], 8);
55*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(uvmode[32], 8);
56*c0909341SAndroid Build Coastguard Worker uint8_t ALIGN(pal_sz[32], 8);
57*c0909341SAndroid Build Coastguard Worker } BlockContext;
58*c0909341SAndroid Build Coastguard Worker
get_intra_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)59*c0909341SAndroid Build Coastguard Worker static inline int get_intra_ctx(const BlockContext *const a,
60*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
61*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
62*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
63*c0909341SAndroid Build Coastguard Worker {
64*c0909341SAndroid Build Coastguard Worker if (have_left) {
65*c0909341SAndroid Build Coastguard Worker if (have_top) {
66*c0909341SAndroid Build Coastguard Worker const int ctx = l->intra[yb4] + a->intra[xb4];
67*c0909341SAndroid Build Coastguard Worker return ctx + (ctx == 2);
68*c0909341SAndroid Build Coastguard Worker } else
69*c0909341SAndroid Build Coastguard Worker return l->intra[yb4] * 2;
70*c0909341SAndroid Build Coastguard Worker } else {
71*c0909341SAndroid Build Coastguard Worker return have_top ? a->intra[xb4] * 2 : 0;
72*c0909341SAndroid Build Coastguard Worker }
73*c0909341SAndroid Build Coastguard Worker }
74*c0909341SAndroid Build Coastguard Worker
get_tx_ctx(const BlockContext * const a,const BlockContext * const l,const TxfmInfo * const max_tx,const int yb4,const int xb4)75*c0909341SAndroid Build Coastguard Worker static inline int get_tx_ctx(const BlockContext *const a,
76*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
77*c0909341SAndroid Build Coastguard Worker const TxfmInfo *const max_tx,
78*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4)
79*c0909341SAndroid Build Coastguard Worker {
80*c0909341SAndroid Build Coastguard Worker return (l->tx_intra[yb4] >= max_tx->lh) + (a->tx_intra[xb4] >= max_tx->lw);
81*c0909341SAndroid Build Coastguard Worker }
82*c0909341SAndroid Build Coastguard Worker
get_partition_ctx(const BlockContext * const a,const BlockContext * const l,const enum BlockLevel bl,const int yb8,const int xb8)83*c0909341SAndroid Build Coastguard Worker static inline int get_partition_ctx(const BlockContext *const a,
84*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
85*c0909341SAndroid Build Coastguard Worker const enum BlockLevel bl,
86*c0909341SAndroid Build Coastguard Worker const int yb8, const int xb8)
87*c0909341SAndroid Build Coastguard Worker {
88*c0909341SAndroid Build Coastguard Worker return ((a->partition[xb8] >> (4 - bl)) & 1) +
89*c0909341SAndroid Build Coastguard Worker (((l->partition[yb8] >> (4 - bl)) & 1) << 1);
90*c0909341SAndroid Build Coastguard Worker }
91*c0909341SAndroid Build Coastguard Worker
gather_left_partition_prob(const uint16_t * const in,const enum BlockLevel bl)92*c0909341SAndroid Build Coastguard Worker static inline unsigned gather_left_partition_prob(const uint16_t *const in,
93*c0909341SAndroid Build Coastguard Worker const enum BlockLevel bl)
94*c0909341SAndroid Build Coastguard Worker {
95*c0909341SAndroid Build Coastguard Worker unsigned out = in[PARTITION_H - 1] - in[PARTITION_H];
96*c0909341SAndroid Build Coastguard Worker // Exploit the fact that cdfs for PARTITION_SPLIT, PARTITION_T_TOP_SPLIT,
97*c0909341SAndroid Build Coastguard Worker // PARTITION_T_BOTTOM_SPLIT and PARTITION_T_LEFT_SPLIT are neighbors.
98*c0909341SAndroid Build Coastguard Worker out += in[PARTITION_SPLIT - 1] - in[PARTITION_T_LEFT_SPLIT];
99*c0909341SAndroid Build Coastguard Worker if (bl != BL_128X128)
100*c0909341SAndroid Build Coastguard Worker out += in[PARTITION_H4 - 1] - in[PARTITION_H4];
101*c0909341SAndroid Build Coastguard Worker return out;
102*c0909341SAndroid Build Coastguard Worker }
103*c0909341SAndroid Build Coastguard Worker
gather_top_partition_prob(const uint16_t * const in,const enum BlockLevel bl)104*c0909341SAndroid Build Coastguard Worker static inline unsigned gather_top_partition_prob(const uint16_t *const in,
105*c0909341SAndroid Build Coastguard Worker const enum BlockLevel bl)
106*c0909341SAndroid Build Coastguard Worker {
107*c0909341SAndroid Build Coastguard Worker // Exploit the fact that cdfs for PARTITION_V, PARTITION_SPLIT and
108*c0909341SAndroid Build Coastguard Worker // PARTITION_T_TOP_SPLIT are neighbors.
109*c0909341SAndroid Build Coastguard Worker unsigned out = in[PARTITION_V - 1] - in[PARTITION_T_TOP_SPLIT];
110*c0909341SAndroid Build Coastguard Worker // Exploit the facts that cdfs for PARTITION_T_LEFT_SPLIT and
111*c0909341SAndroid Build Coastguard Worker // PARTITION_T_RIGHT_SPLIT are neighbors, the probability for
112*c0909341SAndroid Build Coastguard Worker // PARTITION_V4 is always zero, and the probability for
113*c0909341SAndroid Build Coastguard Worker // PARTITION_T_RIGHT_SPLIT is zero in 128x128 blocks.
114*c0909341SAndroid Build Coastguard Worker out += in[PARTITION_T_LEFT_SPLIT - 1];
115*c0909341SAndroid Build Coastguard Worker if (bl != BL_128X128)
116*c0909341SAndroid Build Coastguard Worker out += in[PARTITION_V4 - 1] - in[PARTITION_T_RIGHT_SPLIT];
117*c0909341SAndroid Build Coastguard Worker return out;
118*c0909341SAndroid Build Coastguard Worker }
119*c0909341SAndroid Build Coastguard Worker
get_uv_inter_txtp(const TxfmInfo * const uvt_dim,const enum TxfmType ytxtp)120*c0909341SAndroid Build Coastguard Worker static inline enum TxfmType get_uv_inter_txtp(const TxfmInfo *const uvt_dim,
121*c0909341SAndroid Build Coastguard Worker const enum TxfmType ytxtp)
122*c0909341SAndroid Build Coastguard Worker {
123*c0909341SAndroid Build Coastguard Worker if (uvt_dim->max == TX_32X32)
124*c0909341SAndroid Build Coastguard Worker return ytxtp == IDTX ? IDTX : DCT_DCT;
125*c0909341SAndroid Build Coastguard Worker if (uvt_dim->min == TX_16X16 &&
126*c0909341SAndroid Build Coastguard Worker ((1 << ytxtp) & ((1 << H_FLIPADST) | (1 << V_FLIPADST) |
127*c0909341SAndroid Build Coastguard Worker (1 << H_ADST) | (1 << V_ADST))))
128*c0909341SAndroid Build Coastguard Worker {
129*c0909341SAndroid Build Coastguard Worker return DCT_DCT;
130*c0909341SAndroid Build Coastguard Worker }
131*c0909341SAndroid Build Coastguard Worker
132*c0909341SAndroid Build Coastguard Worker return ytxtp;
133*c0909341SAndroid Build Coastguard Worker }
134*c0909341SAndroid Build Coastguard Worker
get_filter_ctx(const BlockContext * const a,const BlockContext * const l,const int comp,const int dir,const int ref,const int yb4,const int xb4)135*c0909341SAndroid Build Coastguard Worker static inline int get_filter_ctx(const BlockContext *const a,
136*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
137*c0909341SAndroid Build Coastguard Worker const int comp, const int dir, const int ref,
138*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4)
139*c0909341SAndroid Build Coastguard Worker {
140*c0909341SAndroid Build Coastguard Worker const int a_filter = (a->ref[0][xb4] == ref || a->ref[1][xb4] == ref) ?
141*c0909341SAndroid Build Coastguard Worker a->filter[dir][xb4] : DAV1D_N_SWITCHABLE_FILTERS;
142*c0909341SAndroid Build Coastguard Worker const int l_filter = (l->ref[0][yb4] == ref || l->ref[1][yb4] == ref) ?
143*c0909341SAndroid Build Coastguard Worker l->filter[dir][yb4] : DAV1D_N_SWITCHABLE_FILTERS;
144*c0909341SAndroid Build Coastguard Worker
145*c0909341SAndroid Build Coastguard Worker if (a_filter == l_filter) {
146*c0909341SAndroid Build Coastguard Worker return comp * 4 + a_filter;
147*c0909341SAndroid Build Coastguard Worker } else if (a_filter == DAV1D_N_SWITCHABLE_FILTERS) {
148*c0909341SAndroid Build Coastguard Worker return comp * 4 + l_filter;
149*c0909341SAndroid Build Coastguard Worker } else if (l_filter == DAV1D_N_SWITCHABLE_FILTERS) {
150*c0909341SAndroid Build Coastguard Worker return comp * 4 + a_filter;
151*c0909341SAndroid Build Coastguard Worker } else {
152*c0909341SAndroid Build Coastguard Worker return comp * 4 + DAV1D_N_SWITCHABLE_FILTERS;
153*c0909341SAndroid Build Coastguard Worker }
154*c0909341SAndroid Build Coastguard Worker }
155*c0909341SAndroid Build Coastguard Worker
get_comp_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)156*c0909341SAndroid Build Coastguard Worker static inline int get_comp_ctx(const BlockContext *const a,
157*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
158*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
159*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
160*c0909341SAndroid Build Coastguard Worker {
161*c0909341SAndroid Build Coastguard Worker if (have_top) {
162*c0909341SAndroid Build Coastguard Worker if (have_left) {
163*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4]) {
164*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4]) {
165*c0909341SAndroid Build Coastguard Worker return 4;
166*c0909341SAndroid Build Coastguard Worker } else {
167*c0909341SAndroid Build Coastguard Worker // 4U means intra (-1) or bwd (>= 4)
168*c0909341SAndroid Build Coastguard Worker return 2 + ((unsigned)l->ref[0][yb4] >= 4U);
169*c0909341SAndroid Build Coastguard Worker }
170*c0909341SAndroid Build Coastguard Worker } else if (l->comp_type[yb4]) {
171*c0909341SAndroid Build Coastguard Worker // 4U means intra (-1) or bwd (>= 4)
172*c0909341SAndroid Build Coastguard Worker return 2 + ((unsigned)a->ref[0][xb4] >= 4U);
173*c0909341SAndroid Build Coastguard Worker } else {
174*c0909341SAndroid Build Coastguard Worker return (l->ref[0][yb4] >= 4) ^ (a->ref[0][xb4] >= 4);
175*c0909341SAndroid Build Coastguard Worker }
176*c0909341SAndroid Build Coastguard Worker } else {
177*c0909341SAndroid Build Coastguard Worker return a->comp_type[xb4] ? 3 : a->ref[0][xb4] >= 4;
178*c0909341SAndroid Build Coastguard Worker }
179*c0909341SAndroid Build Coastguard Worker } else if (have_left) {
180*c0909341SAndroid Build Coastguard Worker return l->comp_type[yb4] ? 3 : l->ref[0][yb4] >= 4;
181*c0909341SAndroid Build Coastguard Worker } else {
182*c0909341SAndroid Build Coastguard Worker return 1;
183*c0909341SAndroid Build Coastguard Worker }
184*c0909341SAndroid Build Coastguard Worker }
185*c0909341SAndroid Build Coastguard Worker
get_comp_dir_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)186*c0909341SAndroid Build Coastguard Worker static inline int get_comp_dir_ctx(const BlockContext *const a,
187*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
188*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
189*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
190*c0909341SAndroid Build Coastguard Worker {
191*c0909341SAndroid Build Coastguard Worker #define has_uni_comp(edge, off) \
192*c0909341SAndroid Build Coastguard Worker ((edge->ref[0][off] < 4) == (edge->ref[1][off] < 4))
193*c0909341SAndroid Build Coastguard Worker
194*c0909341SAndroid Build Coastguard Worker if (have_top && have_left) {
195*c0909341SAndroid Build Coastguard Worker const int a_intra = a->intra[xb4], l_intra = l->intra[yb4];
196*c0909341SAndroid Build Coastguard Worker
197*c0909341SAndroid Build Coastguard Worker if (a_intra && l_intra) return 2;
198*c0909341SAndroid Build Coastguard Worker if (a_intra || l_intra) {
199*c0909341SAndroid Build Coastguard Worker const BlockContext *const edge = a_intra ? l : a;
200*c0909341SAndroid Build Coastguard Worker const int off = a_intra ? yb4 : xb4;
201*c0909341SAndroid Build Coastguard Worker
202*c0909341SAndroid Build Coastguard Worker if (edge->comp_type[off] == COMP_INTER_NONE) return 2;
203*c0909341SAndroid Build Coastguard Worker return 1 + 2 * has_uni_comp(edge, off);
204*c0909341SAndroid Build Coastguard Worker }
205*c0909341SAndroid Build Coastguard Worker
206*c0909341SAndroid Build Coastguard Worker const int a_comp = a->comp_type[xb4] != COMP_INTER_NONE;
207*c0909341SAndroid Build Coastguard Worker const int l_comp = l->comp_type[yb4] != COMP_INTER_NONE;
208*c0909341SAndroid Build Coastguard Worker const int a_ref0 = a->ref[0][xb4], l_ref0 = l->ref[0][yb4];
209*c0909341SAndroid Build Coastguard Worker
210*c0909341SAndroid Build Coastguard Worker if (!a_comp && !l_comp) {
211*c0909341SAndroid Build Coastguard Worker return 1 + 2 * ((a_ref0 >= 4) == (l_ref0 >= 4));
212*c0909341SAndroid Build Coastguard Worker } else if (!a_comp || !l_comp) {
213*c0909341SAndroid Build Coastguard Worker const BlockContext *const edge = a_comp ? a : l;
214*c0909341SAndroid Build Coastguard Worker const int off = a_comp ? xb4 : yb4;
215*c0909341SAndroid Build Coastguard Worker
216*c0909341SAndroid Build Coastguard Worker if (!has_uni_comp(edge, off)) return 1;
217*c0909341SAndroid Build Coastguard Worker return 3 + ((a_ref0 >= 4) == (l_ref0 >= 4));
218*c0909341SAndroid Build Coastguard Worker } else {
219*c0909341SAndroid Build Coastguard Worker const int a_uni = has_uni_comp(a, xb4), l_uni = has_uni_comp(l, yb4);
220*c0909341SAndroid Build Coastguard Worker
221*c0909341SAndroid Build Coastguard Worker if (!a_uni && !l_uni) return 0;
222*c0909341SAndroid Build Coastguard Worker if (!a_uni || !l_uni) return 2;
223*c0909341SAndroid Build Coastguard Worker return 3 + ((a_ref0 == 4) == (l_ref0 == 4));
224*c0909341SAndroid Build Coastguard Worker }
225*c0909341SAndroid Build Coastguard Worker } else if (have_top || have_left) {
226*c0909341SAndroid Build Coastguard Worker const BlockContext *const edge = have_left ? l : a;
227*c0909341SAndroid Build Coastguard Worker const int off = have_left ? yb4 : xb4;
228*c0909341SAndroid Build Coastguard Worker
229*c0909341SAndroid Build Coastguard Worker if (edge->intra[off]) return 2;
230*c0909341SAndroid Build Coastguard Worker if (edge->comp_type[off] == COMP_INTER_NONE) return 2;
231*c0909341SAndroid Build Coastguard Worker return 4 * has_uni_comp(edge, off);
232*c0909341SAndroid Build Coastguard Worker } else {
233*c0909341SAndroid Build Coastguard Worker return 2;
234*c0909341SAndroid Build Coastguard Worker }
235*c0909341SAndroid Build Coastguard Worker }
236*c0909341SAndroid Build Coastguard Worker
get_poc_diff(const int order_hint_n_bits,const int poc0,const int poc1)237*c0909341SAndroid Build Coastguard Worker static inline int get_poc_diff(const int order_hint_n_bits,
238*c0909341SAndroid Build Coastguard Worker const int poc0, const int poc1)
239*c0909341SAndroid Build Coastguard Worker {
240*c0909341SAndroid Build Coastguard Worker if (!order_hint_n_bits) return 0;
241*c0909341SAndroid Build Coastguard Worker const int mask = 1 << (order_hint_n_bits - 1);
242*c0909341SAndroid Build Coastguard Worker const int diff = poc0 - poc1;
243*c0909341SAndroid Build Coastguard Worker return (diff & (mask - 1)) - (diff & mask);
244*c0909341SAndroid Build Coastguard Worker }
245*c0909341SAndroid Build Coastguard Worker
get_jnt_comp_ctx(const int order_hint_n_bits,const unsigned poc,const unsigned ref0poc,const unsigned ref1poc,const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4)246*c0909341SAndroid Build Coastguard Worker static inline int get_jnt_comp_ctx(const int order_hint_n_bits,
247*c0909341SAndroid Build Coastguard Worker const unsigned poc, const unsigned ref0poc,
248*c0909341SAndroid Build Coastguard Worker const unsigned ref1poc,
249*c0909341SAndroid Build Coastguard Worker const BlockContext *const a,
250*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
251*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4)
252*c0909341SAndroid Build Coastguard Worker {
253*c0909341SAndroid Build Coastguard Worker const unsigned d0 = abs(get_poc_diff(order_hint_n_bits, ref0poc, poc));
254*c0909341SAndroid Build Coastguard Worker const unsigned d1 = abs(get_poc_diff(order_hint_n_bits, poc, ref1poc));
255*c0909341SAndroid Build Coastguard Worker const int offset = d0 == d1;
256*c0909341SAndroid Build Coastguard Worker const int a_ctx = a->comp_type[xb4] >= COMP_INTER_AVG ||
257*c0909341SAndroid Build Coastguard Worker a->ref[0][xb4] == 6;
258*c0909341SAndroid Build Coastguard Worker const int l_ctx = l->comp_type[yb4] >= COMP_INTER_AVG ||
259*c0909341SAndroid Build Coastguard Worker l->ref[0][yb4] == 6;
260*c0909341SAndroid Build Coastguard Worker
261*c0909341SAndroid Build Coastguard Worker return 3 * offset + a_ctx + l_ctx;
262*c0909341SAndroid Build Coastguard Worker }
263*c0909341SAndroid Build Coastguard Worker
get_mask_comp_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4)264*c0909341SAndroid Build Coastguard Worker static inline int get_mask_comp_ctx(const BlockContext *const a,
265*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
266*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4)
267*c0909341SAndroid Build Coastguard Worker {
268*c0909341SAndroid Build Coastguard Worker const int a_ctx = a->comp_type[xb4] >= COMP_INTER_SEG ? 1 :
269*c0909341SAndroid Build Coastguard Worker a->ref[0][xb4] == 6 ? 3 : 0;
270*c0909341SAndroid Build Coastguard Worker const int l_ctx = l->comp_type[yb4] >= COMP_INTER_SEG ? 1 :
271*c0909341SAndroid Build Coastguard Worker l->ref[0][yb4] == 6 ? 3 : 0;
272*c0909341SAndroid Build Coastguard Worker
273*c0909341SAndroid Build Coastguard Worker return imin(a_ctx + l_ctx, 5);
274*c0909341SAndroid Build Coastguard Worker }
275*c0909341SAndroid Build Coastguard Worker
276*c0909341SAndroid Build Coastguard Worker #define av1_get_ref_2_ctx av1_get_bwd_ref_ctx
277*c0909341SAndroid Build Coastguard Worker #define av1_get_ref_3_ctx av1_get_fwd_ref_ctx
278*c0909341SAndroid Build Coastguard Worker #define av1_get_ref_4_ctx av1_get_fwd_ref_1_ctx
279*c0909341SAndroid Build Coastguard Worker #define av1_get_ref_5_ctx av1_get_fwd_ref_2_ctx
280*c0909341SAndroid Build Coastguard Worker #define av1_get_ref_6_ctx av1_get_bwd_ref_1_ctx
281*c0909341SAndroid Build Coastguard Worker #define av1_get_uni_p_ctx av1_get_ref_ctx
282*c0909341SAndroid Build Coastguard Worker #define av1_get_uni_p2_ctx av1_get_fwd_ref_2_ctx
283*c0909341SAndroid Build Coastguard Worker
av1_get_ref_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,int have_top,int have_left)284*c0909341SAndroid Build Coastguard Worker static inline int av1_get_ref_ctx(const BlockContext *const a,
285*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
286*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
287*c0909341SAndroid Build Coastguard Worker int have_top, int have_left)
288*c0909341SAndroid Build Coastguard Worker {
289*c0909341SAndroid Build Coastguard Worker int cnt[2] = { 0 };
290*c0909341SAndroid Build Coastguard Worker
291*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
292*c0909341SAndroid Build Coastguard Worker cnt[a->ref[0][xb4] >= 4]++;
293*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4]) cnt[a->ref[1][xb4] >= 4]++;
294*c0909341SAndroid Build Coastguard Worker }
295*c0909341SAndroid Build Coastguard Worker
296*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
297*c0909341SAndroid Build Coastguard Worker cnt[l->ref[0][yb4] >= 4]++;
298*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4]) cnt[l->ref[1][yb4] >= 4]++;
299*c0909341SAndroid Build Coastguard Worker }
300*c0909341SAndroid Build Coastguard Worker
301*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
302*c0909341SAndroid Build Coastguard Worker }
303*c0909341SAndroid Build Coastguard Worker
av1_get_fwd_ref_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)304*c0909341SAndroid Build Coastguard Worker static inline int av1_get_fwd_ref_ctx(const BlockContext *const a,
305*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
306*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
307*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
308*c0909341SAndroid Build Coastguard Worker {
309*c0909341SAndroid Build Coastguard Worker int cnt[4] = { 0 };
310*c0909341SAndroid Build Coastguard Worker
311*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
312*c0909341SAndroid Build Coastguard Worker if (a->ref[0][xb4] < 4) cnt[a->ref[0][xb4]]++;
313*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && a->ref[1][xb4] < 4) cnt[a->ref[1][xb4]]++;
314*c0909341SAndroid Build Coastguard Worker }
315*c0909341SAndroid Build Coastguard Worker
316*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
317*c0909341SAndroid Build Coastguard Worker if (l->ref[0][yb4] < 4) cnt[l->ref[0][yb4]]++;
318*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && l->ref[1][yb4] < 4) cnt[l->ref[1][yb4]]++;
319*c0909341SAndroid Build Coastguard Worker }
320*c0909341SAndroid Build Coastguard Worker
321*c0909341SAndroid Build Coastguard Worker cnt[0] += cnt[1];
322*c0909341SAndroid Build Coastguard Worker cnt[2] += cnt[3];
323*c0909341SAndroid Build Coastguard Worker
324*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[2] ? 1 : cnt[0] < cnt[2] ? 0 : 2;
325*c0909341SAndroid Build Coastguard Worker }
326*c0909341SAndroid Build Coastguard Worker
av1_get_fwd_ref_1_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)327*c0909341SAndroid Build Coastguard Worker static inline int av1_get_fwd_ref_1_ctx(const BlockContext *const a,
328*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
329*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
330*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
331*c0909341SAndroid Build Coastguard Worker {
332*c0909341SAndroid Build Coastguard Worker int cnt[2] = { 0 };
333*c0909341SAndroid Build Coastguard Worker
334*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
335*c0909341SAndroid Build Coastguard Worker if (a->ref[0][xb4] < 2) cnt[a->ref[0][xb4]]++;
336*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && a->ref[1][xb4] < 2) cnt[a->ref[1][xb4]]++;
337*c0909341SAndroid Build Coastguard Worker }
338*c0909341SAndroid Build Coastguard Worker
339*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
340*c0909341SAndroid Build Coastguard Worker if (l->ref[0][yb4] < 2) cnt[l->ref[0][yb4]]++;
341*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && l->ref[1][yb4] < 2) cnt[l->ref[1][yb4]]++;
342*c0909341SAndroid Build Coastguard Worker }
343*c0909341SAndroid Build Coastguard Worker
344*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
345*c0909341SAndroid Build Coastguard Worker }
346*c0909341SAndroid Build Coastguard Worker
av1_get_fwd_ref_2_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)347*c0909341SAndroid Build Coastguard Worker static inline int av1_get_fwd_ref_2_ctx(const BlockContext *const a,
348*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
349*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
350*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
351*c0909341SAndroid Build Coastguard Worker {
352*c0909341SAndroid Build Coastguard Worker int cnt[2] = { 0 };
353*c0909341SAndroid Build Coastguard Worker
354*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
355*c0909341SAndroid Build Coastguard Worker if ((a->ref[0][xb4] ^ 2U) < 2) cnt[a->ref[0][xb4] - 2]++;
356*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && (a->ref[1][xb4] ^ 2U) < 2) cnt[a->ref[1][xb4] - 2]++;
357*c0909341SAndroid Build Coastguard Worker }
358*c0909341SAndroid Build Coastguard Worker
359*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
360*c0909341SAndroid Build Coastguard Worker if ((l->ref[0][yb4] ^ 2U) < 2) cnt[l->ref[0][yb4] - 2]++;
361*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && (l->ref[1][yb4] ^ 2U) < 2) cnt[l->ref[1][yb4] - 2]++;
362*c0909341SAndroid Build Coastguard Worker }
363*c0909341SAndroid Build Coastguard Worker
364*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
365*c0909341SAndroid Build Coastguard Worker }
366*c0909341SAndroid Build Coastguard Worker
av1_get_bwd_ref_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)367*c0909341SAndroid Build Coastguard Worker static inline int av1_get_bwd_ref_ctx(const BlockContext *const a,
368*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
369*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
370*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
371*c0909341SAndroid Build Coastguard Worker {
372*c0909341SAndroid Build Coastguard Worker int cnt[3] = { 0 };
373*c0909341SAndroid Build Coastguard Worker
374*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
375*c0909341SAndroid Build Coastguard Worker if (a->ref[0][xb4] >= 4) cnt[a->ref[0][xb4] - 4]++;
376*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && a->ref[1][xb4] >= 4) cnt[a->ref[1][xb4] - 4]++;
377*c0909341SAndroid Build Coastguard Worker }
378*c0909341SAndroid Build Coastguard Worker
379*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
380*c0909341SAndroid Build Coastguard Worker if (l->ref[0][yb4] >= 4) cnt[l->ref[0][yb4] - 4]++;
381*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && l->ref[1][yb4] >= 4) cnt[l->ref[1][yb4] - 4]++;
382*c0909341SAndroid Build Coastguard Worker }
383*c0909341SAndroid Build Coastguard Worker
384*c0909341SAndroid Build Coastguard Worker cnt[1] += cnt[0];
385*c0909341SAndroid Build Coastguard Worker
386*c0909341SAndroid Build Coastguard Worker return cnt[2] == cnt[1] ? 1 : cnt[1] < cnt[2] ? 0 : 2;
387*c0909341SAndroid Build Coastguard Worker }
388*c0909341SAndroid Build Coastguard Worker
av1_get_bwd_ref_1_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)389*c0909341SAndroid Build Coastguard Worker static inline int av1_get_bwd_ref_1_ctx(const BlockContext *const a,
390*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
391*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
392*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
393*c0909341SAndroid Build Coastguard Worker {
394*c0909341SAndroid Build Coastguard Worker int cnt[3] = { 0 };
395*c0909341SAndroid Build Coastguard Worker
396*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
397*c0909341SAndroid Build Coastguard Worker if (a->ref[0][xb4] >= 4) cnt[a->ref[0][xb4] - 4]++;
398*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && a->ref[1][xb4] >= 4) cnt[a->ref[1][xb4] - 4]++;
399*c0909341SAndroid Build Coastguard Worker }
400*c0909341SAndroid Build Coastguard Worker
401*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
402*c0909341SAndroid Build Coastguard Worker if (l->ref[0][yb4] >= 4) cnt[l->ref[0][yb4] - 4]++;
403*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && l->ref[1][yb4] >= 4) cnt[l->ref[1][yb4] - 4]++;
404*c0909341SAndroid Build Coastguard Worker }
405*c0909341SAndroid Build Coastguard Worker
406*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
407*c0909341SAndroid Build Coastguard Worker }
408*c0909341SAndroid Build Coastguard Worker
av1_get_uni_p1_ctx(const BlockContext * const a,const BlockContext * const l,const int yb4,const int xb4,const int have_top,const int have_left)409*c0909341SAndroid Build Coastguard Worker static inline int av1_get_uni_p1_ctx(const BlockContext *const a,
410*c0909341SAndroid Build Coastguard Worker const BlockContext *const l,
411*c0909341SAndroid Build Coastguard Worker const int yb4, const int xb4,
412*c0909341SAndroid Build Coastguard Worker const int have_top, const int have_left)
413*c0909341SAndroid Build Coastguard Worker {
414*c0909341SAndroid Build Coastguard Worker int cnt[3] = { 0 };
415*c0909341SAndroid Build Coastguard Worker
416*c0909341SAndroid Build Coastguard Worker if (have_top && !a->intra[xb4]) {
417*c0909341SAndroid Build Coastguard Worker if (a->ref[0][xb4] - 1U < 3) cnt[a->ref[0][xb4] - 1]++;
418*c0909341SAndroid Build Coastguard Worker if (a->comp_type[xb4] && a->ref[1][xb4] - 1U < 3) cnt[a->ref[1][xb4] - 1]++;
419*c0909341SAndroid Build Coastguard Worker }
420*c0909341SAndroid Build Coastguard Worker
421*c0909341SAndroid Build Coastguard Worker if (have_left && !l->intra[yb4]) {
422*c0909341SAndroid Build Coastguard Worker if (l->ref[0][yb4] - 1U < 3) cnt[l->ref[0][yb4] - 1]++;
423*c0909341SAndroid Build Coastguard Worker if (l->comp_type[yb4] && l->ref[1][yb4] - 1U < 3) cnt[l->ref[1][yb4] - 1]++;
424*c0909341SAndroid Build Coastguard Worker }
425*c0909341SAndroid Build Coastguard Worker
426*c0909341SAndroid Build Coastguard Worker cnt[1] += cnt[2];
427*c0909341SAndroid Build Coastguard Worker
428*c0909341SAndroid Build Coastguard Worker return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
429*c0909341SAndroid Build Coastguard Worker }
430*c0909341SAndroid Build Coastguard Worker
get_drl_context(const refmvs_candidate * const ref_mv_stack,const int ref_idx)431*c0909341SAndroid Build Coastguard Worker static inline int get_drl_context(const refmvs_candidate *const ref_mv_stack,
432*c0909341SAndroid Build Coastguard Worker const int ref_idx)
433*c0909341SAndroid Build Coastguard Worker {
434*c0909341SAndroid Build Coastguard Worker if (ref_mv_stack[ref_idx].weight >= 640)
435*c0909341SAndroid Build Coastguard Worker return ref_mv_stack[ref_idx + 1].weight < 640;
436*c0909341SAndroid Build Coastguard Worker
437*c0909341SAndroid Build Coastguard Worker return ref_mv_stack[ref_idx + 1].weight < 640 ? 2 : 0;
438*c0909341SAndroid Build Coastguard Worker }
439*c0909341SAndroid Build Coastguard Worker
get_cur_frame_segid(const int by,const int bx,const int have_top,const int have_left,int * const seg_ctx,const uint8_t * cur_seg_map,const ptrdiff_t stride)440*c0909341SAndroid Build Coastguard Worker static inline unsigned get_cur_frame_segid(const int by, const int bx,
441*c0909341SAndroid Build Coastguard Worker const int have_top,
442*c0909341SAndroid Build Coastguard Worker const int have_left,
443*c0909341SAndroid Build Coastguard Worker int *const seg_ctx,
444*c0909341SAndroid Build Coastguard Worker const uint8_t *cur_seg_map,
445*c0909341SAndroid Build Coastguard Worker const ptrdiff_t stride)
446*c0909341SAndroid Build Coastguard Worker {
447*c0909341SAndroid Build Coastguard Worker cur_seg_map += bx + by * stride;
448*c0909341SAndroid Build Coastguard Worker if (have_left && have_top) {
449*c0909341SAndroid Build Coastguard Worker const int l = cur_seg_map[-1];
450*c0909341SAndroid Build Coastguard Worker const int a = cur_seg_map[-stride];
451*c0909341SAndroid Build Coastguard Worker const int al = cur_seg_map[-(stride + 1)];
452*c0909341SAndroid Build Coastguard Worker
453*c0909341SAndroid Build Coastguard Worker if (l == a && al == l) *seg_ctx = 2;
454*c0909341SAndroid Build Coastguard Worker else if (l == a || al == l || a == al) *seg_ctx = 1;
455*c0909341SAndroid Build Coastguard Worker else *seg_ctx = 0;
456*c0909341SAndroid Build Coastguard Worker return a == al ? a : l;
457*c0909341SAndroid Build Coastguard Worker } else {
458*c0909341SAndroid Build Coastguard Worker *seg_ctx = 0;
459*c0909341SAndroid Build Coastguard Worker return have_left ? cur_seg_map[-1] : have_top ? cur_seg_map[-stride] : 0;
460*c0909341SAndroid Build Coastguard Worker }
461*c0909341SAndroid Build Coastguard Worker }
462*c0909341SAndroid Build Coastguard Worker
fix_int_mv_precision(mv * const mv)463*c0909341SAndroid Build Coastguard Worker static inline void fix_int_mv_precision(mv *const mv) {
464*c0909341SAndroid Build Coastguard Worker mv->x = (mv->x - (mv->x >> 15) + 3) & ~7U;
465*c0909341SAndroid Build Coastguard Worker mv->y = (mv->y - (mv->y >> 15) + 3) & ~7U;
466*c0909341SAndroid Build Coastguard Worker }
467*c0909341SAndroid Build Coastguard Worker
fix_mv_precision(const Dav1dFrameHeader * const hdr,mv * const mv)468*c0909341SAndroid Build Coastguard Worker static inline void fix_mv_precision(const Dav1dFrameHeader *const hdr,
469*c0909341SAndroid Build Coastguard Worker mv *const mv)
470*c0909341SAndroid Build Coastguard Worker {
471*c0909341SAndroid Build Coastguard Worker if (hdr->force_integer_mv) {
472*c0909341SAndroid Build Coastguard Worker fix_int_mv_precision(mv);
473*c0909341SAndroid Build Coastguard Worker } else if (!hdr->hp) {
474*c0909341SAndroid Build Coastguard Worker mv->x = (mv->x - (mv->x >> 15)) & ~1U;
475*c0909341SAndroid Build Coastguard Worker mv->y = (mv->y - (mv->y >> 15)) & ~1U;
476*c0909341SAndroid Build Coastguard Worker }
477*c0909341SAndroid Build Coastguard Worker }
478*c0909341SAndroid Build Coastguard Worker
get_gmv_2d(const Dav1dWarpedMotionParams * const gmv,const int bx4,const int by4,const int bw4,const int bh4,const Dav1dFrameHeader * const hdr)479*c0909341SAndroid Build Coastguard Worker static inline mv get_gmv_2d(const Dav1dWarpedMotionParams *const gmv,
480*c0909341SAndroid Build Coastguard Worker const int bx4, const int by4,
481*c0909341SAndroid Build Coastguard Worker const int bw4, const int bh4,
482*c0909341SAndroid Build Coastguard Worker const Dav1dFrameHeader *const hdr)
483*c0909341SAndroid Build Coastguard Worker {
484*c0909341SAndroid Build Coastguard Worker switch (gmv->type) {
485*c0909341SAndroid Build Coastguard Worker case DAV1D_WM_TYPE_ROT_ZOOM:
486*c0909341SAndroid Build Coastguard Worker assert(gmv->matrix[5] == gmv->matrix[2]);
487*c0909341SAndroid Build Coastguard Worker assert(gmv->matrix[4] == -gmv->matrix[3]);
488*c0909341SAndroid Build Coastguard Worker // fall-through
489*c0909341SAndroid Build Coastguard Worker default:
490*c0909341SAndroid Build Coastguard Worker case DAV1D_WM_TYPE_AFFINE: {
491*c0909341SAndroid Build Coastguard Worker const int x = bx4 * 4 + bw4 * 2 - 1;
492*c0909341SAndroid Build Coastguard Worker const int y = by4 * 4 + bh4 * 2 - 1;
493*c0909341SAndroid Build Coastguard Worker const int xc = (gmv->matrix[2] - (1 << 16)) * x +
494*c0909341SAndroid Build Coastguard Worker gmv->matrix[3] * y + gmv->matrix[0];
495*c0909341SAndroid Build Coastguard Worker const int yc = (gmv->matrix[5] - (1 << 16)) * y +
496*c0909341SAndroid Build Coastguard Worker gmv->matrix[4] * x + gmv->matrix[1];
497*c0909341SAndroid Build Coastguard Worker const int shift = 16 - (3 - !hdr->hp);
498*c0909341SAndroid Build Coastguard Worker const int round = (1 << shift) >> 1;
499*c0909341SAndroid Build Coastguard Worker mv res = (mv) {
500*c0909341SAndroid Build Coastguard Worker .y = apply_sign(((abs(yc) + round) >> shift) << !hdr->hp, yc),
501*c0909341SAndroid Build Coastguard Worker .x = apply_sign(((abs(xc) + round) >> shift) << !hdr->hp, xc),
502*c0909341SAndroid Build Coastguard Worker };
503*c0909341SAndroid Build Coastguard Worker if (hdr->force_integer_mv)
504*c0909341SAndroid Build Coastguard Worker fix_int_mv_precision(&res);
505*c0909341SAndroid Build Coastguard Worker return res;
506*c0909341SAndroid Build Coastguard Worker }
507*c0909341SAndroid Build Coastguard Worker case DAV1D_WM_TYPE_TRANSLATION: {
508*c0909341SAndroid Build Coastguard Worker mv res = (mv) {
509*c0909341SAndroid Build Coastguard Worker .y = gmv->matrix[0] >> 13,
510*c0909341SAndroid Build Coastguard Worker .x = gmv->matrix[1] >> 13,
511*c0909341SAndroid Build Coastguard Worker };
512*c0909341SAndroid Build Coastguard Worker if (hdr->force_integer_mv)
513*c0909341SAndroid Build Coastguard Worker fix_int_mv_precision(&res);
514*c0909341SAndroid Build Coastguard Worker return res;
515*c0909341SAndroid Build Coastguard Worker }
516*c0909341SAndroid Build Coastguard Worker case DAV1D_WM_TYPE_IDENTITY:
517*c0909341SAndroid Build Coastguard Worker return (mv) { .x = 0, .y = 0 };
518*c0909341SAndroid Build Coastguard Worker }
519*c0909341SAndroid Build Coastguard Worker }
520*c0909341SAndroid Build Coastguard Worker
521*c0909341SAndroid Build Coastguard Worker #endif /* DAV1D_SRC_ENV_H */
522