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