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