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