FFmpeg
hevc_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 "threadframe.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 HEVCContext *s, int qp_y, int c_idx, int tc_offset)
48 {
49  static const int qp_c[] = {
50  29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
51  };
52  int qp, qp_i, offset, idxt;
53 
54  // slice qp offset is not used for deblocking
55  if (c_idx == 1)
56  offset = s->ps.pps->cb_qp_offset;
57  else
58  offset = s->ps.pps->cr_qp_offset;
59 
60  qp_i = av_clip(qp_y + offset, 0, 57);
61  if (s->ps.sps->chroma_format_idc == 1) {
62  if (qp_i < 30)
63  qp = qp_i;
64  else if (qp_i > 43)
65  qp = qp_i - 6;
66  else
67  qp = qp_c[qp_i - 30];
68  } else {
69  qp = av_clip(qp_i, 0, 51);
70  }
71 
72  idxt = av_clip(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
73  return tctable[idxt];
74 }
75 
76 static int get_qPy_pred(HEVCLocalContext *lc, const HEVCContext *s,
77  int xBase, int yBase, int log2_cb_size)
78 {
79  int ctb_size_mask = (1 << s->ps.sps->log2_ctb_size) - 1;
80  int MinCuQpDeltaSizeMask = (1 << (s->ps.sps->log2_ctb_size -
81  s->ps.pps->diff_cu_qp_delta_depth)) - 1;
82  int xQgBase = xBase - (xBase & MinCuQpDeltaSizeMask);
83  int yQgBase = yBase - (yBase & MinCuQpDeltaSizeMask);
84  int min_cb_width = s->ps.sps->min_cb_width;
85  int x_cb = xQgBase >> s->ps.sps->log2_min_cb_size;
86  int y_cb = yQgBase >> s->ps.sps->log2_min_cb_size;
87  int availableA = (xBase & ctb_size_mask) &&
88  (xQgBase & ctb_size_mask);
89  int availableB = (yBase & ctb_size_mask) &&
90  (yQgBase & ctb_size_mask);
91  int qPy_pred, qPy_a, qPy_b;
92 
93  // qPy_pred
94  if (lc->first_qp_group || (!xQgBase && !yQgBase)) {
96  qPy_pred = s->sh.slice_qp;
97  } else {
98  qPy_pred = lc->qPy_pred;
99  }
100 
101  // qPy_a
102  if (availableA == 0)
103  qPy_a = qPy_pred;
104  else
105  qPy_a = s->qp_y_tab[(x_cb - 1) + y_cb * min_cb_width];
106 
107  // qPy_b
108  if (availableB == 0)
109  qPy_b = qPy_pred;
110  else
111  qPy_b = s->qp_y_tab[x_cb + (y_cb - 1) * min_cb_width];
112 
113  av_assert2(qPy_a >= -s->ps.sps->qp_bd_offset && qPy_a < 52);
114  av_assert2(qPy_b >= -s->ps.sps->qp_bd_offset && qPy_b < 52);
115 
116  return (qPy_a + qPy_b + 1) >> 1;
117 }
118 
119 void ff_hevc_set_qPy(HEVCLocalContext *lc, int xBase, int yBase, int log2_cb_size)
120 {
121  const HEVCContext *const s = lc->parent;
122  int qp_y = get_qPy_pred(lc, s, xBase, yBase, log2_cb_size);
123 
124  if (lc->tu.cu_qp_delta != 0) {
125  int off = s->ps.sps->qp_bd_offset;
126  lc->qp_y = FFUMOD(qp_y + lc->tu.cu_qp_delta + 52 + 2 * off,
127  52 + off) - off;
128  } else
129  lc->qp_y = qp_y;
130 }
131 
132 static int get_qPy(const HEVCContext *s, int xC, int yC)
133 {
134  int log2_min_cb_size = s->ps.sps->log2_min_cb_size;
135  int x = xC >> log2_min_cb_size;
136  int y = yC >> log2_min_cb_size;
137  return s->qp_y_tab[x + y * s->ps.sps->min_cb_width];
138 }
139 
140 static void copy_CTB(uint8_t *dst, const uint8_t *src, int width, int height,
141  ptrdiff_t stride_dst, ptrdiff_t stride_src)
142 {
143  int i, j;
144 
145  if (((intptr_t)dst | (intptr_t)src | stride_dst | stride_src) & 15) {
146  for (i = 0; i < height; i++) {
147  for (j = 0; j < width - 7; j+=8)
148  AV_COPY64U(dst+j, src+j);
149  dst += stride_dst;
150  src += stride_src;
151  }
152  if (width&7) {
153  dst += ((width>>3)<<3) - stride_dst * height;
154  src += ((width>>3)<<3) - stride_src * height;
155  width &= 7;
156  for (i = 0; i < height; i++) {
157  for (j = 0; j < width; j++)
158  dst[j] = src[j];
159  dst += stride_dst;
160  src += stride_src;
161  }
162  }
163  } else {
164  for (i = 0; i < height; i++) {
165  for (j = 0; j < width; j+=16)
166  AV_COPY128(dst+j, src+j);
167  dst += stride_dst;
168  src += stride_src;
169  }
170  }
171 }
172 
173 static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
174 {
175  if (pixel_shift)
176  *(uint16_t *)dst = *(uint16_t *)src;
177  else
178  *dst = *src;
179 }
180 
181 static void copy_vert(uint8_t *dst, const uint8_t *src,
182  int pixel_shift, int height,
183  ptrdiff_t stride_dst, ptrdiff_t stride_src)
184 {
185  int i;
186  if (pixel_shift == 0) {
187  for (i = 0; i < height; i++) {
188  *dst = *src;
189  dst += stride_dst;
190  src += stride_src;
191  }
192  } else {
193  for (i = 0; i < height; i++) {
194  *(uint16_t *)dst = *(uint16_t *)src;
195  dst += stride_dst;
196  src += stride_src;
197  }
198  }
199 }
200 
201 static void copy_CTB_to_hv(const HEVCContext *s, const uint8_t *src,
202  ptrdiff_t stride_src, int x, int y, int width, int height,
203  int c_idx, int x_ctb, int y_ctb)
204 {
205  int sh = s->ps.sps->pixel_shift;
206  int w = s->ps.sps->width >> s->ps.sps->hshift[c_idx];
207  int h = s->ps.sps->height >> s->ps.sps->vshift[c_idx];
208 
209  /* copy horizontal edges */
210  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
211  src, width << sh);
212  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
213  src + stride_src * (height - 1), width << sh);
214 
215  /* copy vertical edges */
216  copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
217 
218  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);
219 }
220 
221 static void restore_tqb_pixels(const HEVCContext *s,
222  uint8_t *src1, const uint8_t *dst1,
223  ptrdiff_t stride_src, ptrdiff_t stride_dst,
224  int x0, int y0, int width, int height, int c_idx)
225 {
226  if ( s->ps.pps->transquant_bypass_enable_flag ||
227  (s->ps.sps->pcm.loop_filter_disable_flag && s->ps.sps->pcm_enabled_flag)) {
228  int x, y;
229  int min_pu_size = 1 << s->ps.sps->log2_min_pu_size;
230  int hshift = s->ps.sps->hshift[c_idx];
231  int vshift = s->ps.sps->vshift[c_idx];
232  int x_min = ((x0 ) >> s->ps.sps->log2_min_pu_size);
233  int y_min = ((y0 ) >> s->ps.sps->log2_min_pu_size);
234  int x_max = ((x0 + width ) >> s->ps.sps->log2_min_pu_size);
235  int y_max = ((y0 + height) >> s->ps.sps->log2_min_pu_size);
236  int len = (min_pu_size >> hshift) << s->ps.sps->pixel_shift;
237  for (y = y_min; y < y_max; y++) {
238  for (x = x_min; x < x_max; x++) {
239  if (s->is_pcm[y * s->ps.sps->min_pu_width + x]) {
240  int n;
241  uint8_t *src = src1 + (((y << s->ps.sps->log2_min_pu_size) - y0) >> vshift) * stride_src + ((((x << s->ps.sps->log2_min_pu_size) - x0) >> hshift) << s->ps.sps->pixel_shift);
242  const uint8_t *dst = dst1 + (((y << s->ps.sps->log2_min_pu_size) - y0) >> vshift) * stride_dst + ((((x << s->ps.sps->log2_min_pu_size) - x0) >> hshift) << s->ps.sps->pixel_shift);
243  for (n = 0; n < (min_pu_size >> vshift); n++) {
244  memcpy(src, dst, len);
245  src += stride_src;
246  dst += stride_dst;
247  }
248  }
249  }
250  }
251  }
252 }
253 
254 #define CTB(tab, x, y) ((tab)[(y) * s->ps.sps->ctb_width + (x)])
255 
256 static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCContext *s, int x, int y)
257 {
258  static const uint8_t sao_tab[8] = { 0, 1, 2, 2, 3, 3, 4, 4 };
259  int c_idx;
260  int edges[4]; // 0 left 1 top 2 right 3 bottom
261  int x_ctb = x >> s->ps.sps->log2_ctb_size;
262  int y_ctb = y >> s->ps.sps->log2_ctb_size;
263  int ctb_addr_rs = y_ctb * s->ps.sps->ctb_width + x_ctb;
264  int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs];
265  SAOParams *sao = &CTB(s->sao, x_ctb, y_ctb);
266  // flags indicating unfilterable edges
267  uint8_t vert_edge[] = { 0, 0 };
268  uint8_t horiz_edge[] = { 0, 0 };
269  uint8_t diag_edge[] = { 0, 0, 0, 0 };
270  uint8_t lfase = CTB(s->filter_slice_edges, x_ctb, y_ctb);
271  uint8_t no_tile_filter = s->ps.pps->tiles_enabled_flag &&
272  !s->ps.pps->loop_filter_across_tiles_enabled_flag;
273  uint8_t restore = no_tile_filter || !lfase;
274  uint8_t left_tile_edge = 0;
275  uint8_t right_tile_edge = 0;
276  uint8_t up_tile_edge = 0;
277  uint8_t bottom_tile_edge = 0;
278 
279  edges[0] = x_ctb == 0;
280  edges[1] = y_ctb == 0;
281  edges[2] = x_ctb == s->ps.sps->ctb_width - 1;
282  edges[3] = y_ctb == s->ps.sps->ctb_height - 1;
283 
284  if (restore) {
285  if (!edges[0]) {
286  left_tile_edge = no_tile_filter && s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs-1]];
287  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;
288  }
289  if (!edges[2]) {
290  right_tile_edge = no_tile_filter && s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs+1]];
291  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;
292  }
293  if (!edges[1]) {
294  up_tile_edge = no_tile_filter && s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->ps.sps->ctb_width]];
295  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;
296  }
297  if (!edges[3]) {
298  bottom_tile_edge = no_tile_filter && s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs + s->ps.sps->ctb_width]];
299  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;
300  }
301  if (!edges[0] && !edges[1]) {
302  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;
303  }
304  if (!edges[1] && !edges[2]) {
305  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;
306  }
307  if (!edges[2] && !edges[3]) {
308  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;
309  }
310  if (!edges[0] && !edges[3]) {
311  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;
312  }
313  }
314 
315  for (c_idx = 0; c_idx < (s->ps.sps->chroma_format_idc ? 3 : 1); c_idx++) {
316  int x0 = x >> s->ps.sps->hshift[c_idx];
317  int y0 = y >> s->ps.sps->vshift[c_idx];
318  ptrdiff_t stride_src = s->frame->linesize[c_idx];
319  int ctb_size_h = (1 << (s->ps.sps->log2_ctb_size)) >> s->ps.sps->hshift[c_idx];
320  int ctb_size_v = (1 << (s->ps.sps->log2_ctb_size)) >> s->ps.sps->vshift[c_idx];
321  int width = FFMIN(ctb_size_h, (s->ps.sps->width >> s->ps.sps->hshift[c_idx]) - x0);
322  int height = FFMIN(ctb_size_v, (s->ps.sps->height >> s->ps.sps->vshift[c_idx]) - y0);
323  int tab = sao_tab[(FFALIGN(width, 8) >> 3) - 1];
324  uint8_t *src = &s->frame->data[c_idx][y0 * stride_src + (x0 << s->ps.sps->pixel_shift)];
325  ptrdiff_t stride_dst;
326  uint8_t *dst;
327 
328  switch (sao->type_idx[c_idx]) {
329  case SAO_BAND:
330  copy_CTB_to_hv(s, src, stride_src, x0, y0, width, height, c_idx,
331  x_ctb, y_ctb);
332  if (s->ps.pps->transquant_bypass_enable_flag ||
333  (s->ps.sps->pcm.loop_filter_disable_flag && s->ps.sps->pcm_enabled_flag)) {
334  dst = lc->edge_emu_buffer;
335  stride_dst = 2*MAX_PB_SIZE;
336  copy_CTB(dst, src, width << s->ps.sps->pixel_shift, height, stride_dst, stride_src);
337  s->hevcdsp.sao_band_filter[tab](src, dst, stride_src, stride_dst,
338  sao->offset_val[c_idx], sao->band_position[c_idx],
339  width, height);
340  restore_tqb_pixels(s, src, dst, stride_src, stride_dst,
341  x, y, width, height, c_idx);
342  } else {
343  s->hevcdsp.sao_band_filter[tab](src, src, stride_src, stride_src,
344  sao->offset_val[c_idx], sao->band_position[c_idx],
345  width, height);
346  }
347  sao->type_idx[c_idx] = SAO_APPLIED;
348  break;
349  case SAO_EDGE:
350  {
351  int w = s->ps.sps->width >> s->ps.sps->hshift[c_idx];
352  int h = s->ps.sps->height >> s->ps.sps->vshift[c_idx];
353  int left_edge = edges[0];
354  int top_edge = edges[1];
355  int right_edge = edges[2];
356  int bottom_edge = edges[3];
357  int sh = s->ps.sps->pixel_shift;
358  int left_pixels, right_pixels;
359 
360  stride_dst = 2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE;
361  dst = lc->edge_emu_buffer + stride_dst + AV_INPUT_BUFFER_PADDING_SIZE;
362 
363  if (!top_edge) {
364  int left = 1 - left_edge;
365  int right = 1 - right_edge;
366  const uint8_t *src1[2];
367  uint8_t *dst1;
368  int src_idx, pos;
369 
370  dst1 = dst - stride_dst - (left << sh);
371  src1[0] = src - stride_src - (left << sh);
372  src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh);
373  pos = 0;
374  if (left) {
375  src_idx = (CTB(s->sao, x_ctb-1, y_ctb-1).type_idx[c_idx] ==
376  SAO_APPLIED);
377  copy_pixel(dst1, src1[src_idx], sh);
378  pos += (1 << sh);
379  }
380  src_idx = (CTB(s->sao, x_ctb, y_ctb-1).type_idx[c_idx] ==
381  SAO_APPLIED);
382  memcpy(dst1 + pos, src1[src_idx] + pos, width << sh);
383  if (right) {
384  pos += width << sh;
385  src_idx = (CTB(s->sao, x_ctb+1, y_ctb-1).type_idx[c_idx] ==
386  SAO_APPLIED);
387  copy_pixel(dst1 + pos, src1[src_idx] + pos, sh);
388  }
389  }
390  if (!bottom_edge) {
391  int left = 1 - left_edge;
392  int right = 1 - right_edge;
393  const uint8_t *src1[2];
394  uint8_t *dst1;
395  int src_idx, pos;
396 
397  dst1 = dst + height * stride_dst - (left << sh);
398  src1[0] = src + height * stride_src - (left << sh);
399  src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh);
400  pos = 0;
401  if (left) {
402  src_idx = (CTB(s->sao, x_ctb-1, y_ctb+1).type_idx[c_idx] ==
403  SAO_APPLIED);
404  copy_pixel(dst1, src1[src_idx], sh);
405  pos += (1 << sh);
406  }
407  src_idx = (CTB(s->sao, x_ctb, y_ctb+1).type_idx[c_idx] ==
408  SAO_APPLIED);
409  memcpy(dst1 + pos, src1[src_idx] + pos, width << sh);
410  if (right) {
411  pos += width << sh;
412  src_idx = (CTB(s->sao, x_ctb+1, y_ctb+1).type_idx[c_idx] ==
413  SAO_APPLIED);
414  copy_pixel(dst1 + pos, src1[src_idx] + pos, sh);
415  }
416  }
417  left_pixels = 0;
418  if (!left_edge) {
419  if (CTB(s->sao, x_ctb-1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
420  copy_vert(dst - (1 << sh),
421  s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh),
422  sh, height, stride_dst, 1 << sh);
423  } else {
424  left_pixels = 1;
425  }
426  }
427  right_pixels = 0;
428  if (!right_edge) {
429  if (CTB(s->sao, x_ctb+1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
430  copy_vert(dst + (width << sh),
431  s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh),
432  sh, height, stride_dst, 1 << sh);
433  } else {
434  right_pixels = 1;
435  }
436  }
437 
438  copy_CTB(dst - (left_pixels << sh),
439  src - (left_pixels << sh),
440  (width + left_pixels + right_pixels) << sh,
441  height, stride_dst, stride_src);
442 
443  copy_CTB_to_hv(s, src, stride_src, x0, y0, width, height, c_idx,
444  x_ctb, y_ctb);
445  s->hevcdsp.sao_edge_filter[tab](src, dst, stride_src, sao->offset_val[c_idx],
446  sao->eo_class[c_idx], width, height);
447  s->hevcdsp.sao_edge_restore[restore](src, dst,
448  stride_src, stride_dst,
449  sao,
450  edges, width,
451  height, c_idx,
452  vert_edge,
453  horiz_edge,
454  diag_edge);
455  restore_tqb_pixels(s, src, dst, stride_src, stride_dst,
456  x, y, width, height, c_idx);
457  sao->type_idx[c_idx] = SAO_APPLIED;
458  break;
459  }
460  }
461  }
462 }
463 
464 static int get_pcm(const HEVCContext *s, int x, int y)
465 {
466  int log2_min_pu_size = s->ps.sps->log2_min_pu_size;
467  int x_pu, y_pu;
468 
469  if (x < 0 || y < 0)
470  return 2;
471 
472  x_pu = x >> log2_min_pu_size;
473  y_pu = y >> log2_min_pu_size;
474 
475  if (x_pu >= s->ps.sps->min_pu_width || y_pu >= s->ps.sps->min_pu_height)
476  return 2;
477  return s->is_pcm[y_pu * s->ps.sps->min_pu_width + x_pu];
478 }
479 
480 #define TC_CALC(qp, bs) \
481  tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
482  (tc_offset & -2), \
483  0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
484 
485 static void deblocking_filter_CTB(const HEVCContext *s, int x0, int y0)
486 {
487  uint8_t *src;
488  int x, y;
489  int chroma, beta;
490  int32_t c_tc[2], tc[2];
491  uint8_t no_p[2] = { 0 };
492  uint8_t no_q[2] = { 0 };
493 
494  int log2_ctb_size = s->ps.sps->log2_ctb_size;
495  int x_end, x_end2, y_end;
496  int ctb_size = 1 << log2_ctb_size;
497  int ctb = (x0 >> log2_ctb_size) +
498  (y0 >> log2_ctb_size) * s->ps.sps->ctb_width;
499  int cur_tc_offset = s->deblock[ctb].tc_offset;
500  int cur_beta_offset = s->deblock[ctb].beta_offset;
501  int left_tc_offset, left_beta_offset;
502  int tc_offset, beta_offset;
503  int pcmf = (s->ps.sps->pcm_enabled_flag &&
504  s->ps.sps->pcm.loop_filter_disable_flag) ||
505  s->ps.pps->transquant_bypass_enable_flag;
506 
507  if (x0) {
508  left_tc_offset = s->deblock[ctb - 1].tc_offset;
509  left_beta_offset = s->deblock[ctb - 1].beta_offset;
510  } else {
511  left_tc_offset = 0;
512  left_beta_offset = 0;
513  }
514 
515  x_end = x0 + ctb_size;
516  if (x_end > s->ps.sps->width)
517  x_end = s->ps.sps->width;
518  y_end = y0 + ctb_size;
519  if (y_end > s->ps.sps->height)
520  y_end = s->ps.sps->height;
521 
522  tc_offset = cur_tc_offset;
523  beta_offset = cur_beta_offset;
524 
525  x_end2 = x_end;
526  if (x_end2 != s->ps.sps->width)
527  x_end2 -= 8;
528  for (y = y0; y < y_end; y += 8) {
529  // vertical filtering luma
530  for (x = x0 ? x0 : 8; x < x_end; x += 8) {
531  const int bs0 = s->vertical_bs[(x + y * s->bs_width) >> 2];
532  const int bs1 = s->vertical_bs[(x + (y + 4) * s->bs_width) >> 2];
533  if (bs0 || bs1) {
534  const int qp = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
535 
536  beta = betatable[av_clip(qp + beta_offset, 0, MAX_QP)];
537 
538  tc[0] = bs0 ? TC_CALC(qp, bs0) : 0;
539  tc[1] = bs1 ? TC_CALC(qp, bs1) : 0;
540  src = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->ps.sps->pixel_shift)];
541  if (pcmf) {
542  no_p[0] = get_pcm(s, x - 1, y);
543  no_p[1] = get_pcm(s, x - 1, y + 4);
544  no_q[0] = get_pcm(s, x, y);
545  no_q[1] = get_pcm(s, x, y + 4);
546  s->hevcdsp.hevc_v_loop_filter_luma_c(src,
547  s->frame->linesize[LUMA],
548  beta, tc, no_p, no_q);
549  } else
550  s->hevcdsp.hevc_v_loop_filter_luma(src,
551  s->frame->linesize[LUMA],
552  beta, tc, no_p, no_q);
553  }
554  }
555 
556  if(!y)
557  continue;
558 
559  // horizontal filtering luma
560  for (x = x0 ? x0 - 8 : 0; x < x_end2; x += 8) {
561  const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2];
562  const int bs1 = s->horizontal_bs[((x + 4) + y * s->bs_width) >> 2];
563  if (bs0 || bs1) {
564  const int qp = (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1;
565 
566  tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
567  beta_offset = x >= x0 ? cur_beta_offset : left_beta_offset;
568 
569  beta = betatable[av_clip(qp + beta_offset, 0, MAX_QP)];
570  tc[0] = bs0 ? TC_CALC(qp, bs0) : 0;
571  tc[1] = bs1 ? TC_CALC(qp, bs1) : 0;
572  src = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->ps.sps->pixel_shift)];
573  if (pcmf) {
574  no_p[0] = get_pcm(s, x, y - 1);
575  no_p[1] = get_pcm(s, x + 4, y - 1);
576  no_q[0] = get_pcm(s, x, y);
577  no_q[1] = get_pcm(s, x + 4, y);
578  s->hevcdsp.hevc_h_loop_filter_luma_c(src,
579  s->frame->linesize[LUMA],
580  beta, tc, no_p, no_q);
581  } else
582  s->hevcdsp.hevc_h_loop_filter_luma(src,
583  s->frame->linesize[LUMA],
584  beta, tc, no_p, no_q);
585  }
586  }
587  }
588 
589  if (s->ps.sps->chroma_format_idc) {
590  for (chroma = 1; chroma <= 2; chroma++) {
591  int h = 1 << s->ps.sps->hshift[chroma];
592  int v = 1 << s->ps.sps->vshift[chroma];
593 
594  // vertical filtering chroma
595  for (y = y0; y < y_end; y += (8 * v)) {
596  for (x = x0 ? x0 : 8 * h; x < x_end; x += (8 * h)) {
597  const int bs0 = s->vertical_bs[(x + y * s->bs_width) >> 2];
598  const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * s->bs_width) >> 2];
599 
600  if ((bs0 == 2) || (bs1 == 2)) {
601  const int qp0 = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
602  const int qp1 = (get_qPy(s, x - 1, y + (4 * v)) + get_qPy(s, x, y + (4 * v)) + 1) >> 1;
603 
604  c_tc[0] = (bs0 == 2) ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
605  c_tc[1] = (bs1 == 2) ? chroma_tc(s, qp1, chroma, tc_offset) : 0;
606  src = &s->frame->data[chroma][(y >> s->ps.sps->vshift[chroma]) * s->frame->linesize[chroma] + ((x >> s->ps.sps->hshift[chroma]) << s->ps.sps->pixel_shift)];
607  if (pcmf) {
608  no_p[0] = get_pcm(s, x - 1, y);
609  no_p[1] = get_pcm(s, x - 1, y + (4 * v));
610  no_q[0] = get_pcm(s, x, y);
611  no_q[1] = get_pcm(s, x, y + (4 * v));
612  s->hevcdsp.hevc_v_loop_filter_chroma_c(src,
613  s->frame->linesize[chroma],
614  c_tc, no_p, no_q);
615  } else
616  s->hevcdsp.hevc_v_loop_filter_chroma(src,
617  s->frame->linesize[chroma],
618  c_tc, no_p, no_q);
619  }
620  }
621 
622  if(!y)
623  continue;
624 
625  // horizontal filtering chroma
626  tc_offset = x0 ? left_tc_offset : cur_tc_offset;
627  x_end2 = x_end;
628  if (x_end != s->ps.sps->width)
629  x_end2 = x_end - 8 * h;
630  for (x = x0 ? x0 - 8 * h : 0; x < x_end2; x += (8 * h)) {
631  const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2];
632  const int bs1 = s->horizontal_bs[((x + 4 * h) + y * s->bs_width) >> 2];
633  if ((bs0 == 2) || (bs1 == 2)) {
634  const int qp0 = bs0 == 2 ? (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1 : 0;
635  const int qp1 = bs1 == 2 ? (get_qPy(s, x + (4 * h), y - 1) + get_qPy(s, x + (4 * h), y) + 1) >> 1 : 0;
636 
637  c_tc[0] = bs0 == 2 ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
638  c_tc[1] = bs1 == 2 ? chroma_tc(s, qp1, chroma, cur_tc_offset) : 0;
639  src = &s->frame->data[chroma][(y >> s->ps.sps->vshift[1]) * s->frame->linesize[chroma] + ((x >> s->ps.sps->hshift[1]) << s->ps.sps->pixel_shift)];
640  if (pcmf) {
641  no_p[0] = get_pcm(s, x, y - 1);
642  no_p[1] = get_pcm(s, x + (4 * h), y - 1);
643  no_q[0] = get_pcm(s, x, y);
644  no_q[1] = get_pcm(s, x + (4 * h), y);
645  s->hevcdsp.hevc_h_loop_filter_chroma_c(src,
646  s->frame->linesize[chroma],
647  c_tc, no_p, no_q);
648  } else
649  s->hevcdsp.hevc_h_loop_filter_chroma(src,
650  s->frame->linesize[chroma],
651  c_tc, no_p, no_q);
652  }
653  }
654  }
655  }
656  }
657 }
658 
659 static int boundary_strength(const HEVCContext *s, const MvField *curr, const MvField *neigh,
660  const RefPicList *neigh_refPicList)
661 {
662  if (curr->pred_flag == PF_BI && neigh->pred_flag == PF_BI) {
663  // same L0 and L1
664  if (s->ref->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]] &&
665  s->ref->refPicList[0].list[curr->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]] &&
666  neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
667  if ((FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
668  FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
669  (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
670  FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4))
671  return 1;
672  else
673  return 0;
674  } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
675  neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
676  if (FFABS(neigh->mv[0].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
677  FFABS(neigh->mv[1].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 4)
678  return 1;
679  else
680  return 0;
681  } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
682  neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
683  if (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 4 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
684  FFABS(neigh->mv[0].x - curr->mv[1].x) >= 4 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 4)
685  return 1;
686  else
687  return 0;
688  } else {
689  return 1;
690  }
691  } else if ((curr->pred_flag != PF_BI) && (neigh->pred_flag != PF_BI)){ // 1 MV
692  Mv A, B;
693  int ref_A, ref_B;
694 
695  if (curr->pred_flag & 1) {
696  A = curr->mv[0];
697  ref_A = s->ref->refPicList[0].list[curr->ref_idx[0]];
698  } else {
699  A = curr->mv[1];
700  ref_A = s->ref->refPicList[1].list[curr->ref_idx[1]];
701  }
702 
703  if (neigh->pred_flag & 1) {
704  B = neigh->mv[0];
705  ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
706  } else {
707  B = neigh->mv[1];
708  ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
709  }
710 
711  if (ref_A == ref_B) {
712  if (FFABS(A.x - B.x) >= 4 || FFABS(A.y - B.y) >= 4)
713  return 1;
714  else
715  return 0;
716  } else
717  return 1;
718  }
719 
720  return 1;
721 }
722 
724  int log2_trafo_size)
725 {
726  const HEVCContext *s = lc->parent;
727  const MvField *tab_mvf = s->ref->tab_mvf;
728  int log2_min_pu_size = s->ps.sps->log2_min_pu_size;
729  int log2_min_tu_size = s->ps.sps->log2_min_tb_size;
730  int min_pu_width = s->ps.sps->min_pu_width;
731  int min_tu_width = s->ps.sps->min_tb_width;
732  int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
733  (x0 >> log2_min_pu_size)].pred_flag == PF_INTRA;
734  int boundary_upper, boundary_left;
735  int i, j, bs;
736 
737  boundary_upper = y0 > 0 && !(y0 & 7);
738  if (boundary_upper &&
739  ((!s->sh.slice_loop_filter_across_slices_enabled_flag &&
741  (y0 % (1 << s->ps.sps->log2_ctb_size)) == 0) ||
742  (!s->ps.pps->loop_filter_across_tiles_enabled_flag &&
744  (y0 % (1 << s->ps.sps->log2_ctb_size)) == 0)))
745  boundary_upper = 0;
746 
747  if (boundary_upper) {
748  const RefPicList *rpl_top = (lc->boundary_flags & BOUNDARY_UPPER_SLICE) ?
749  ff_hevc_get_ref_list(s, s->ref, x0, y0 - 1) :
750  s->ref->refPicList;
751  int yp_pu = (y0 - 1) >> log2_min_pu_size;
752  int yq_pu = y0 >> log2_min_pu_size;
753  int yp_tu = (y0 - 1) >> log2_min_tu_size;
754  int yq_tu = y0 >> log2_min_tu_size;
755 
756  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
757  int x_pu = (x0 + i) >> log2_min_pu_size;
758  int x_tu = (x0 + i) >> log2_min_tu_size;
759  const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
760  const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
761  uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
762  uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
763 
764  if (curr->pred_flag == PF_INTRA || top->pred_flag == PF_INTRA)
765  bs = 2;
766  else if (curr_cbf_luma || top_cbf_luma)
767  bs = 1;
768  else
769  bs = boundary_strength(s, curr, top, rpl_top);
770  s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
771  }
772  }
773 
774  // bs for vertical TU boundaries
775  boundary_left = x0 > 0 && !(x0 & 7);
776  if (boundary_left &&
777  ((!s->sh.slice_loop_filter_across_slices_enabled_flag &&
779  (x0 % (1 << s->ps.sps->log2_ctb_size)) == 0) ||
780  (!s->ps.pps->loop_filter_across_tiles_enabled_flag &&
782  (x0 % (1 << s->ps.sps->log2_ctb_size)) == 0)))
783  boundary_left = 0;
784 
785  if (boundary_left) {
786  const RefPicList *rpl_left = (lc->boundary_flags & BOUNDARY_LEFT_SLICE) ?
787  ff_hevc_get_ref_list(s, s->ref, x0 - 1, y0) :
788  s->ref->refPicList;
789  int xp_pu = (x0 - 1) >> log2_min_pu_size;
790  int xq_pu = x0 >> log2_min_pu_size;
791  int xp_tu = (x0 - 1) >> log2_min_tu_size;
792  int xq_tu = x0 >> log2_min_tu_size;
793 
794  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
795  int y_pu = (y0 + i) >> log2_min_pu_size;
796  int y_tu = (y0 + i) >> log2_min_tu_size;
797  const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
798  const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
799  uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
800  uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
801 
802  if (curr->pred_flag == PF_INTRA || left->pred_flag == PF_INTRA)
803  bs = 2;
804  else if (curr_cbf_luma || left_cbf_luma)
805  bs = 1;
806  else
807  bs = boundary_strength(s, curr, left, rpl_left);
808  s->vertical_bs[(x0 + (y0 + i) * s->bs_width) >> 2] = bs;
809  }
810  }
811 
812  if (log2_trafo_size > log2_min_pu_size && !is_intra) {
813  const RefPicList *rpl = s->ref->refPicList;
814 
815  // bs for TU internal horizontal PU boundaries
816  for (j = 8; j < (1 << log2_trafo_size); j += 8) {
817  int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
818  int yq_pu = (y0 + j) >> log2_min_pu_size;
819 
820  for (i = 0; i < (1 << log2_trafo_size); i += 4) {
821  int x_pu = (x0 + i) >> log2_min_pu_size;
822  const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
823  const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
824 
825  bs = boundary_strength(s, curr, top, rpl);
826  s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
827  }
828  }
829 
830  // bs for TU internal vertical PU boundaries
831  for (j = 0; j < (1 << log2_trafo_size); j += 4) {
832  int y_pu = (y0 + j) >> log2_min_pu_size;
833 
834  for (i = 8; i < (1 << log2_trafo_size); i += 8) {
835  int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
836  int xq_pu = (x0 + i) >> log2_min_pu_size;
837  const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
838  const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
839 
840  bs = boundary_strength(s, curr, left, rpl);
841  s->vertical_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
842  }
843  }
844  }
845 }
846 
847 #undef LUMA
848 #undef CB
849 #undef CR
850 
851 void ff_hevc_hls_filter(HEVCLocalContext *lc, int x, int y, int ctb_size)
852 {
853  const HEVCContext *const s = lc->parent;
854  int x_end = x >= s->ps.sps->width - ctb_size;
855  int skip = 0;
856  if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
857  (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && !IS_IDR(s)) ||
858  (s->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&
859  s->sh.slice_type != HEVC_SLICE_I) ||
860  (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR &&
861  s->sh.slice_type == HEVC_SLICE_B) ||
862  (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
863  ff_hevc_nal_is_nonref(s->nal_unit_type)))
864  skip = 1;
865 
866  if (!skip)
867  deblocking_filter_CTB(s, x, y);
868  if (s->ps.sps->sao_enabled && !skip) {
869  int y_end = y >= s->ps.sps->height - ctb_size;
870  if (y && x)
871  sao_filter_CTB(lc, s, x - ctb_size, y - ctb_size);
872  if (x && y_end)
873  sao_filter_CTB(lc, s, x - ctb_size, y);
874  if (y && x_end) {
875  sao_filter_CTB(lc, s, x, y - ctb_size);
876  if (s->threads_type & FF_THREAD_FRAME )
877  ff_thread_report_progress(&s->ref->tf, y, 0);
878  }
879  if (x_end && y_end) {
880  sao_filter_CTB(lc, s, x , y);
881  if (s->threads_type & FF_THREAD_FRAME )
882  ff_thread_report_progress(&s->ref->tf, y + ctb_size, 0);
883  }
884  } else if (s->threads_type & FF_THREAD_FRAME && x_end)
885  ff_thread_report_progress(&s->ref->tf, y + ctb_size - 4, 0);
886 }
887 
888 void ff_hevc_hls_filters(HEVCLocalContext *lc, int x_ctb, int y_ctb, int ctb_size)
889 {
890  int x_end = x_ctb >= lc->parent->ps.sps->width - ctb_size;
891  int y_end = y_ctb >= lc->parent->ps.sps->height - ctb_size;
892  if (y_ctb && x_ctb)
893  ff_hevc_hls_filter(lc, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
894  if (y_ctb && x_end)
895  ff_hevc_hls_filter(lc, x_ctb, y_ctb - ctb_size, ctb_size);
896  if (x_ctb && y_end)
897  ff_hevc_hls_filter(lc, x_ctb - ctb_size, y_ctb, ctb_size);
898 }
sao_filter_CTB
static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCContext *s, int x, int y)
Definition: hevc_filter.c:256
A
#define A(x)
Definition: vpx_arith.h:28
FFUMOD
#define FFUMOD(a, b)
Definition: common.h:64
HEVCLocalContext
Definition: hevcdec.h:382
av_clip
#define av_clip
Definition: common.h:98
chroma_tc
static int chroma_tc(const HEVCContext *s, int qp_y, int c_idx, int tc_offset)
Definition: hevc_filter.c:47
ff_hevc_get_ref_list
const RefPicList * ff_hevc_get_ref_list(const HEVCContext *s, const HEVCFrame *ref, int x0, int y0)
Definition: hevc_refs.c:56
restore_tqb_pixels
static void restore_tqb_pixels(const HEVCContext *s, 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: hevc_filter.c:221
SAO_APPLIED
@ SAO_APPLIED
Definition: hevcdec.h:161
SAO_BAND
@ SAO_BAND
Definition: hevcdec.h:159
TC_CALC
#define TC_CALC(qp, bs)
Definition: hevc_filter.c:480
src1
const pixel * src1
Definition: h264pred_template.c:421
copy_pixel
static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
Definition: hevc_filter.c:173
TransformUnit::cu_qp_delta
int cu_qp_delta
Definition: hevcdec.h:326
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
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:297
SAO_EDGE
@ SAO_EDGE
Definition: hevcdec.h:160
TransformUnit::is_cu_qp_delta_coded
uint8_t is_cu_qp_delta_coded
Definition: hevcdec.h:334
RefPicList
Definition: hevcdec.h:189
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:113
BOUNDARY_LEFT_TILE
#define BOUNDARY_LEFT_TILE
Definition: hevcdec.h:432
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: hevc_filter.c:140
ff_hevc_hls_filter
void ff_hevc_hls_filter(HEVCLocalContext *lc, int x, int y, int ctb_size)
Definition: hevc_filter.c:851
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
ff_hevc_deblocking_boundary_strengths
void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, int x0, int y0, int log2_trafo_size)
Definition: hevc_filter.c:723
ff_thread_report_progress
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
Notify later decoding threads when part of their reference picture is ready.
Definition: pthread_frame.c:573
width
#define width
HEVCLocalContext::parent
const struct HEVCContext * parent
Definition: hevcdec.h:390
s
#define s(width, name)
Definition: cbs_vp9.c:198
HEVCSPS::height
int height
Definition: hevc_ps.h:285
ff_hevc_nal_is_nonref
static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type)
Definition: hevcdec.h:614
B
#define B
Definition: huffyuv.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: hevc_filter.c:181
IS_IDR
#define IS_IDR(s)
Definition: hevcdec.h:75
HEVC_SLICE_I
@ HEVC_SLICE_I
Definition: hevc.h:98
AVDISCARD_BIDIR
@ AVDISCARD_BIDIR
discard all bidirectional frames
Definition: defs.h:216
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
if
if(ret)
Definition: filter_design.txt:179
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:219
threadframe.h
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
AV_COPY128
#define AV_COPY128(d, s)
Definition: intreadwrite.h:605
boundary_strength
static int boundary_strength(const HEVCContext *s, const MvField *curr, const MvField *neigh, const RefPicList *neigh_refPicList)
Definition: hevc_filter.c:659
HEVCLocalContext::first_qp_group
uint8_t first_qp_group
Definition: hevcdec.h:387
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:434
AV_COPY64U
#define AV_COPY64U(d, s)
Definition: intreadwrite.h:574
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:296
PF_BI
@ PF_BI
Definition: hevcdec.h:116
get_pcm
static int get_pcm(const HEVCContext *s, int x, int y)
Definition: hevc_filter.c:464
HEVCLocalContext::edge_emu_buffer
uint8_t edge_emu_buffer[(MAX_PB_SIZE+7) *EDGE_EMU_BUFFER_STRIDE *2]
Definition: hevcdec.h:421
SAOParams::offset_val
int16_t offset_val[3][5]
SaoOffsetVal.
Definition: hevcdsp.h:42
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:218
BOUNDARY_UPPER_SLICE
#define BOUNDARY_UPPER_SLICE
Definition: hevcdec.h:433
hevcdec.h
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
CTB
#define CTB(tab, x, y)
Definition: hevc_filter.c:254
MvField
Definition: hevcdec.h:300
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
HEVCContext::ps
HEVCParamSets ps
Definition: hevcdec.h:461
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:303
SAOParams::eo_class
int eo_class[3]
sao_eo_class
Definition: hevcdsp.h:40
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1593
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:217
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
DEFAULT_INTRA_TC_OFFSET
#define DEFAULT_INTRA_TC_OFFSET
Definition: hevcdec.h:50
HEVCParamSets::sps
const HEVCSPS * sps
Definition: hevc_ps.h:448
internal.h
MAX_PB_SIZE
#define MAX_PB_SIZE
Definition: hevcdsp.h:32
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
HEVCLocalContext::qp_y
int8_t qp_y
Definition: hevcdec.h:407
HEVCSPS::width
int width
Definition: hevc_ps.h:284
len
int len
Definition: vorbis_enc_data.h:426
SAOParams
Definition: hevcdsp.h:34
pos
unsigned int pos
Definition: spdifenc.c:413
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:437
ff_hevc_hls_filters
void ff_hevc_hls_filters(HEVCLocalContext *lc, int x_ctb, int y_ctb, int ctb_size)
Definition: hevc_filter.c:888
HEVCContext
Definition: hevcdec.h:440
HEVCLocalContext::qPy_pred
int qPy_pred
Definition: hevcdec.h:410
copy_CTB_to_hv
static void copy_CTB_to_hv(const HEVCContext *s, 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: hevc_filter.c:201
SAOParams::type_idx
uint8_t type_idx[3]
sao_type_idx
Definition: hevcdsp.h:44
ff_hevc_set_qPy
void ff_hevc_set_qPy(HEVCLocalContext *lc, int xBase, int yBase, int log2_cb_size)
Definition: hevc_filter.c:119
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:191
HEVCLocalContext::tu
TransformUnit tu
Definition: hevcdec.h:412
MAX_QP
#define MAX_QP
Definition: hevcdec.h:49
MvField::mv
Mv mv[2]
mvL0, vvL1
Definition: hevcdec.h:301
tc
#define tc
Definition: regdef.h:69
Mv
Definition: hevcdec.h:295
MvField::ref_idx
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition: hevcdec.h:302
get_qPy_pred
static int get_qPy_pred(HEVCLocalContext *lc, const HEVCContext *s, int xBase, int yBase, int log2_cb_size)
Definition: hevc_filter.c:76
deblocking_filter_CTB
static void deblocking_filter_CTB(const HEVCContext *s, int x0, int y0)
Definition: hevc_filter.c:485
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:431
SAOParams::band_position
uint8_t band_position[3]
sao_band_position
Definition: hevcdsp.h:38
tctable
static const uint8_t tctable[54]
Definition: hevc_filter.c:35
AVDISCARD_NONREF
@ AVDISCARD_NONREF
discard all non reference
Definition: defs.h:215
get_qPy
static int get_qPy(const HEVCContext *s, int xC, int yC)
Definition: hevc_filter.c:132
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
LUMA
#define LUMA
Definition: hevc_filter.c:31
betatable
static const uint8_t betatable[52]
Definition: hevc_filter.c:41