FFmpeg
filter.c
Go to the documentation of this file.
1 /*
2  * HEVC video decoder
3  *
4  * Copyright (C) 2012 - 2013 Guillaume Martres
5  * Copyright (C) 2013 Seppo Tomperi
6  * Copyright (C) 2013 Wassim Hamidouche
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include "libavutil/common.h"
26 #include "libavutil/internal.h"
27 
28 #include "hevcdec.h"
29 #include "progressframe.h"
30 
31 #define LUMA 0
32 #define CB 1
33 #define CR 2
34 
35 static const uint8_t tctable[54] = {
36  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // QP 0...18
37  1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, // QP 19...37
38  5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24 // QP 38...53
39 };
40 
41 static const uint8_t betatable[52] = {
42  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, // QP 0...18
43  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, // QP 19...37
44  38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64 // QP 38...51
45 };
46 
47 static int chroma_tc(const HEVCPPS *pps, const HEVCSPS *sps,
48  int qp_y, int c_idx, int tc_offset)
49 {
50  static const int qp_c[] = {
51  29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
52  };
53  int qp, qp_i, offset, idxt;
54 
55  // slice qp offset is not used for deblocking
56  if (c_idx == 1)
57  offset = pps->cb_qp_offset;
58  else
59  offset = pps->cr_qp_offset;
60 
61  qp_i = av_clip(qp_y + offset, 0, 57);
62  if (sps->chroma_format_idc == 1) {
63  if (qp_i < 30)
64  qp = qp_i;
65  else if (qp_i > 43)
66  qp = qp_i - 6;
67  else
68  qp = qp_c[qp_i - 30];
69  } else {
70  qp = av_clip(qp_i, 0, 51);
71  }
72 
73  idxt = av_clip(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
74  return tctable[idxt];
75 }
76 
77 static int get_qPy_pred(HEVCLocalContext *lc, const HEVCContext *s,
78  const HEVCPPS *pps, const HEVCSPS *sps,
79  int xBase, int yBase, int log2_cb_size)
80 {
81  int ctb_size_mask = (1 << sps->log2_ctb_size) - 1;
82  int MinCuQpDeltaSizeMask = (1 << (sps->log2_ctb_size -
83  pps->diff_cu_qp_delta_depth)) - 1;
84  int xQgBase = xBase - (xBase & MinCuQpDeltaSizeMask);
85  int yQgBase = yBase - (yBase & MinCuQpDeltaSizeMask);
86  int min_cb_width = sps->min_cb_width;
87  int x_cb = xQgBase >> sps->log2_min_cb_size;
88  int y_cb = yQgBase >> sps->log2_min_cb_size;
89  int availableA = (xBase & ctb_size_mask) &&
90  (xQgBase & ctb_size_mask);
91  int availableB = (yBase & ctb_size_mask) &&
92  (yQgBase & ctb_size_mask);
93  int qPy_pred, qPy_a, qPy_b;
94 
95  // qPy_pred
96  if (lc->first_qp_group || (!xQgBase && !yQgBase)) {
98  qPy_pred = s->sh.slice_qp;
99  } else {
100  qPy_pred = lc->qPy_pred;
101  }
102 
103  // qPy_a
104  if (availableA == 0)
105  qPy_a = qPy_pred;
106  else
107  qPy_a = s->qp_y_tab[(x_cb - 1) + y_cb * min_cb_width];
108 
109  // qPy_b
110  if (availableB == 0)
111  qPy_b = qPy_pred;
112  else
113  qPy_b = s->qp_y_tab[x_cb + (y_cb - 1) * min_cb_width];
114 
115  av_assert2(qPy_a >= -sps->qp_bd_offset && qPy_a < 52);
116  av_assert2(qPy_b >= -sps->qp_bd_offset && qPy_b < 52);
117 
118  return (qPy_a + qPy_b + 1) >> 1;
119 }
120 
122  int xBase, int yBase, int log2_cb_size)
123 {
124  const HEVCSPS *const sps = pps->sps;
125  const HEVCContext *const s = lc->parent;
126  int qp_y = get_qPy_pred(lc, s, pps, sps, xBase, yBase, log2_cb_size);
127 
128  if (lc->tu.cu_qp_delta != 0) {
129  int off = sps->qp_bd_offset;
130  lc->qp_y = FFUMOD(qp_y + lc->tu.cu_qp_delta + 52 + 2 * off,
131  52 + off) - off;
132  } else
133  lc->qp_y = qp_y;
134 }
135 
136 static int get_qPy(const HEVCSPS *sps, const int8_t *qp_y_tab, int xC, int yC)
137 {
138  int log2_min_cb_size = sps->log2_min_cb_size;
139  int x = xC >> log2_min_cb_size;
140  int y = yC >> log2_min_cb_size;
141  return qp_y_tab[x + y * sps->min_cb_width];
142 }
143 
144 static void copy_CTB(uint8_t *dst, const uint8_t *src, int width, int height,
145  ptrdiff_t stride_dst, ptrdiff_t stride_src)
146 {
147  int i, j;
148 
149  if (((intptr_t)dst | (intptr_t)src | stride_dst | stride_src) & 15) {
150  for (i = 0; i < height; i++) {
151  for (j = 0; j < width - 7; j+=8)
152  AV_COPY64U(dst+j, src+j);
153  dst += stride_dst;
154  src += stride_src;
155  }
156  if (width&7) {
157  dst += ((width>>3)<<3) - stride_dst * height;
158  src += ((width>>3)<<3) - stride_src * height;
159  width &= 7;
160  for (i = 0; i < height; i++) {
161  for (j = 0; j < width; j++)
162  dst[j] = src[j];
163  dst += stride_dst;
164  src += stride_src;
165  }
166  }
167  } else {
168  for (i = 0; i < height; i++) {
169  for (j = 0; j < width; j+=16)
170  AV_COPY128(dst+j, src+j);
171  dst += stride_dst;
172  src += stride_src;
173  }
174  }
175 }
176 
177 static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
178 {
179  if (pixel_shift)
180  *(uint16_t *)dst = *(uint16_t *)src;
181  else
182  *dst = *src;
183 }
184 
185 static void copy_vert(uint8_t *dst, const uint8_t *src,
186  int pixel_shift, int height,
187  ptrdiff_t stride_dst, ptrdiff_t stride_src)
188 {
189  int i;
190  if (pixel_shift == 0) {
191  for (i = 0; i < height; i++) {
192  *dst = *src;
193  dst += stride_dst;
194  src += stride_src;
195  }
196  } else {
197  for (i = 0; i < height; i++) {
198  *(uint16_t *)dst = *(uint16_t *)src;
199  dst += stride_dst;
200  src += stride_src;
201  }
202  }
203 }
204 
205 static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps,
206  const uint8_t *src,
207  ptrdiff_t stride_src, int x, int y, int width, int height,
208  int c_idx, int x_ctb, int y_ctb)
209 {
210  int sh = sps->pixel_shift;
211  int w = sps->width >> sps->hshift[c_idx];
212  int h = sps->height >> sps->vshift[c_idx];
213 
214  /* copy horizontal edges */
215  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
216  src, width << sh);
217  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
218  src + stride_src * (height - 1), width << sh);
219 
220  /* copy vertical edges */
221  copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
222 
223  copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src);
224 }
225 
226 static void restore_tqb_pixels(const HEVCContext *s,
227  const HEVCPPS *pps, const HEVCSPS *sps,
228  uint8_t *src1, const uint8_t *dst1,
229  ptrdiff_t stride_src, ptrdiff_t stride_dst,
230  int x0, int y0, int width, int height, int c_idx)
231 {
232  if (pps->transquant_bypass_enable_flag ||
233  (sps->pcm_loop_filter_disabled && sps->pcm_enabled)) {
234  int x, y;
235  int min_pu_size = 1 << sps->log2_min_pu_size;
236  int hshift = sps->hshift[c_idx];
237  int vshift = sps->vshift[c_idx];
238  int x_min = ((x0 ) >> sps->log2_min_pu_size);
239  int y_min = ((y0 ) >> sps->log2_min_pu_size);
240  int x_max = ((x0 + width ) >> sps->log2_min_pu_size);
241  int y_max = ((y0 + height) >> sps->log2_min_pu_size);
242  int len = (min_pu_size >> hshift) << sps->pixel_shift;
243  for (y = y_min; y < y_max; y++) {
244  for (x = x_min; x < x_max; x++) {
245  if (s->is_pcm[y * sps->min_pu_width + x]) {
246  int n;
247  uint8_t *src = src1 +
248  (((y << sps->log2_min_pu_size) - y0) >> vshift) * stride_src +
249  ((((x << sps->log2_min_pu_size) - x0) >> hshift) << sps->pixel_shift);
250  const uint8_t *dst = dst1 +
251  (((y << sps->log2_min_pu_size) - y0) >> vshift) * stride_dst +
252  ((((x << sps->log2_min_pu_size) - x0) >> hshift) << sps->pixel_shift);
253 
254  for (n = 0; n < (min_pu_size >> vshift); n++) {
255  memcpy(src, dst, len);
256  src += stride_src;
257  dst += stride_dst;
258  }
259  }
260  }
261  }
262  }
263 }
264 
265 #define CTB(tab, x, y) ((tab)[(y) * sps->ctb_width + (x)])
266 
268  const HEVCPPS *pps, const HEVCSPS *sps,
269  int x, int y)
270 {
271  static const uint8_t sao_tab[8] = { 0, 1, 2, 2, 3, 3, 4, 4 };
272  int c_idx;
273  int edges[4]; // 0 left 1 top 2 right 3 bottom
274  int x_ctb = x >> sps->log2_ctb_size;
275  int y_ctb = y >> sps->log2_ctb_size;
276  int ctb_addr_rs = y_ctb * sps->ctb_width + x_ctb;
277  int ctb_addr_ts = pps->ctb_addr_rs_to_ts[ctb_addr_rs];
278  SAOParams *sao = &CTB(s->sao, x_ctb, y_ctb);
279  // flags indicating unfilterable edges
280  uint8_t vert_edge[] = { 0, 0 };
281  uint8_t horiz_edge[] = { 0, 0 };
282  uint8_t diag_edge[] = { 0, 0, 0, 0 };
283  uint8_t lfase = CTB(s->filter_slice_edges, x_ctb, y_ctb);
284  uint8_t no_tile_filter = pps->tiles_enabled_flag &&
285  !pps->loop_filter_across_tiles_enabled_flag;
286  uint8_t restore = no_tile_filter || !lfase;
287  uint8_t left_tile_edge = 0;
288  uint8_t right_tile_edge = 0;
289  uint8_t up_tile_edge = 0;
290  uint8_t bottom_tile_edge = 0;
291 
292  edges[0] = x_ctb == 0;
293  edges[1] = y_ctb == 0;
294  edges[2] = x_ctb == sps->ctb_width - 1;
295  edges[3] = y_ctb == sps->ctb_height - 1;
296 
297  if (restore) {
298  if (!edges[0]) {
299  left_tile_edge = no_tile_filter && pps->tile_id[ctb_addr_ts] != pps->tile_id[pps->ctb_addr_rs_to_ts[ctb_addr_rs-1]];
300  vert_edge[0] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb)) || left_tile_edge;
301  }
302  if (!edges[2]) {
303  right_tile_edge = no_tile_filter && pps->tile_id[ctb_addr_ts] != pps->tile_id[pps->ctb_addr_rs_to_ts[ctb_addr_rs+1]];
304  vert_edge[1] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb + 1, y_ctb)) || right_tile_edge;
305  }
306  if (!edges[1]) {
307  up_tile_edge = no_tile_filter && pps->tile_id[ctb_addr_ts] != pps->tile_id[pps->ctb_addr_rs_to_ts[ctb_addr_rs - sps->ctb_width]];
308  horiz_edge[0] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) || up_tile_edge;
309  }
310  if (!edges[3]) {
311  bottom_tile_edge = no_tile_filter && pps->tile_id[ctb_addr_ts] != pps->tile_id[pps->ctb_addr_rs_to_ts[ctb_addr_rs + sps->ctb_width]];
312  horiz_edge[1] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb, y_ctb + 1)) || bottom_tile_edge;
313  }
314  if (!edges[0] && !edges[1]) {
315  diag_edge[0] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || left_tile_edge || up_tile_edge;
316  }
317  if (!edges[1] && !edges[2]) {
318  diag_edge[1] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb + 1, y_ctb - 1)) || right_tile_edge || up_tile_edge;
319  }
320  if (!edges[2] && !edges[3]) {
321  diag_edge[2] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb + 1, y_ctb + 1)) || right_tile_edge || bottom_tile_edge;
322  }
323  if (!edges[0] && !edges[3]) {
324  diag_edge[3] = (!lfase && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb + 1)) || left_tile_edge || bottom_tile_edge;
325  }
326  }
327 
328  for (c_idx = 0; c_idx < (sps->chroma_format_idc ? 3 : 1); c_idx++) {
329  int x0 = x >> sps->hshift[c_idx];
330  int y0 = y >> sps->vshift[c_idx];
331  ptrdiff_t stride_src = s->cur_frame->f->linesize[c_idx];
332  int ctb_size_h = (1 << (sps->log2_ctb_size)) >> sps->hshift[c_idx];
333  int ctb_size_v = (1 << (sps->log2_ctb_size)) >> sps->vshift[c_idx];
334  int width = FFMIN(ctb_size_h, (sps->width >> sps->hshift[c_idx]) - x0);
335  int height = FFMIN(ctb_size_v, (sps->height >> sps->vshift[c_idx]) - y0);
336  int tab = sao_tab[(FFALIGN(width, 8) >> 3) - 1];
337  uint8_t *src = &s->cur_frame->f->data[c_idx][y0 * stride_src + (x0 << sps->pixel_shift)];
338  ptrdiff_t stride_dst;
339  uint8_t *dst;
340 
341  switch (sao->type_idx[c_idx]) {
342  case SAO_BAND:
343  copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx,
344  x_ctb, y_ctb);
345  if (pps->transquant_bypass_enable_flag ||
346  (sps->pcm_loop_filter_disabled && sps->pcm_enabled)) {
347  dst = lc->edge_emu_buffer;
348  stride_dst = 2*MAX_PB_SIZE;
349  copy_CTB(dst, src, width << sps->pixel_shift, height, stride_dst, stride_src);
350  s->hevcdsp.sao_band_filter[tab](src, dst, stride_src, stride_dst,
351  sao->offset_val[c_idx], sao->band_position[c_idx],
352  width, height);
353  restore_tqb_pixels(s, pps, sps, src, dst, stride_src, stride_dst,
354  x, y, width, height, c_idx);
355  } else {
356  s->hevcdsp.sao_band_filter[tab](src, src, stride_src, stride_src,
357  sao->offset_val[c_idx], sao->band_position[c_idx],
358  width, height);
359  }
360  sao->type_idx[c_idx] = SAO_APPLIED;
361  break;
362  case SAO_EDGE:
363  {
364  int w = sps->width >> sps->hshift[c_idx];
365  int h = sps->height >> sps->vshift[c_idx];
366  int left_edge = edges[0];
367  int top_edge = edges[1];
368  int right_edge = edges[2];
369  int bottom_edge = edges[3];
370  int sh = sps->pixel_shift;
371  int left_pixels, right_pixels;
372 
373  stride_dst = 2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE;
374  dst = lc->edge_emu_buffer + stride_dst + AV_INPUT_BUFFER_PADDING_SIZE;
375 
376  if (!top_edge) {
377  int left = 1 - left_edge;
378  int right = 1 - right_edge;
379  const uint8_t *src1[2];
380  uint8_t *dst1;
381  int src_idx, pos;
382 
383  dst1 = dst - stride_dst - (left << sh);
384  src1[0] = src - stride_src - (left << sh);
385  src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh);
386  pos = 0;
387  if (left) {
388  src_idx = (CTB(s->sao, x_ctb-1, y_ctb-1).type_idx[c_idx] ==
389  SAO_APPLIED);
390  copy_pixel(dst1, src1[src_idx], sh);
391  pos += (1 << sh);
392  }
393  src_idx = (CTB(s->sao, x_ctb, y_ctb-1).type_idx[c_idx] ==
394  SAO_APPLIED);
395  memcpy(dst1 + pos, src1[src_idx] + pos, width << sh);
396  if (right) {
397  pos += width << sh;
398  src_idx = (CTB(s->sao, x_ctb+1, y_ctb-1).type_idx[c_idx] ==
399  SAO_APPLIED);
400  copy_pixel(dst1 + pos, src1[src_idx] + pos, sh);
401  }
402  }
403  if (!bottom_edge) {
404  int left = 1 - left_edge;
405  int right = 1 - right_edge;
406  const uint8_t *src1[2];
407  uint8_t *dst1;
408  int src_idx, pos;
409 
410  dst1 = dst + height * stride_dst - (left << sh);
411  src1[0] = src + height * stride_src - (left << sh);
412  src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh);
413  pos = 0;
414  if (left) {
415  src_idx = (CTB(s->sao, x_ctb-1, y_ctb+1).type_idx[c_idx] ==
416  SAO_APPLIED);
417  copy_pixel(dst1, src1[src_idx], sh);
418  pos += (1 << sh);
419  }
420  src_idx = (CTB(s->sao, x_ctb, y_ctb+1).type_idx[c_idx] ==
421  SAO_APPLIED);
422  memcpy(dst1 + pos, src1[src_idx] + pos, width << sh);
423  if (right) {
424  pos += width << sh;
425  src_idx = (CTB(s->sao, x_ctb+1, y_ctb+1).type_idx[c_idx] ==
426  SAO_APPLIED);
427  copy_pixel(dst1 + pos, src1[src_idx] + pos, sh);
428  }
429  }
430  left_pixels = 0;
431  if (!left_edge) {
432  if (CTB(s->sao, x_ctb-1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
433  copy_vert(dst - (1 << sh),
434  s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh),
435  sh, height, stride_dst, 1 << sh);
436  } else {
437  left_pixels = 1;
438  }
439  }
440  right_pixels = 0;
441  if (!right_edge) {
442  if (CTB(s->sao, x_ctb+1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
443  copy_vert(dst + (width << sh),
444  s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh),
445  sh, height, stride_dst, 1 << sh);
446  } else {
447  right_pixels = 1;
448  }
449  }
450 
451  copy_CTB(dst - (left_pixels << sh),
452  src - (left_pixels << sh),
453  (width + left_pixels + right_pixels) << sh,
454  height, stride_dst, stride_src);
455 
456  copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx,
457  x_ctb, y_ctb);
458  s->hevcdsp.sao_edge_filter[tab](src, dst, stride_src, sao->offset_val[c_idx],
459  sao->eo_class[c_idx], width, height);
460  s->hevcdsp.sao_edge_restore[restore](src, dst,
461  stride_src, stride_dst,
462  sao,
463  edges, width,
464  height, c_idx,
465  vert_edge,
466  horiz_edge,
467  diag_edge);
468  restore_tqb_pixels(s, pps, sps, src, dst, stride_src, stride_dst,
469  x, y, width, height, c_idx);
470  sao->type_idx[c_idx] = SAO_APPLIED;
471  break;
472  }
473  }
474  }
475 }
476 
477 static int get_pcm(const HEVCSPS *sps, const uint8_t *is_pcm, int x, int y)
478 {
479  int log2_min_pu_size = sps->log2_min_pu_size;
480  int x_pu, y_pu;
481 
482  if (x < 0 || y < 0)
483  return 2;
484 
485  x_pu = x >> log2_min_pu_size;
486  y_pu = y >> log2_min_pu_size;
487 
488  if (x_pu >= sps->min_pu_width || y_pu >= sps->min_pu_height)
489  return 2;
490  return is_pcm[y_pu * sps->min_pu_width + x_pu];
491 }
492 
493 #define TC_CALC(qp, bs) \
494  tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
495  (tc_offset & -2), \
496  0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
497 
499  const HEVCPPS *pps, const HEVCSPS *sps,
500  int x0, int y0)
501 {
502  uint8_t **data = s->cur_frame->f->data;
503  int *linesize = s->cur_frame->f->linesize;
504 
505  uint8_t *src;
506  int x, y;
507  int chroma, beta;
508  int32_t c_tc[2], tc[2];
509  uint8_t no_p[2] = { 0 };
510  uint8_t no_q[2] = { 0 };
511 
512  int log2_ctb_size = sps->log2_ctb_size;
513  int x_end, x_end2, y_end;
514  int ctb_size = 1 << log2_ctb_size;
515  int ctb = (x0 >> log2_ctb_size) +
516  (y0 >> log2_ctb_size) * sps->ctb_width;
517  int cur_tc_offset = s->deblock[ctb].tc_offset;
518  int cur_beta_offset = s->deblock[ctb].beta_offset;
519  int left_tc_offset, left_beta_offset;
520  int tc_offset, beta_offset;
521  int pcmf = (sps->pcm_enabled &&
522  sps->pcm_loop_filter_disabled) ||
523  pps->transquant_bypass_enable_flag;
524 
525  if (x0) {
526  left_tc_offset = s->deblock[ctb - 1].tc_offset;
527  left_beta_offset = s->deblock[ctb - 1].beta_offset;
528  } else {
529  left_tc_offset = 0;
530  left_beta_offset = 0;
531  }
532 
533  x_end = x0 + ctb_size;
534  if (x_end > sps->width)
535  x_end = sps->width;
536  y_end = y0 + ctb_size;
537  if (y_end > sps->height)
538  y_end = sps->height;
539 
540  tc_offset = cur_tc_offset;
541  beta_offset = cur_beta_offset;
542 
543  x_end2 = x_end;
544  if (x_end2 != sps->width)
545  x_end2 -= 8;
546  for (y = y0; y < y_end; y += 8) {
547  // vertical filtering luma
548  for (x = x0 ? x0 : 8; x < x_end; x += 8) {
549  const int bs0 = s->vertical_bs[(x + y * s->bs_width) >> 2];
550  const int bs1 = s->vertical_bs[(x + (y + 4) * s->bs_width) >> 2];
551  if (bs0 || bs1) {
552  const int qp = (get_qPy(sps, s->qp_y_tab, x - 1, y) +
553  get_qPy(sps, s->qp_y_tab, x, y) + 1) >> 1;
554 
555  beta = betatable[av_clip(qp + beta_offset, 0, MAX_QP)];
556 
557  tc[0] = bs0 ? TC_CALC(qp, bs0) : 0;
558  tc[1] = bs1 ? TC_CALC(qp, bs1) : 0;
559  src = &data[LUMA][y * linesize[LUMA] + (x << sps->pixel_shift)];
560  if (pcmf) {
561  no_p[0] = get_pcm(sps, s->is_pcm, x - 1, y);
562  no_p[1] = get_pcm(sps, s->is_pcm, x - 1, y + 4);
563  no_q[0] = get_pcm(sps, s->is_pcm, x, y);
564  no_q[1] = get_pcm(sps, s->is_pcm, x, y + 4);
565  s->hevcdsp.hevc_v_loop_filter_luma_c(src, linesize[LUMA],
566  beta, tc, no_p, no_q);
567  } else
568  s->hevcdsp.hevc_v_loop_filter_luma(src, linesize[LUMA],
569  beta, tc, no_p, no_q);
570  }
571  }
572 
573  if(!y)
574  continue;
575 
576  // horizontal filtering luma
577  for (x = x0 ? x0 - 8 : 0; x < x_end2; x += 8) {
578  const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2];
579  const int bs1 = s->horizontal_bs[((x + 4) + y * s->bs_width) >> 2];
580  if (bs0 || bs1) {
581  const int qp = (get_qPy(sps, s->qp_y_tab, x, y - 1) +
582  get_qPy(sps, s->qp_y_tab, x, y) + 1) >> 1;
583 
584  tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
585  beta_offset = x >= x0 ? cur_beta_offset : left_beta_offset;
586 
587  beta = betatable[av_clip(qp + beta_offset, 0, MAX_QP)];
588  tc[0] = bs0 ? TC_CALC(qp, bs0) : 0;
589  tc[1] = bs1 ? TC_CALC(qp, bs1) : 0;
590  src = &data[LUMA][y * linesize[LUMA] + (x << sps->pixel_shift)];
591  if (pcmf) {
592  no_p[0] = get_pcm(sps, s->is_pcm, x, y - 1);
593  no_p[1] = get_pcm(sps, s->is_pcm, x + 4, y - 1);
594  no_q[0] = get_pcm(sps, s->is_pcm, x, y);
595  no_q[1] = get_pcm(sps, s->is_pcm, x + 4, y);
596  s->hevcdsp.hevc_h_loop_filter_luma_c(src, linesize[LUMA],
597  beta, tc, no_p, no_q);
598  } else
599  s->hevcdsp.hevc_h_loop_filter_luma(src, linesize[LUMA],
600  beta, tc, no_p, no_q);
601  }
602  }
603  }
604 
605  if (sps->chroma_format_idc) {
606  for (chroma = 1; chroma <= 2; chroma++) {
607  int h = 1 << sps->hshift[chroma];
608  int v = 1 << sps->vshift[chroma];
609 
610  // vertical filtering chroma
611  for (y = y0; y < y_end; y += (8 * v)) {
612  for (x = x0 ? x0 : 8 * h; x < x_end; x += (8 * h)) {
613  const int bs0 = s->vertical_bs[(x + y * s->bs_width) >> 2];
614  const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * s->bs_width) >> 2];
615 
616  if ((bs0 == 2) || (bs1 == 2)) {
617  const int qp0 = (get_qPy(sps, s->qp_y_tab, x - 1, y) +
618  get_qPy(sps, s->qp_y_tab, x, y) + 1) >> 1;
619  const int qp1 = (get_qPy(sps, s->qp_y_tab, x - 1, y + (4 * v)) +
620  get_qPy(sps, s->qp_y_tab, x, y + (4 * v)) + 1) >> 1;
621 
622  c_tc[0] = (bs0 == 2) ? chroma_tc(pps, sps, qp0, chroma, tc_offset) : 0;
623  c_tc[1] = (bs1 == 2) ? chroma_tc(pps, sps, qp1, chroma, tc_offset) : 0;
624  src = &data[chroma][(y >> sps->vshift[chroma]) * linesize[chroma] + ((x >> sps->hshift[chroma]) << sps->pixel_shift)];
625  if (pcmf) {
626  no_p[0] = get_pcm(sps, s->is_pcm, x - 1, y);
627  no_p[1] = get_pcm(sps, s->is_pcm, x - 1, y + (4 * v));
628  no_q[0] = get_pcm(sps, s->is_pcm, x, y);
629  no_q[1] = get_pcm(sps, s->is_pcm, x, y + (4 * v));
630  s->hevcdsp.hevc_v_loop_filter_chroma_c(src, linesize[chroma],
631  c_tc, no_p, no_q);
632  } else
633  s->hevcdsp.hevc_v_loop_filter_chroma(src, linesize[chroma],
634  c_tc, no_p, no_q);
635  }
636  }
637 
638  if(!y)
639  continue;
640 
641  // horizontal filtering chroma
642  tc_offset = x0 ? left_tc_offset : cur_tc_offset;
643  x_end2 = x_end;
644  if (x_end != sps->width)
645  x_end2 = x_end - 8 * h;
646  for (x = x0 ? x0 - 8 * h : 0; x < x_end2; x += (8 * h)) {
647  const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2];
648  const int bs1 = s->horizontal_bs[((x + 4 * h) + y * s->bs_width) >> 2];
649  if ((bs0 == 2) || (bs1 == 2)) {
650  const int qp0 = bs0 == 2 ? (get_qPy(sps, s->qp_y_tab, x, y - 1) +
651  get_qPy(sps, s->qp_y_tab, x, y) + 1) >> 1 : 0;
652  const int qp1 = bs1 == 2 ? (get_qPy(sps, s->qp_y_tab, x + (4 * h), y - 1) +
653  get_qPy(sps, s->qp_y_tab, x + (4 * h), y) + 1) >> 1 : 0;
654 
655  c_tc[0] = bs0 == 2 ? chroma_tc(pps, sps, qp0, chroma, tc_offset) : 0;
656  c_tc[1] = bs1 == 2 ? chroma_tc(pps, sps, qp1, chroma, cur_tc_offset) : 0;
657  src = &data[chroma][(y >> sps->vshift[1]) * linesize[chroma] + ((x >> sps->hshift[1]) << sps->pixel_shift)];
658  if (pcmf) {
659  no_p[0] = get_pcm(sps, s->is_pcm, x, y - 1);
660  no_p[1] = get_pcm(sps, s->is_pcm, x + (4 * h), y - 1);
661  no_q[0] = get_pcm(sps, s->is_pcm, x, y);
662  no_q[1] = get_pcm(sps, s->is_pcm, x + (4 * h), y);
663  s->hevcdsp.hevc_h_loop_filter_chroma_c(src, linesize[chroma],
664  c_tc, no_p, no_q);
665  } else
666  s->hevcdsp.hevc_h_loop_filter_chroma(src, linesize[chroma],
667  c_tc, no_p, no_q);
668  }
669  }
670  }
671  }
672  }
673 }
674 
675 static int boundary_strength(const HEVCContext *s, const MvField *curr, const MvField *neigh,
676  const RefPicList *neigh_refPicList)
677 {
678  if (curr->pred_flag == PF_BI && neigh->pred_flag == PF_BI) {
679  // same L0 and L1
680  if (s->cur_frame->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]] &&
681  s->cur_frame->refPicList[0].list[curr->ref_idx[0]] == s->cur_frame->refPicList[1].list[curr->ref_idx[1]] &&
682  neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
683  if ((FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
684  FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
685  (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
686  FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4))
687  return 1;
688  else
689  return 0;
690  } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->cur_frame->refPicList[0].list[curr->ref_idx[0]] &&
691  neigh_refPicList[1].list[neigh->ref_idx[1]] == s->cur_frame->refPicList[1].list[curr->ref_idx[1]]) {
692  if (FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
693  FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4)
694  return 1;
695  else
696  return 0;
697  } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->cur_frame->refPicList[0].list[curr->ref_idx[0]] &&
698  neigh_refPicList[0].list[neigh->ref_idx[0]] == s->cur_frame->refPicList[1].list[curr->ref_idx[1]]) {
699  if (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
700  FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4)
701  return 1;
702  else
703  return 0;
704  } else {
705  return 1;
706  }
707  } else if ((curr->pred_flag != PF_BI) && (neigh->pred_flag != PF_BI)){ // 1 MV
708  Mv A, B;
709  int ref_A, ref_B;
710 
711  if (curr->pred_flag & 1) {
712  A = curr->mv[0];
713  ref_A = s->cur_frame->refPicList[0].list[curr->ref_idx[0]];
714  } else {
715  A = curr->mv[1];
716  ref_A = s->cur_frame->refPicList[1].list[curr->ref_idx[1]];
717  }
718 
719  if (neigh->pred_flag & 1) {
720  B = neigh->mv[0];
721  ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
722  } else {
723  B = neigh->mv[1];
724  ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
725  }
726 
727  if (ref_A == ref_B) {
728  if (FFABS(A.x - B.x) >= 4 || FFABS(A.y - B.y) >= 4)
729  return 1;
730  else
731  return 0;
732  } else
733  return 1;
734  }
735 
736  return 1;
737 }
738 
740  int x0, int y0, int log2_trafo_size)
741 {
742  const HEVCSPS *const sps = pps->sps;
743  const HEVCContext *s = lc->parent;
744  const MvField *tab_mvf = s->cur_frame->tab_mvf;
745  int log2_min_pu_size = sps->log2_min_pu_size;
746  int log2_min_tu_size = sps->log2_min_tb_size;
747  int min_pu_width = sps->min_pu_width;
748  int min_tu_width = sps->min_tb_width;
749  int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
750  (x0 >> log2_min_pu_size)].pred_flag == PF_INTRA;
751  int boundary_upper, boundary_left;
752  int i, j, bs;
753 
754  boundary_upper = y0 > 0 && !(y0 & 7);
755  if (boundary_upper &&
756  ((!s->sh.slice_loop_filter_across_slices_enabled_flag &&
758  (y0 % (1 << sps->log2_ctb_size)) == 0) ||
759  (!pps->loop_filter_across_tiles_enabled_flag &&
761  (y0 % (1 << sps->log2_ctb_size)) == 0)))
762  boundary_upper = 0;
763 
764  if (boundary_upper) {
765  const RefPicList *rpl_top = (lc->boundary_flags & BOUNDARY_UPPER_SLICE) ?
766  ff_hevc_get_ref_list(s, s->cur_frame, x0, y0 - 1) :
767  s->cur_frame->refPicList;
768  int yp_pu = (y0 - 1) >> log2_min_pu_size;
769  int yq_pu = y0 >> log2_min_pu_size;
770  int yp_tu = (y0 - 1) >> log2_min_tu_size;
771  int yq_tu = y0 >> log2_min_tu_size;
772 
773  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
774  int x_pu = (x0 + i) >> log2_min_pu_size;
775  int x_tu = (x0 + i) >> log2_min_tu_size;
776  const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
777  const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
778  uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
779  uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
780 
781  if (curr->pred_flag == PF_INTRA || top->pred_flag == PF_INTRA)
782  bs = 2;
783  else if (curr_cbf_luma || top_cbf_luma)
784  bs = 1;
785  else
786  bs = boundary_strength(s, curr, top, rpl_top);
787  s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
788  }
789  }
790 
791  // bs for vertical TU boundaries
792  boundary_left = x0 > 0 && !(x0 & 7);
793  if (boundary_left &&
794  ((!s->sh.slice_loop_filter_across_slices_enabled_flag &&
796  (x0 % (1 << sps->log2_ctb_size)) == 0) ||
797  (!pps->loop_filter_across_tiles_enabled_flag &&
799  (x0 % (1 << sps->log2_ctb_size)) == 0)))
800  boundary_left = 0;
801 
802  if (boundary_left) {
803  const RefPicList *rpl_left = (lc->boundary_flags & BOUNDARY_LEFT_SLICE) ?
804  ff_hevc_get_ref_list(s, s->cur_frame, x0 - 1, y0) :
805  s->cur_frame->refPicList;
806  int xp_pu = (x0 - 1) >> log2_min_pu_size;
807  int xq_pu = x0 >> log2_min_pu_size;
808  int xp_tu = (x0 - 1) >> log2_min_tu_size;
809  int xq_tu = x0 >> log2_min_tu_size;
810 
811  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
812  int y_pu = (y0 + i) >> log2_min_pu_size;
813  int y_tu = (y0 + i) >> log2_min_tu_size;
814  const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
815  const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
816  uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
817  uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
818 
819  if (curr->pred_flag == PF_INTRA || left->pred_flag == PF_INTRA)
820  bs = 2;
821  else if (curr_cbf_luma || left_cbf_luma)
822  bs = 1;
823  else
824  bs = boundary_strength(s, curr, left, rpl_left);
825  s->vertical_bs[(x0 + (y0 + i) * s->bs_width) >> 2] = bs;
826  }
827  }
828 
829  if (log2_trafo_size > log2_min_pu_size && !is_intra) {
830  const RefPicList *rpl = s->cur_frame->refPicList;
831 
832  // bs for TU internal horizontal PU boundaries
833  for (j = 8; j < (1 << log2_trafo_size); j += 8) {
834  int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
835  int yq_pu = (y0 + j) >> log2_min_pu_size;
836 
837  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
838  int x_pu = (x0 + i) >> log2_min_pu_size;
839  const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
840  const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
841 
842  bs = boundary_strength(s, curr, top, rpl);
843  s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
844  }
845  }
846 
847  // bs for TU internal vertical PU boundaries
848  for (j = 0; j < (1 << log2_trafo_size); j += 4) {
849  int y_pu = (y0 + j) >> log2_min_pu_size;
850 
851  for (i = 8; i < (1 << log2_trafo_size); i += 8) {
852  int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
853  int xq_pu = (x0 + i) >> log2_min_pu_size;
854  const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
855  const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
856 
857  bs = boundary_strength(s, curr, left, rpl);
858  s->vertical_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
859  }
860  }
861  }
862 }
863 
864 #undef LUMA
865 #undef CB
866 #undef CR
867 
869  int x, int y, int ctb_size)
870 {
871  const HEVCSPS *const sps = pps->sps;
872  const HEVCContext *const s = lc->parent;
873  int x_end = x >= sps->width - ctb_size;
874  int skip = 0;
875  if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
876  (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && !IS_IDR(s)) ||
877  (s->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&
878  s->sh.slice_type != HEVC_SLICE_I) ||
879  (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR &&
880  s->sh.slice_type == HEVC_SLICE_B) ||
881  (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
882  ff_hevc_nal_is_nonref(s->nal_unit_type)))
883  skip = 1;
884 
885  if (!skip)
886  deblocking_filter_CTB(s, pps, sps, x, y);
887  if (sps->sao_enabled && !skip) {
888  int y_end = y >= sps->height - ctb_size;
889  if (y && x)
890  sao_filter_CTB(lc, s, pps, sps, x - ctb_size, y - ctb_size);
891  if (x && y_end)
892  sao_filter_CTB(lc, s, pps, sps, x - ctb_size, y);
893  if (y && x_end) {
894  sao_filter_CTB(lc, s, pps, sps, x, y - ctb_size);
895  if (s->avctx->active_thread_type & FF_THREAD_FRAME )
896  ff_progress_frame_report(&s->cur_frame->tf, y);
897  }
898  if (x_end && y_end) {
899  sao_filter_CTB(lc, s, pps, sps, x , y);
900  if (s->avctx->active_thread_type & FF_THREAD_FRAME )
901  ff_progress_frame_report(&s->cur_frame->tf, y + ctb_size);
902  }
903  } else if (s->avctx->active_thread_type & FF_THREAD_FRAME && x_end)
904  ff_progress_frame_report(&s->cur_frame->tf, y + ctb_size - 4);
905 }
906 
908  int x_ctb, int y_ctb, int ctb_size)
909 {
910  int x_end = x_ctb >= pps->sps->width - ctb_size;
911  int y_end = y_ctb >= pps->sps->height - ctb_size;
912  if (y_ctb && x_ctb)
913  ff_hevc_hls_filter(lc, pps, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
914  if (y_ctb && x_end)
915  ff_hevc_hls_filter(lc, pps, x_ctb, y_ctb - ctb_size, ctb_size);
916  if (x_ctb && y_end)
917  ff_hevc_hls_filter(lc, pps, x_ctb - ctb_size, y_ctb, ctb_size);
918 }
ff_progress_frame_report
void ff_progress_frame_report(ProgressFrame *f, int n)
Notify later decoding threads when part of their reference frame is ready.
Definition: decode.c:1759
A
#define A(x)
Definition: vpx_arith.h:28
FFUMOD
#define FFUMOD(a, b)
Definition: common.h:66
ff_hevc_get_ref_list
const RefPicList * ff_hevc_get_ref_list(const HEVCContext *s, const HEVCFrame *frame, int x0, int y0)
Definition: refs.c:51
HEVCLocalContext
Definition: hevcdec.h:389
av_clip
#define av_clip
Definition: common.h:100
LUMA
#define LUMA
Definition: filter.c:31
DEFAULT_INTRA_TC_OFFSET
#define DEFAULT_INTRA_TC_OFFSET
Definition: filter.c:36
SAO_APPLIED
@ SAO_APPLIED
Definition: hevcdec.h:162
SAO_BAND
@ SAO_BAND
Definition: hevcdec.h:160
src1
const pixel * src1
Definition: h264pred_template.c:421
get_pcm
static int get_pcm(const HEVCSPS *sps, const uint8_t *is_pcm, int x, int y)
Definition: filter.c:477
tctable
static const uint8_t tctable[54]
Definition: filter.c:35
TransformUnit::cu_qp_delta
int cu_qp_delta
Definition: hevcdec.h:329
w
uint8_t w
Definition: llviddspenc.c:38
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
data
const char data[16]
Definition: mxf.c:148
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:300
betatable
static const uint8_t betatable[52]
Definition: filter.c:41
SAO_EDGE
@ SAO_EDGE
Definition: hevcdec.h:161
TransformUnit::is_cu_qp_delta_coded
uint8_t is_cu_qp_delta_coded
Definition: hevcdec.h:337
chroma_tc
static int chroma_tc(const HEVCPPS *pps, const HEVCSPS *sps, int qp_y, int c_idx, int tc_offset)
Definition: filter.c:47
deblocking_filter_CTB
static void deblocking_filter_CTB(const HEVCContext *s, const HEVCPPS *pps, const HEVCSPS *sps, int x0, int y0)
Definition: filter.c:498
RefPicList
Definition: hevcdec.h:190
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:114
ff_hevc_deblocking_boundary_strengths
void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *pps, int x0, int y0, int log2_trafo_size)
Definition: filter.c:739
BOUNDARY_LEFT_TILE
#define BOUNDARY_LEFT_TILE
Definition: hevcdec.h:438
TC_CALC
#define TC_CALC(qp, bs)
Definition: filter.c:493
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
copy_pixel
static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
Definition: filter.c:177
progressframe.h
copy_CTB
static void copy_CTB(uint8_t *dst, const uint8_t *src, int width, int height, ptrdiff_t stride_dst, ptrdiff_t stride_src)
Definition: filter.c:144
boundary_strength
static int boundary_strength(const HEVCContext *s, const MvField *curr, const MvField *neigh, const RefPicList *neigh_refPicList)
Definition: filter.c:675
sao_filter_CTB
static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCContext *s, const HEVCPPS *pps, const HEVCSPS *sps, int x, int y)
Definition: filter.c:267
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
get_qPy
static int get_qPy(const HEVCSPS *sps, const int8_t *qp_y_tab, int xC, int yC)
Definition: filter.c:136
width
#define width
HEVCLocalContext::parent
const struct HEVCContext * parent
Definition: hevcdec.h:397
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_hevc_nal_is_nonref
static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type)
Definition: hevcdec.h:618
B
#define B
Definition: huffyuv.h:42
IS_IDR
#define IS_IDR(s)
Definition: hevcdec.h:76
AVDISCARD_BIDIR
@ AVDISCARD_BIDIR
discard all bidirectional frames
Definition: defs.h:217
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
if
if(ret)
Definition: filter_design.txt:179
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:220
AV_COPY128
#define AV_COPY128(d, s)
Definition: intreadwrite.h:601
is_pcm
static int is_pcm(enum AVCodecID codec_id)
Definition: mxfdec.c:2467
HEVC_SLICE_I
@ HEVC_SLICE_I
Definition: hevc.h:98
HEVCLocalContext::first_qp_group
uint8_t first_qp_group
Definition: hevcdec.h:394
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
BOUNDARY_UPPER_TILE
#define BOUNDARY_UPPER_TILE
Definition: hevcdec.h:440
ff_hevc_hls_filters
void ff_hevc_hls_filters(HEVCLocalContext *lc, const HEVCPPS *pps, int x_ctb, int y_ctb, int ctb_size)
Definition: filter.c:907
AV_COPY64U
#define AV_COPY64U(d, s)
Definition: intreadwrite.h:570
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:299
CTB
#define CTB(tab, x, y)
Definition: filter.c:265
PF_BI
@ PF_BI
Definition: hevcdec.h:117
HEVCLocalContext::edge_emu_buffer
uint8_t edge_emu_buffer[(MAX_PB_SIZE+7) *EDGE_EMU_BUFFER_STRIDE *2]
Definition: hevcdec.h:427
restore_tqb_pixels
static void restore_tqb_pixels(const HEVCContext *s, const HEVCPPS *pps, const HEVCSPS *sps, uint8_t *src1, const uint8_t *dst1, ptrdiff_t stride_src, ptrdiff_t stride_dst, int x0, int y0, int width, int height, int c_idx)
Definition: filter.c:226
SAOParams::offset_val
int16_t offset_val[3][5]
SaoOffsetVal.
Definition: dsp.h:42
copy_vert
static void copy_vert(uint8_t *dst, const uint8_t *src, int pixel_shift, int height, ptrdiff_t stride_dst, ptrdiff_t stride_src)
Definition: filter.c:185
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:219
BOUNDARY_UPPER_SLICE
#define BOUNDARY_UPPER_SLICE
Definition: hevcdec.h:439
hevcdec.h
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
MvField
Definition: hevcdec.h:303
height
#define height
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:306
SAOParams::eo_class
int eo_class[3]
sao_eo_class
Definition: dsp.h:40
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1594
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
AVDISCARD_NONINTRA
@ AVDISCARD_NONINTRA
discard all non intra frames
Definition: defs.h:218
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
internal.h
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:192
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
HEVCLocalContext::qp_y
int8_t qp_y
Definition: hevcdec.h:413
len
int len
Definition: vorbis_enc_data.h:426
SAOParams
Definition: dsp.h:34
MAX_PB_SIZE
#define MAX_PB_SIZE
Definition: dsp.h:32
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
pos
unsigned int pos
Definition: spdifenc.c:414
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
HEVCLocalContext::boundary_flags
int boundary_flags
Definition: hevcdec.h:443
HEVCContext
Definition: hevcdec.h:450
HEVCLocalContext::qPy_pred
int qPy_pred
Definition: hevcdec.h:416
pps
uint64_t pps
Definition: dovi_rpuenc.c:35
SAOParams::type_idx
uint8_t type_idx[3]
sao_type_idx
Definition: dsp.h:44
ff_hevc_hls_filter
void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCPPS *pps, int x, int y, int ctb_size)
Definition: filter.c:868
HEVCLocalContext::tu
TransformUnit tu
Definition: hevcdec.h:418
MAX_QP
#define MAX_QP
Definition: hevcdec.h:50
MvField::mv
Mv mv[2]
mvL0, vvL1
Definition: hevcdec.h:304
Mv
Definition: hevcdec.h:298
MvField::ref_idx
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition: hevcdec.h:305
ff_hevc_set_qPy
void ff_hevc_set_qPy(HEVCLocalContext *lc, const HEVCPPS *pps, int xBase, int yBase, int log2_cb_size)
Definition: filter.c:121
HEVCSPS
Definition: ps.h:190
HEVCPPS
Definition: ps.h:309
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
int32_t
int32_t
Definition: audioconvert.c:56
h
h
Definition: vp9dsp_template.c:2038
BOUNDARY_LEFT_SLICE
#define BOUNDARY_LEFT_SLICE
Definition: hevcdec.h:437
SAOParams::band_position
uint8_t band_position[3]
sao_band_position
Definition: dsp.h:38
AVDISCARD_NONREF
@ AVDISCARD_NONREF
discard all non reference
Definition: defs.h:216
copy_CTB_to_hv
static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps, const uint8_t *src, ptrdiff_t stride_src, int x, int y, int width, int height, int c_idx, int x_ctb, int y_ctb)
Definition: filter.c:205
get_qPy_pred
static int get_qPy_pred(HEVCLocalContext *lc, const HEVCContext *s, const HEVCPPS *pps, const HEVCSPS *sps, int xBase, int yBase, int log2_cb_size)
Definition: filter.c:77
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375