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(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(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
77 {
78  HEVCLocalContext *lc = s->HEVClc;
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(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
120 {
121  int qp_y = get_qPy_pred(s, xBase, yBase, log2_cb_size);
122 
123  if (s->HEVClc->tu.cu_qp_delta != 0) {
124  int off = s->ps.sps->qp_bd_offset;
125  s->HEVClc->qp_y = FFUMOD(qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off,
126  52 + off) - off;
127  } else
128  s->HEVClc->qp_y = qp_y;
129 }
130 
131 static int get_qPy(HEVCContext *s, int xC, int yC)
132 {
133  int log2_min_cb_size = s->ps.sps->log2_min_cb_size;
134  int x = xC >> log2_min_cb_size;
135  int y = yC >> log2_min_cb_size;
136  return s->qp_y_tab[x + y * s->ps.sps->min_cb_width];
137 }
138 
139 static void copy_CTB(uint8_t *dst, const uint8_t *src, int width, int height,
140  ptrdiff_t stride_dst, ptrdiff_t stride_src)
141 {
142  int i, j;
143 
144  if (((intptr_t)dst | (intptr_t)src | stride_dst | stride_src) & 15) {
145  for (i = 0; i < height; i++) {
146  for (j = 0; j < width - 7; j+=8)
147  AV_COPY64U(dst+j, src+j);
148  dst += stride_dst;
149  src += stride_src;
150  }
151  if (width&7) {
152  dst += ((width>>3)<<3) - stride_dst * height;
153  src += ((width>>3)<<3) - stride_src * height;
154  width &= 7;
155  for (i = 0; i < height; i++) {
156  for (j = 0; j < width; j++)
157  dst[j] = src[j];
158  dst += stride_dst;
159  src += stride_src;
160  }
161  }
162  } else {
163  for (i = 0; i < height; i++) {
164  for (j = 0; j < width; j+=16)
165  AV_COPY128(dst+j, src+j);
166  dst += stride_dst;
167  src += stride_src;
168  }
169  }
170 }
171 
172 static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
173 {
174  if (pixel_shift)
175  *(uint16_t *)dst = *(uint16_t *)src;
176  else
177  *dst = *src;
178 }
179 
180 static void copy_vert(uint8_t *dst, const uint8_t *src,
181  int pixel_shift, int height,
182  ptrdiff_t stride_dst, ptrdiff_t stride_src)
183 {
184  int i;
185  if (pixel_shift == 0) {
186  for (i = 0; i < height; i++) {
187  *dst = *src;
188  dst += stride_dst;
189  src += stride_src;
190  }
191  } else {
192  for (i = 0; i < height; i++) {
193  *(uint16_t *)dst = *(uint16_t *)src;
194  dst += stride_dst;
195  src += stride_src;
196  }
197  }
198 }
199 
200 static void copy_CTB_to_hv(HEVCContext *s, const uint8_t *src,
201  ptrdiff_t stride_src, int x, int y, int width, int height,
202  int c_idx, int x_ctb, int y_ctb)
203 {
204  int sh = s->ps.sps->pixel_shift;
205  int w = s->ps.sps->width >> s->ps.sps->hshift[c_idx];
206  int h = s->ps.sps->height >> s->ps.sps->vshift[c_idx];
207 
208  /* copy horizontal edges */
209  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
210  src, width << sh);
211  memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
212  src + stride_src * (height - 1), width << sh);
213 
214  /* copy vertical edges */
215  copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
216 
217  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);
218 }
219 
221  uint8_t *src1, const uint8_t *dst1,
222  ptrdiff_t stride_src, ptrdiff_t stride_dst,
223  int x0, int y0, int width, int height, int c_idx)
224 {
225  if ( s->ps.pps->transquant_bypass_enable_flag ||
226  (s->ps.sps->pcm.loop_filter_disable_flag && s->ps.sps->pcm_enabled_flag)) {
227  int x, y;
228  int min_pu_size = 1 << s->ps.sps->log2_min_pu_size;
229  int hshift = s->ps.sps->hshift[c_idx];
230  int vshift = s->ps.sps->vshift[c_idx];
231  int x_min = ((x0 ) >> s->ps.sps->log2_min_pu_size);
232  int y_min = ((y0 ) >> s->ps.sps->log2_min_pu_size);
233  int x_max = ((x0 + width ) >> s->ps.sps->log2_min_pu_size);
234  int y_max = ((y0 + height) >> s->ps.sps->log2_min_pu_size);
235  int len = (min_pu_size >> hshift) << s->ps.sps->pixel_shift;
236  for (y = y_min; y < y_max; y++) {
237  for (x = x_min; x < x_max; x++) {
238  if (s->is_pcm[y * s->ps.sps->min_pu_width + x]) {
239  int n;
240  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);
241  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);
242  for (n = 0; n < (min_pu_size >> vshift); n++) {
243  memcpy(src, dst, len);
244  src += stride_src;
245  dst += stride_dst;
246  }
247  }
248  }
249  }
250  }
251 }
252 
253 #define CTB(tab, x, y) ((tab)[(y) * s->ps.sps->ctb_width + (x)])
254 
255 static void sao_filter_CTB(HEVCContext *s, int x, int y)
256 {
257  static const uint8_t sao_tab[8] = { 0, 1, 2, 2, 3, 3, 4, 4 };
258  HEVCLocalContext *lc = s->HEVClc;
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(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(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  HEVCLocalContext *lc = s->HEVClc;
727  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  MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
760  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  MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
798  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  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  MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
823  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  MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
838  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(HEVCContext *s, int x, int y, int ctb_size)
852 {
853  int x_end = x >= s->ps.sps->width - ctb_size;
854  int skip = 0;
855  if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
856  (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && !IS_IDR(s)) ||
857  (s->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&
858  s->sh.slice_type != HEVC_SLICE_I) ||
859  (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR &&
860  s->sh.slice_type == HEVC_SLICE_B) ||
861  (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
862  ff_hevc_nal_is_nonref(s->nal_unit_type)))
863  skip = 1;
864 
865  if (!skip)
866  deblocking_filter_CTB(s, x, y);
867  if (s->ps.sps->sao_enabled && !skip) {
868  int y_end = y >= s->ps.sps->height - ctb_size;
869  if (y && x)
870  sao_filter_CTB(s, x - ctb_size, y - ctb_size);
871  if (x && y_end)
872  sao_filter_CTB(s, x - ctb_size, y);
873  if (y && x_end) {
874  sao_filter_CTB(s, x, y - ctb_size);
875  if (s->threads_type & FF_THREAD_FRAME )
876  ff_thread_report_progress(&s->ref->tf, y, 0);
877  }
878  if (x_end && y_end) {
879  sao_filter_CTB(s, x , y);
880  if (s->threads_type & FF_THREAD_FRAME )
881  ff_thread_report_progress(&s->ref->tf, y + ctb_size, 0);
882  }
883  } else if (s->threads_type & FF_THREAD_FRAME && x_end)
884  ff_thread_report_progress(&s->ref->tf, y + ctb_size - 4, 0);
885 }
886 
887 void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
888 {
889  int x_end = x_ctb >= s->ps.sps->width - ctb_size;
890  int y_end = y_ctb >= s->ps.sps->height - ctb_size;
891  if (y_ctb && x_ctb)
892  ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
893  if (y_ctb && x_end)
894  ff_hevc_hls_filter(s, x_ctb, y_ctb - ctb_size, ctb_size);
895  if (x_ctb && y_end)
896  ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb, ctb_size);
897 }
FFUMOD
#define FFUMOD(a, b)
Definition: common.h:56
HEVCLocalContext
Definition: hevcdec.h:424
av_clip
#define av_clip
Definition: common.h:95
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:58
ff_hevc_set_qPy
void ff_hevc_set_qPy(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
Definition: hevc_filter.c:119
SAO_APPLIED
@ SAO_APPLIED
Definition: hevcdec.h:213
SAO_BAND
@ SAO_BAND
Definition: hevcdec.h:211
ff_hevc_hls_filter
void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size)
Definition: hevc_filter.c:851
TC_CALC
#define TC_CALC(qp, bs)
Definition: hevc_filter.c:480
src1
const pixel * src1
Definition: h264pred_template.c:421
sao_filter_CTB
static void sao_filter_CTB(HEVCContext *s, int x, int y)
Definition: hevc_filter.c:255
copy_pixel
static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
Definition: hevc_filter.c:172
copy_CTB_to_hv
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:200
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:1635
ff_hevc_hls_filters
void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
Definition: hevc_filter.c:887
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:339
SAO_EDGE
@ SAO_EDGE
Definition: hevcdec.h:212
MvField::mv
Mv mv[2]
Definition: hevcdec.h:343
TransformUnit::is_cu_qp_delta_coded
uint8_t is_cu_qp_delta_coded
Definition: hevcdec.h:376
RefPicList
Definition: hevcdec.h:236
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:165
A
#define A(x)
Definition: vp56_arith.h:28
BOUNDARY_LEFT_TILE
#define BOUNDARY_LEFT_TILE
Definition: hevcdec.h:459
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:139
get_qPy_pred
static int get_qPy_pred(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
Definition: hevc_filter.c:76
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
restore_tqb_pixels
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:220
MvField::ref_idx
int8_t ref_idx[2]
Definition: hevcdec.h:344
ff_hevc_deblocking_boundary_strengths
void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0, int log2_trafo_size)
Definition: hevc_filter.c:723
SAOParams::eo_class
int eo_class[3]
sao_eo_class
Definition: hevcdsp.h:40
SAOParams::type_idx
uint8_t type_idx[3]
sao_type_idx
Definition: hevcdsp.h:44
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:595
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:256
ff_hevc_nal_is_nonref
static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type)
Definition: hevcdec.h:640
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:180
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:51
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
if
if(ret)
Definition: filter_design.txt:179
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:54
threadframe.h
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
AV_COPY128
#define AV_COPY128(d, s)
Definition: intreadwrite.h:609
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:429
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:461
AV_COPY64U
#define AV_COPY64U(d, s)
Definition: intreadwrite.h:576
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:338
PF_BI
@ PF_BI
Definition: hevcdec.h:168
HEVCLocalContext::edge_emu_buffer
uint8_t edge_emu_buffer[(MAX_PB_SIZE+7) *EDGE_EMU_BUFFER_STRIDE *2]
Definition: hevcdec.h:448
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:53
BOUNDARY_UPPER_SLICE
#define BOUNDARY_UPPER_SLICE
Definition: hevcdec.h:460
hevcdec.h
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
CTB
#define CTB(tab, x, y)
Definition: hevc_filter.c:253
MvField
Definition: hevcdec.h:342
height
#define height
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:345
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1474
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
AVDISCARD_NONINTRA
@ AVDISCARD_NONINTRA
discard all non intra frames
Definition: defs.h:52
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
SAOParams::band_position
uint8_t band_position[3]
sao_band_position
Definition: hevcdsp.h:38
DEFAULT_INTRA_TC_OFFSET
#define DEFAULT_INTRA_TC_OFFSET
Definition: hevcdec.h:50
internal.h
MAX_PB_SIZE
#define MAX_PB_SIZE
Definition: hevcdsp.h:32
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:238
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
get_pcm
static int get_pcm(HEVCContext *s, int x, int y)
Definition: hevc_filter.c:464
SAOParams
Definition: hevcdsp.h:34
get_qPy
static int get_qPy(HEVCContext *s, int xC, int yC)
Definition: hevc_filter.c:131
pos
unsigned int pos
Definition: spdifenc.c:412
chroma_tc
static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
Definition: hevc_filter.c:47
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:464
B
#define B
Definition: huffyuvdsp.h:32
HEVCContext
Definition: hevcdec.h:467
HEVCLocalContext::qPy_pred
int qPy_pred
Definition: hevcdec.h:437
HEVCLocalContext::tu
TransformUnit tu
Definition: hevcdec.h:439
MAX_QP
#define MAX_QP
Definition: hevcdec.h:49
tc
#define tc
Definition: regdef.h:69
Mv
Definition: hevcdec.h:337
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
SAOParams::offset_val
int16_t offset_val[3][5]
SaoOffsetVal.
Definition: hevcdsp.h:42
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:458
tctable
static const uint8_t tctable[54]
Definition: hevc_filter.c:35
AVDISCARD_NONREF
@ AVDISCARD_NONREF
discard all non reference
Definition: defs.h:50
deblocking_filter_CTB
static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
Definition: hevc_filter.c:485
LUMA
#define LUMA
Definition: hevc_filter.c:31
betatable
static const uint8_t betatable[52]
Definition: hevc_filter.c:41