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