FFmpeg
vp9mvs.c
Go to the documentation of this file.
1 /*
2  * VP9 compatible video decoder
3  *
4  * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
5  * Copyright (C) 2013 Clément Bœsch <u pkh me>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "internal.h"
25 #include "vp56.h"
26 #include "vp9.h"
27 #include "vp9data.h"
28 #include "vp9dec.h"
29 
30 static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
31  VP9TileData *td)
32 {
33  dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x);
34  dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y);
35 }
36 
38  VP56mv *pmv, int ref, int z, int idx, int sb)
39 {
40  static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
41  [BS_64x64] = { { 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 },
42  { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 } },
43  [BS_64x32] = { { 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 },
44  { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 } },
45  [BS_32x64] = { { -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 },
46  { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 } },
47  [BS_32x32] = { { 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 },
48  { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
49  [BS_32x16] = { { 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 },
50  { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
51  [BS_16x32] = { { -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 },
52  { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 } },
53  [BS_16x16] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 },
54  { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
55  [BS_16x8] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 },
56  { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 } },
57  [BS_8x16] = { { -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 },
58  { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 } },
59  [BS_8x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
60  { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
61  [BS_8x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
62  { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
63  [BS_4x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
64  { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
65  [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
66  { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
67  };
68  VP9Context *s = td->s;
69  VP9Block *b = td->b;
70  int row = td->row, col = td->col, row7 = td->row7;
71  const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
72 #define INVALID_MV 0x80008000U
73  uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV;
74  int i;
75 
76 #define RETURN_DIRECT_MV(mv) \
77  do { \
78  uint32_t m = AV_RN32A(&mv); \
79  if (!idx) { \
80  AV_WN32A(pmv, m); \
81  return; \
82  } else if (mem == INVALID_MV) { \
83  mem = m; \
84  } else if (m != mem) { \
85  AV_WN32A(pmv, m); \
86  return; \
87  } \
88  } while (0)
89 
90  if (sb >= 0) {
91  if (sb == 2 || sb == 1) {
92  RETURN_DIRECT_MV(b->mv[0][z]);
93  } else if (sb == 3) {
94  RETURN_DIRECT_MV(b->mv[2][z]);
95  RETURN_DIRECT_MV(b->mv[1][z]);
96  RETURN_DIRECT_MV(b->mv[0][z]);
97  }
98 
99 #define RETURN_MV(mv) \
100  do { \
101  if (sb > 0) { \
102  VP56mv tmp; \
103  uint32_t m; \
104  av_assert2(idx == 1); \
105  av_assert2(mem != INVALID_MV); \
106  if (mem_sub8x8 == INVALID_MV) { \
107  clamp_mv(&tmp, &mv, td); \
108  m = AV_RN32A(&tmp); \
109  if (m != mem) { \
110  AV_WN32A(pmv, m); \
111  return; \
112  } \
113  mem_sub8x8 = AV_RN32A(&mv); \
114  } else if (mem_sub8x8 != AV_RN32A(&mv)) { \
115  clamp_mv(&tmp, &mv, td); \
116  m = AV_RN32A(&tmp); \
117  if (m != mem) { \
118  AV_WN32A(pmv, m); \
119  } else { \
120  /* BUG I'm pretty sure this isn't the intention */ \
121  AV_WN32A(pmv, 0); \
122  } \
123  return; \
124  } \
125  } else { \
126  uint32_t m = AV_RN32A(&mv); \
127  if (!idx) { \
128  clamp_mv(pmv, &mv, td); \
129  return; \
130  } else if (mem == INVALID_MV) { \
131  mem = m; \
132  } else if (m != mem) { \
133  clamp_mv(pmv, &mv, td); \
134  return; \
135  } \
136  } \
137  } while (0)
138 
139  if (row > 0) {
140  VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
141  if (mv->ref[0] == ref)
142  RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
143  else if (mv->ref[1] == ref)
144  RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
145  }
146  if (col > td->tile_col_start) {
147  VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
148  if (mv->ref[0] == ref)
149  RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
150  else if (mv->ref[1] == ref)
151  RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
152  }
153  i = 2;
154  } else {
155  i = 0;
156  }
157 
158  // previously coded MVs in this neighborhood, using same reference frame
159  for (; i < 8; i++) {
160  int c = p[i][0] + col, r = p[i][1] + row;
161 
162  if (c >= td->tile_col_start && c < s->cols &&
163  r >= 0 && r < s->rows) {
164  VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
165 
166  if (mv->ref[0] == ref)
167  RETURN_MV(mv->mv[0]);
168  else if (mv->ref[1] == ref)
169  RETURN_MV(mv->mv[1]);
170  }
171  }
172 
173  // MV at this position in previous frame, using same reference frame
174  if (s->s.h.use_last_frame_mvs) {
175  VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
176 
179  if (mv->ref[0] == ref)
180  RETURN_MV(mv->mv[0]);
181  else if (mv->ref[1] == ref)
182  RETURN_MV(mv->mv[1]);
183  }
184 
185 #define RETURN_SCALE_MV(mv, scale) \
186  do { \
187  if (scale) { \
188  VP56mv mv_temp = { -mv.x, -mv.y }; \
189  RETURN_MV(mv_temp); \
190  } else { \
191  RETURN_MV(mv); \
192  } \
193  } while (0)
194 
195  // previously coded MVs in this neighborhood, using different reference frame
196  for (i = 0; i < 8; i++) {
197  int c = p[i][0] + col, r = p[i][1] + row;
198 
199  if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
200  VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
201 
202  if (mv->ref[0] != ref && mv->ref[0] >= 0)
203  RETURN_SCALE_MV(mv->mv[0],
204  s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
205  if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
206  // BUG - libvpx has this condition regardless of whether
207  // we used the first ref MV and pre-scaling
208  AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
209  RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]);
210  }
211  }
212  }
213 
214  // MV at this position in previous frame, using different reference frame
215  if (s->s.h.use_last_frame_mvs) {
216  VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
217 
218  // no need to await_progress, because we already did that above
219  if (mv->ref[0] != ref && mv->ref[0] >= 0)
220  RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
221  if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
222  // BUG - libvpx has this condition regardless of whether
223  // we used the first ref MV and pre-scaling
224  AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
225  RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]);
226  }
227  }
228 
229  AV_ZERO32(pmv);
230  clamp_mv(pmv, pmv, td);
231 #undef INVALID_MV
232 #undef RETURN_MV
233 #undef RETURN_SCALE_MV
234 }
235 
236 static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp)
237 {
238  VP9Context *s = td->s;
239  int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign);
241  s->prob.p.mv_comp[idx].classes);
242 
243  td->counts.mv_comp[idx].sign[sign]++;
244  td->counts.mv_comp[idx].classes[c]++;
245  if (c) {
246  int m;
247 
248  for (n = 0, m = 0; m < c; m++) {
249  bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]);
250  n |= bit << m;
251  td->counts.mv_comp[idx].bits[m][bit]++;
252  }
253  n <<= 3;
255  s->prob.p.mv_comp[idx].fp);
256  n |= bit << 1;
257  td->counts.mv_comp[idx].fp[bit]++;
258  if (hp) {
259  bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp);
260  td->counts.mv_comp[idx].hp[bit]++;
261  n |= bit;
262  } else {
263  n |= 1;
264  // bug in libvpx - we count for bw entropy purposes even if the
265  // bit wasn't coded
266  td->counts.mv_comp[idx].hp[1]++;
267  }
268  n += 8 << c;
269  } else {
270  n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0);
271  td->counts.mv_comp[idx].class0[n]++;
273  s->prob.p.mv_comp[idx].class0_fp[n]);
274  td->counts.mv_comp[idx].class0_fp[n][bit]++;
275  n = (n << 3) | (bit << 1);
276  if (hp) {
277  bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp);
278  td->counts.mv_comp[idx].class0_hp[bit]++;
279  n |= bit;
280  } else {
281  n |= 1;
282  // bug in libvpx - we count for bw entropy purposes even if the
283  // bit wasn't coded
284  td->counts.mv_comp[idx].class0_hp[1]++;
285  }
286  }
287 
288  return sign ? -(n + 1) : (n + 1);
289 }
290 
291 void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb)
292 {
293  VP9Context *s = td->s;
294  VP9Block *b = td->b;
295 
296  if (mode == ZEROMV) {
297  AV_ZERO64(mv);
298  } else {
299  int hp;
300 
301  // FIXME cache this value and reuse for other subblocks
302  find_ref_mvs(td, &mv[0], b->ref[0], 0, mode == NEARMV,
303  mode == NEWMV ? -1 : sb);
304  // FIXME maybe move this code into find_ref_mvs()
305  if ((mode == NEWMV || sb == -1) &&
306  !(hp = s->s.h.highprecisionmvs &&
307  abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
308  if (mv[0].y & 1) {
309  if (mv[0].y < 0)
310  mv[0].y++;
311  else
312  mv[0].y--;
313  }
314  if (mv[0].x & 1) {
315  if (mv[0].x < 0)
316  mv[0].x++;
317  else
318  mv[0].x--;
319  }
320  }
321  if (mode == NEWMV) {
323  s->prob.p.mv_joint);
324 
325  td->counts.mv_joint[j]++;
326  if (j >= MV_JOINT_V)
327  mv[0].y += read_mv_component(td, 0, hp);
328  if (j & 1)
329  mv[0].x += read_mv_component(td, 1, hp);
330  }
331 
332  if (b->comp) {
333  // FIXME cache this value and reuse for other subblocks
334  find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV,
335  mode == NEWMV ? -1 : sb);
336  if ((mode == NEWMV || sb == -1) &&
337  !(hp = s->s.h.highprecisionmvs &&
338  abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
339  if (mv[1].y & 1) {
340  if (mv[1].y < 0)
341  mv[1].y++;
342  else
343  mv[1].y--;
344  }
345  if (mv[1].x & 1) {
346  if (mv[1].x < 0)
347  mv[1].x++;
348  else
349  mv[1].x--;
350  }
351  }
352  if (mode == NEWMV) {
354  s->prob.p.mv_joint);
355 
356  td->counts.mv_joint[j]++;
357  if (j >= MV_JOINT_V)
358  mv[1].y += read_mv_component(td, 0, hp);
359  if (j & 1)
360  mv[1].x += read_mv_component(td, 1, hp);
361  }
362  }
363  }
364 }
ThreadFrame tf
Definition: vp9shared.h:60
const int8_t ff_vp9_mv_joint_tree[3][2]
Definition: vp9data.c:2224
static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp)
Definition: vp9mvs.c:236
VP5 and VP6 compatible video decoder (common features)
VP9Context * s
Definition: vp9dec.h:160
static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t(*tree)[2], const uint8_t *probs)
Definition: vp56.h:394
VP9BitstreamHeader h
Definition: vp9shared.h:160
ProbContext p
Definition: vp9dec.h:124
struct VP9TileData::@194 min_mv
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them.reget_buffer() and buffer age optimizations no longer work.*The contents of buffers must not be written to after ff_thread_report_progress() has been called on them.This includes draw_edges().Porting codecs to frame threading
#define src
Definition: vp8dsp.c:254
uint8_t ref[2]
Definition: vp9dec.h:80
#define RETURN_MV(mv)
const int8_t ff_vp9_mv_class_tree[10][2]
Definition: vp9data.c:2230
#define AV_RN32A(p)
Definition: intreadwrite.h:526
int16_t y
Definition: vp56.h:68
int mem
Definition: avisynth_c.h:916
VP9Frame frames[3]
Definition: vp9shared.h:166
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
int col
Definition: vp9dec.h:163
int row7
Definition: vp9dec.h:163
static void find_ref_mvs(VP9TileData *td, VP56mv *pmv, int ref, int z, int idx, int sb)
Definition: vp9mvs.c:37
uint8_t hp
Definition: vp9dec.h:68
unsigned tile_col_start
Definition: vp9dec.h:167
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define td
Definition: regdef.h:70
uint8_t sign
Definition: vp9dec.h:61
uint8_t fp[3]
Definition: vp9dec.h:66
uint8_t signbias[3]
Definition: vp9shared.h:112
const char * r
Definition: vf_curves.c:114
VP56RangeCoder * c
Definition: vp9dec.h:162
static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, VP9TileData *td)
Definition: vp9mvs.c:30
#define REF_FRAME_MVPAIR
Definition: vp9shared.h:164
struct VP9TileData::@193::@195 mv_comp[2]
#define b
Definition: input.c:41
struct VP9TileData::@194 max_mv
int uses_2pass
Definition: vp9shared.h:64
const int8_t ff_vp9_mv_fp_tree[3][2]
Definition: vp9data.c:2243
int8_t ref[2]
Definition: vp9shared.h:56
uint8_t class0_hp
Definition: vp9dec.h:67
#define s(width, name)
Definition: cbs_vp9.c:257
VP9SharedContext s
Definition: vp9dec.h:92
int n
Definition: avisynth_c.h:760
MVJoint
Definition: vp9dec.h:39
#define vp56_rac_get_prob
Definition: vp56.h:268
if(ret)
#define RETURN_SCALE_MV(mv, scale)
unsigned sb_cols
Definition: vp9dec.h:116
static const int8_t mv[256][2]
Definition: 4xm.c:77
struct VP9TileData::@193 counts
VP56mv(* above_mv_ctx)[2]
Definition: vp9dec.h:145
uint8_t class0_fp[2][3]
Definition: vp9dec.h:65
#define abs(x)
Definition: cuda_runtime.h:35
#define CUR_FRAME
Definition: vp9shared.h:163
int row
Definition: vp9dec.h:163
enum BlockSize bs
Definition: vp9dec.h:83
VP56mv mv[4][2]
Definition: vp9dec.h:82
Definition: vp56.h:66
uint8_t comp
Definition: vp9dec.h:80
uint8_t bits[10]
Definition: vp9dec.h:64
unsigned mv_joint[4]
Definition: vp9dec.h:182
#define AV_ZERO64(d)
Definition: intreadwrite.h:633
int16_t x
Definition: vp56.h:67
common internal api header.
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
#define bit(string, value)
Definition: cbs_mpeg2.c:58
#define INVALID_MV
#define RETURN_DIRECT_MV(mv)
uint8_t mv_joint[3]
Definition: vp9dec.h:59
uint8_t class0
Definition: vp9dec.h:63
#define AV_ZERO32(d)
Definition: intreadwrite.h:629
VP9mvrefPair * mv
Definition: vp9shared.h:63
struct ProbContext::@189 mv_comp[2]
uint8_t use_last_frame_mvs
Definition: vp9shared.h:110
VP9Block * b
Definition: vp9dec.h:166
#define av_always_inline
Definition: attributes.h:39
VP56mv mv[2]
Definition: vp9shared.h:55
uint8_t classes[10]
Definition: vp9dec.h:62
uint8_t highprecisionmvs
Definition: vp9shared.h:104
void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb)
Definition: vp9mvs.c:291
VP56mv left_mv_ctx[16][2]
Definition: vp9dec.h:204
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
struct VP9Context::@192 prob