cavs.c
Go to the documentation of this file.
1 /*
2  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
3  * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
25  * @author Stefan Gehrer <stefan.gehrer@gmx.de>
26  */
27 
28 #include "avcodec.h"
29 #include "get_bits.h"
30 #include "golomb.h"
31 #include "h264chroma.h"
32 #include "mathops.h"
33 #include "cavs.h"
34 
35 static const uint8_t alpha_tab[64] = {
36  0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
37  4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
38  22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
39  46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
40 };
41 
42 static const uint8_t beta_tab[64] = {
43  0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
44  2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
45  6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
46  15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
47 };
48 
49 static const uint8_t tc_tab[64] = {
50  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
52  2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
53  5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
54 };
55 
56 /** mark block as unavailable, i.e. out of picture
57  or not yet decoded */
58 static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
59 
60 static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
61 static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
62 static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
63 static const int8_t top_modifier_c[7] = { 4, 1, -1, -1, 4, 6, 6 };
64 
65 /*****************************************************************************
66  *
67  * in-loop deblocking filter
68  *
69  ****************************************************************************/
70 
71 static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
72 {
73  if ((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
74  return 2;
75  if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4))
76  return 1;
77  if (b) {
78  mvP += MV_BWD_OFFS;
79  mvQ += MV_BWD_OFFS;
80  if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4))
81  return 1;
82  } else {
83  if (mvP->ref != mvQ->ref)
84  return 1;
85  }
86  return 0;
87 }
88 
89 #define SET_PARAMS \
90  alpha = alpha_tab[av_clip(qp_avg + h->alpha_offset, 0, 63)]; \
91  beta = beta_tab[av_clip(qp_avg + h->beta_offset, 0, 63)]; \
92  tc = tc_tab[av_clip(qp_avg + h->alpha_offset, 0, 63)];
93 
94 /**
95  * in-loop deblocking filter for a single macroblock
96  *
97  * boundary strength (bs) mapping:
98  *
99  * --4---5--
100  * 0 2 |
101  * | 6 | 7 |
102  * 1 3 |
103  * ---------
104  *
105  */
106 void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
107 {
108  uint8_t bs[8];
109  int qp_avg, alpha, beta, tc;
110  int i;
111 
112  /* save un-deblocked lines */
113  h->topleft_border_y = h->top_border_y[h->mbx * 16 + 15];
114  h->topleft_border_u = h->top_border_u[h->mbx * 10 + 8];
115  h->topleft_border_v = h->top_border_v[h->mbx * 10 + 8];
116  memcpy(&h->top_border_y[h->mbx * 16], h->cy + 15 * h->l_stride, 16);
117  memcpy(&h->top_border_u[h->mbx * 10 + 1], h->cu + 7 * h->c_stride, 8);
118  memcpy(&h->top_border_v[h->mbx * 10 + 1], h->cv + 7 * h->c_stride, 8);
119  for (i = 0; i < 8; i++) {
120  h->left_border_y[i * 2 + 1] = *(h->cy + 15 + (i * 2 + 0) * h->l_stride);
121  h->left_border_y[i * 2 + 2] = *(h->cy + 15 + (i * 2 + 1) * h->l_stride);
122  h->left_border_u[i + 1] = *(h->cu + 7 + i * h->c_stride);
123  h->left_border_v[i + 1] = *(h->cv + 7 + i * h->c_stride);
124  }
125  if (!h->loop_filter_disable) {
126  /* determine bs */
127  if (mb_type == I_8X8)
128  memset(bs, 2, 8);
129  else{
130  memset(bs, 0, 8);
131  if (ff_cavs_partition_flags[mb_type] & SPLITV) {
132  bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
133  bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
134  }
135  if (ff_cavs_partition_flags[mb_type] & SPLITH) {
136  bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
137  bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
138  }
139  bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8);
140  bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8);
141  bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
142  bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
143  }
144  if (AV_RN64(bs)) {
145  if (h->flags & A_AVAIL) {
146  qp_avg = (h->qp + h->left_qp + 1) >> 1;
147  SET_PARAMS;
148  h->cdsp.cavs_filter_lv(h->cy, h->l_stride, alpha, beta, tc, bs[0], bs[1]);
149  h->cdsp.cavs_filter_cv(h->cu, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
150  h->cdsp.cavs_filter_cv(h->cv, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
151  }
152  qp_avg = h->qp;
153  SET_PARAMS;
154  h->cdsp.cavs_filter_lv(h->cy + 8, h->l_stride, alpha, beta, tc, bs[2], bs[3]);
155  h->cdsp.cavs_filter_lh(h->cy + 8 * h->l_stride, h->l_stride, alpha, beta, tc, bs[6], bs[7]);
156 
157  if (h->flags & B_AVAIL) {
158  qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
159  SET_PARAMS;
160  h->cdsp.cavs_filter_lh(h->cy, h->l_stride, alpha, beta, tc, bs[4], bs[5]);
161  h->cdsp.cavs_filter_ch(h->cu, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
162  h->cdsp.cavs_filter_ch(h->cv, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
163  }
164  }
165  }
166  h->left_qp = h->qp;
167  h->top_qp[h->mbx] = h->qp;
168 }
169 
170 #undef SET_PARAMS
171 
172 /*****************************************************************************
173  *
174  * spatial intra prediction
175  *
176  ****************************************************************************/
177 
179  uint8_t **left, int block)
180 {
181  int i;
182 
183  switch (block) {
184  case 0:
185  *left = h->left_border_y;
186  h->left_border_y[0] = h->left_border_y[1];
187  memset(&h->left_border_y[17], h->left_border_y[16], 9);
188  memcpy(&top[1], &h->top_border_y[h->mbx * 16], 16);
189  top[17] = top[16];
190  top[0] = top[1];
191  if ((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
192  h->left_border_y[0] = top[0] = h->topleft_border_y;
193  break;
194  case 1:
195  *left = h->intern_border_y;
196  for (i = 0; i < 8; i++)
197  h->intern_border_y[i + 1] = *(h->cy + 7 + i * h->l_stride);
198  memset(&h->intern_border_y[9], h->intern_border_y[8], 9);
199  h->intern_border_y[0] = h->intern_border_y[1];
200  memcpy(&top[1], &h->top_border_y[h->mbx * 16 + 8], 8);
201  if (h->flags & C_AVAIL)
202  memcpy(&top[9], &h->top_border_y[(h->mbx + 1) * 16], 8);
203  else
204  memset(&top[9], top[8], 9);
205  top[17] = top[16];
206  top[0] = top[1];
207  if (h->flags & B_AVAIL)
208  h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx * 16 + 7];
209  break;
210  case 2:
211  *left = &h->left_border_y[8];
212  memcpy(&top[1], h->cy + 7 * h->l_stride, 16);
213  top[17] = top[16];
214  top[0] = top[1];
215  if (h->flags & A_AVAIL)
216  top[0] = h->left_border_y[8];
217  break;
218  case 3:
219  *left = &h->intern_border_y[8];
220  for (i = 0; i < 8; i++)
221  h->intern_border_y[i + 9] = *(h->cy + 7 + (i + 8) * h->l_stride);
222  memset(&h->intern_border_y[17], h->intern_border_y[16], 9);
223  memcpy(&top[0], h->cy + 7 + 7 * h->l_stride, 9);
224  memset(&top[9], top[8], 9);
225  break;
226  }
227 }
228 
230 {
231  /* extend borders by one pixel */
232  h->left_border_u[9] = h->left_border_u[8];
233  h->left_border_v[9] = h->left_border_v[8];
234  h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
235  h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
236  if (h->mbx && h->mby) {
237  h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
238  h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
239  } else {
240  h->left_border_u[0] = h->left_border_u[1];
241  h->left_border_v[0] = h->left_border_v[1];
242  h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
243  h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
244  }
245 }
246 
247 static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
248 {
249  int y;
250  uint64_t a = AV_RN64(&top[1]);
251  for (y = 0; y < 8; y++) {
252  *((uint64_t *)(d + y * stride)) = a;
253  }
254 }
255 
256 static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
257 {
258  int y;
259  uint64_t a;
260  for (y = 0; y < 8; y++) {
261  a = left[y + 1] * 0x0101010101010101ULL;
262  *((uint64_t *)(d + y * stride)) = a;
263  }
264 }
265 
266 static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
267 {
268  int y;
269  uint64_t a = 0x8080808080808080ULL;
270  for (y = 0; y < 8; y++)
271  *((uint64_t *)(d + y * stride)) = a;
272 }
273 
274 static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
275 {
276  int x, y, ia;
277  int ih = 0;
278  int iv = 0;
279  const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
280 
281  for (x = 0; x < 4; x++) {
282  ih += (x + 1) * (top [5 + x] - top [3 - x]);
283  iv += (x + 1) * (left[5 + x] - left[3 - x]);
284  }
285  ia = (top[8] + left[8]) << 4;
286  ih = (17 * ih + 16) >> 5;
287  iv = (17 * iv + 16) >> 5;
288  for (y = 0; y < 8; y++)
289  for (x = 0; x < 8; x++)
290  d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
291 }
292 
293 #define LOWPASS(ARRAY,INDEX) \
294  ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
295 
296 static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
297 {
298  int x, y;
299  for (y = 0; y < 8; y++)
300  for (x = 0; x < 8; x++)
301  d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
302 }
303 
304 static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
305 {
306  int x, y;
307  for (y = 0; y < 8; y++)
308  for (x = 0; x < 8; x++)
309  d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
310 }
311 
312 static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
313 {
314  int x, y;
315  for (y = 0; y < 8; y++)
316  for (x = 0; x < 8; x++)
317  if (x == y)
318  d[y * stride + x] = (left[1] + 2 * top[0] + top[1] + 2) >> 2;
319  else if (x > y)
320  d[y * stride + x] = LOWPASS(top, x - y);
321  else
322  d[y * stride + x] = LOWPASS(left, y - x);
323 }
324 
325 static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
326 {
327  int x, y;
328  for (y = 0; y < 8; y++)
329  for (x = 0; x < 8; x++)
330  d[y * stride + x] = LOWPASS(left, y + 1);
331 }
332 
333 static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
334 {
335  int x, y;
336  for (y = 0; y < 8; y++)
337  for (x = 0; x < 8; x++)
338  d[y * stride + x] = LOWPASS(top, x + 1);
339 }
340 
341 #undef LOWPASS
342 
343 static inline void modify_pred(const int8_t *mod_table, int *mode)
344 {
345  *mode = mod_table[*mode];
346  if (*mode < 0) {
347  av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
348  *mode = 0;
349  }
350 }
351 
352 void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
353 {
354  /* save pred modes before they get modified */
355  h->pred_mode_Y[3] = h->pred_mode_Y[5];
356  h->pred_mode_Y[6] = h->pred_mode_Y[8];
357  h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
358  h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
359 
360  /* modify pred modes according to availability of neighbour samples */
361  if (!(h->flags & A_AVAIL)) {
364  modify_pred(left_modifier_c, pred_mode_uv);
365  }
366  if (!(h->flags & B_AVAIL)) {
369  modify_pred(top_modifier_c, pred_mode_uv);
370  }
371 }
372 
373 /*****************************************************************************
374  *
375  * motion compensation
376  *
377  ****************************************************************************/
378 
379 static inline void mc_dir_part(AVSContext *h, AVFrame *pic,
380  int chroma_height,int delta,int list,uint8_t *dest_y,
381  uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset,
382  int src_y_offset,qpel_mc_func *qpix_op,
384 {
385  const int mx= mv->x + src_x_offset*8;
386  const int my= mv->y + src_y_offset*8;
387  const int luma_xy= (mx&3) + ((my&3)<<2);
388  uint8_t * src_y = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
389  uint8_t * src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
390  uint8_t * src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
391  int extra_width = 0;
392  int extra_height= extra_width;
393  int emu=0;
394  const int full_mx= mx>>2;
395  const int full_my= my>>2;
396  const int pic_width = 16*h->mb_width;
397  const int pic_height = 16*h->mb_height;
398 
399  if (!pic->data[0])
400  return;
401  if(mx&7) extra_width -= 3;
402  if(my&7) extra_height -= 3;
403 
404  if( full_mx < 0-extra_width
405  || full_my < 0-extra_height
406  || full_mx + 16/*FIXME*/ > pic_width + extra_width
407  || full_my + 16/*FIXME*/ > pic_height + extra_height){
408  h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,
409  16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
410  src_y= h->edge_emu_buffer + 2 + 2*h->l_stride;
411  emu=1;
412  }
413 
414  qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps?
415 
416  if(emu){
417  h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->c_stride,
418  9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
419  src_cb= h->edge_emu_buffer;
420  }
421  chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7);
422 
423  if(emu){
424  h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->c_stride,
425  9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
426  src_cr= h->edge_emu_buffer;
427  }
428  chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7);
429 }
430 
431 static inline void mc_part_std(AVSContext *h,int chroma_height,int delta,
432  uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr,
433  int x_offset, int y_offset,qpel_mc_func *qpix_put,
434  h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg,
435  h264_chroma_mc_func chroma_avg, cavs_vector *mv)
436 {
437  qpel_mc_func *qpix_op= qpix_put;
438  h264_chroma_mc_func chroma_op= chroma_put;
439 
440  dest_y += 2*x_offset + 2*y_offset*h->l_stride;
441  dest_cb += x_offset + y_offset*h->c_stride;
442  dest_cr += x_offset + y_offset*h->c_stride;
443  x_offset += 8*h->mbx;
444  y_offset += 8*h->mby;
445 
446  if(mv->ref >= 0){
447  AVFrame *ref = h->DPB[mv->ref].f;
448  mc_dir_part(h, ref, chroma_height, delta, 0,
449  dest_y, dest_cb, dest_cr, x_offset, y_offset,
450  qpix_op, chroma_op, mv);
451 
452  qpix_op= qpix_avg;
453  chroma_op= chroma_avg;
454  }
455 
456  if((mv+MV_BWD_OFFS)->ref >= 0){
457  AVFrame *ref = h->DPB[0].f;
458  mc_dir_part(h, ref, chroma_height, delta, 1,
459  dest_y, dest_cb, dest_cr, x_offset, y_offset,
460  qpix_op, chroma_op, mv+MV_BWD_OFFS);
461  }
462 }
463 
464 void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) {
465  if(ff_cavs_partition_flags[mb_type] == 0){ // 16x16
466  mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
471  &h->mv[MV_FWD_X0]);
472  }else{
473  mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
478  &h->mv[MV_FWD_X0]);
479  mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
484  &h->mv[MV_FWD_X1]);
485  mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
490  &h->mv[MV_FWD_X2]);
491  mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
496  &h->mv[MV_FWD_X3]);
497  }
498 }
499 
500 /*****************************************************************************
501  *
502  * motion vector prediction
503  *
504  ****************************************************************************/
505 
506 static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) {
507  int den = h->scale_den[src->ref];
508 
509  *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9;
510  *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9;
511 }
512 
513 static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP,
514  cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC) {
515  int ax, ay, bx, by, cx, cy;
516  int len_ab, len_bc, len_ca, len_mid;
517 
518  /* scale candidates according to their temporal span */
519  scale_mv(h, &ax, &ay, mvA, mvP->dist);
520  scale_mv(h, &bx, &by, mvB, mvP->dist);
521  scale_mv(h, &cx, &cy, mvC, mvP->dist);
522  /* find the geometrical median of the three candidates */
523  len_ab = abs(ax - bx) + abs(ay - by);
524  len_bc = abs(bx - cx) + abs(by - cy);
525  len_ca = abs(cx - ax) + abs(cy - ay);
526  len_mid = mid_pred(len_ab, len_bc, len_ca);
527  if(len_mid == len_ab) {
528  mvP->x = cx;
529  mvP->y = cy;
530  } else if(len_mid == len_bc) {
531  mvP->x = ax;
532  mvP->y = ay;
533  } else {
534  mvP->x = bx;
535  mvP->y = by;
536  }
537 }
538 
539 void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
540  enum cavs_mv_pred mode, enum cavs_block size, int ref) {
541  cavs_vector *mvP = &h->mv[nP];
542  cavs_vector *mvA = &h->mv[nP-1];
543  cavs_vector *mvB = &h->mv[nP-4];
544  cavs_vector *mvC = &h->mv[nC];
545  const cavs_vector *mvP2 = NULL;
546 
547  mvP->ref = ref;
548  mvP->dist = h->dist[mvP->ref];
549  if(mvC->ref == NOT_AVAIL)
550  mvC = &h->mv[nP-5]; // set to top-left (mvD)
551  if((mode == MV_PRED_PSKIP) &&
552  ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) ||
553  ((mvA->x | mvA->y | mvA->ref) == 0) ||
554  ((mvB->x | mvB->y | mvB->ref) == 0) )) {
555  mvP2 = &un_mv;
556  /* if there is only one suitable candidate, take it */
557  } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) {
558  mvP2= mvA;
559  } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) {
560  mvP2= mvB;
561  } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) {
562  mvP2= mvC;
563  } else if(mode == MV_PRED_LEFT && mvA->ref == ref){
564  mvP2= mvA;
565  } else if(mode == MV_PRED_TOP && mvB->ref == ref){
566  mvP2= mvB;
567  } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){
568  mvP2= mvC;
569  }
570  if(mvP2){
571  mvP->x = mvP2->x;
572  mvP->y = mvP2->y;
573  }else
574  mv_pred_median(h, mvP, mvA, mvB, mvC);
575 
576  if(mode < MV_PRED_PSKIP) {
577  mvP->x += get_se_golomb(&h->gb);
578  mvP->y += get_se_golomb(&h->gb);
579  }
580  set_mvs(mvP,size);
581 }
582 
583 /*****************************************************************************
584  *
585  * macroblock level
586  *
587  ****************************************************************************/
588 
589 /**
590  * initialise predictors for motion vectors and intra prediction
591  */
593  int i;
594 
595  /* copy predictors from top line (MB B and C) into cache */
596  for(i=0;i<3;i++) {
597  h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i];
598  h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i];
599  }
600  h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0];
601  h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1];
602  /* clear top predictors if MB B is not available */
603  if(!(h->flags & B_AVAIL)) {
604  h->mv[MV_FWD_B2] = un_mv;
605  h->mv[MV_FWD_B3] = un_mv;
606  h->mv[MV_BWD_B2] = un_mv;
607  h->mv[MV_BWD_B3] = un_mv;
608  h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
609  h->flags &= ~(C_AVAIL|D_AVAIL);
610  } else if(h->mbx) {
611  h->flags |= D_AVAIL;
612  }
613  if(h->mbx == h->mb_width-1) //MB C not available
614  h->flags &= ~C_AVAIL;
615  /* clear top-right predictors if MB C is not available */
616  if(!(h->flags & C_AVAIL)) {
617  h->mv[MV_FWD_C2] = un_mv;
618  h->mv[MV_BWD_C2] = un_mv;
619  }
620  /* clear top-left predictors if MB D is not available */
621  if(!(h->flags & D_AVAIL)) {
622  h->mv[MV_FWD_D3] = un_mv;
623  h->mv[MV_BWD_D3] = un_mv;
624  }
625 }
626 
627 /**
628  * save predictors for later macroblocks and increase
629  * macroblock address
630  * @return 0 if end of frame is reached, 1 otherwise
631  */
633  int i;
634 
635  h->flags |= A_AVAIL;
636  h->cy += 16;
637  h->cu += 8;
638  h->cv += 8;
639  /* copy mvs as predictors to the left */
640  for(i=0;i<=20;i+=4)
641  h->mv[i] = h->mv[i+2];
642  /* copy bottom mvs from cache to top line */
643  h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2];
644  h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3];
645  h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2];
646  h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3];
647  /* next MB address */
648  h->mbidx++;
649  h->mbx++;
650  if(h->mbx == h->mb_width) { //new mb line
651  h->flags = B_AVAIL|C_AVAIL;
652  /* clear left pred_modes */
653  h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
654  /* clear left mv predictors */
655  for(i=0;i<=20;i+=4)
656  h->mv[i] = un_mv;
657  h->mbx = 0;
658  h->mby++;
659  /* re-calculate sample pointers */
660  h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
661  h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride;
662  h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride;
663  if(h->mby == h->mb_height) { //frame end
664  return 0;
665  }
666  }
667  return 1;
668 }
669 
670 /*****************************************************************************
671  *
672  * frame level
673  *
674  ****************************************************************************/
675 
677  int i;
678 
679  /* clear some predictors */
680  for(i=0;i<=20;i+=4)
681  h->mv[i] = un_mv;
683  set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
685  set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
686  h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
687  h->cy = h->cur.f->data[0];
688  h->cu = h->cur.f->data[1];
689  h->cv = h->cur.f->data[2];
690  h->l_stride = h->cur.f->linesize[0];
691  h->c_stride = h->cur.f->linesize[1];
692  h->luma_scan[2] = 8*h->l_stride;
693  h->luma_scan[3] = 8*h->l_stride+8;
694  h->mbx = h->mby = h->mbidx = 0;
695  h->flags = 0;
696 
697  return 0;
698 }
699 
700 /*****************************************************************************
701  *
702  * headers and interface
703  *
704  ****************************************************************************/
705 
706 /**
707  * some predictions require data from the top-neighbouring macroblock.
708  * this data has to be stored for one complete row of macroblocks
709  * and this storage space is allocated here
710  */
712  /* alloc top line of predictors */
713  h->top_qp = av_mallocz( h->mb_width);
714  h->top_mv[0] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
715  h->top_mv[1] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
716  h->top_pred_Y = av_mallocz( h->mb_width*2*sizeof(*h->top_pred_Y));
717  h->top_border_y = av_mallocz((h->mb_width+1)*16);
718  h->top_border_u = av_mallocz( h->mb_width * 10);
719  h->top_border_v = av_mallocz( h->mb_width * 10);
720 
721  /* alloc space for co-located MVs and types */
722  h->col_mv = av_mallocz( h->mb_width*h->mb_height*4*sizeof(cavs_vector));
724  h->block = av_mallocz(64*sizeof(int16_t));
725 }
726 
728  AVSContext *h = avctx->priv_data;
729 
730  ff_dsputil_init(&h->dsp, avctx);
732  ff_videodsp_init(&h->vdsp, 8);
733  ff_cavsdsp_init(&h->cdsp, avctx);
735  h->cdsp.idct_perm);
737 
738  h->avctx = avctx;
739  avctx->pix_fmt= AV_PIX_FMT_YUV420P;
740 
741  h->cur.f = av_frame_alloc();
742  h->DPB[0].f = av_frame_alloc();
743  h->DPB[1].f = av_frame_alloc();
744  if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
745  ff_cavs_end(avctx);
746  return AVERROR(ENOMEM);
747  }
748 
749  h->luma_scan[0] = 0;
750  h->luma_scan[1] = 8;
766  h->mv[ 7] = un_mv;
767  h->mv[19] = un_mv;
768  return 0;
769 }
770 
772  AVSContext *h = avctx->priv_data;
773 
774  av_frame_free(&h->cur.f);
775  av_frame_free(&h->DPB[0].f);
776  av_frame_free(&h->DPB[1].f);
777 
778  av_free(h->top_qp);
779  av_free(h->top_mv[0]);
780  av_free(h->top_mv[1]);
781  av_free(h->top_pred_Y);
782  av_free(h->top_border_y);
783  av_free(h->top_border_u);
784  av_free(h->top_border_v);
785  av_free(h->col_mv);
787  av_free(h->block);
789  return 0;
790 }
cavs_mv_loc
Definition: cavs.h:119
void(* intra_pred_c[7])(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.h:228
uint8_t * top_border_v
Definition: cavs.h:222
uint8_t * top_border_u
Definition: cavs.h:222
void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
Definition: cavs.c:352
uint8_t topleft_border_y
Definition: cavs.h:225
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx)
Definition: dsputil.c:2675
AVCodecContext * avctx
Definition: cavs.h:163
#define ff_cropTbl
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
FIXME Range Coding of cr are ref
Definition: snow.txt:367
uint8_t * edge_emu_buffer
Definition: cavs.h:236
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition: golomb.h:175
static int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
Definition: cavs.c:71
static const int8_t left_modifier_c[7]
Definition: cavs.c:62
Definition: cavs.h:61
void(* cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2)
Definition: cavsdsp.h:33
av_cold int ff_cavs_end(AVCodecContext *avctx)
Definition: cavs.c:771
int mbidx
macroblock coordinates
Definition: cavs.h:184
static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:333
cavs_vector * col_mv
Definition: cavs.h:205
#define MAX_NEG_CROP
Definition: dsputil.h:47
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define tc
Definition: regdef.h:69
#define A_AVAIL
Definition: cavs.h:38
void ff_cavs_init_mb(AVSContext *h)
initialise predictors for motion vectors and intra prediction
Definition: cavs.c:592
int qp
Definition: cavs.h:215
int loop_filter_disable
Definition: cavs.h:181
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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
int stride
Definition: mace.c:144
void(* cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2)
Definition: cavsdsp.h:31
void(* cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2)
Definition: cavsdsp.h:32
int left_qp
Definition: cavs.h:188
uint8_t intern_border_y[26]
Definition: cavs.h:224
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
set threshold d
cavs_mb
Definition: cavs.h:60
#define MV_BWD_OFFS
Definition: cavs.h:57
int mbx
Definition: cavs.h:184
ScanTable scantable
Definition: cavs.h:218
uint8_t
#define av_cold
Definition: attributes.h:78
float delta
mode
Definition: f_perms.c:27
#define SPLITH
Definition: cavs.h:54
uint8_t * top_qp
Definition: cavs.h:189
static const int8_t left_modifier_l[8]
Definition: cavs.c:60
#define b
Definition: input.c:42
uint8_t * top_border_y
intra prediction is done with un-deblocked samples they are saved here before deblocking the MB ...
Definition: cavs.h:222
av_cold void ff_cavsdsp_init(CAVSDSPContext *c, AVCodecContext *avctx)
Definition: cavsdsp.c:535
cavs_vector
Definition: cavs.h:147
cavs_vector mv[2 *4 *3]
mv motion vector cache 0: D3 B2 B3 C2 4: A1 X0 X1 - 8: A3 X2 X3 -
Definition: cavs.h:203
cavs_vector * top_mv[2]
Definition: cavs.h:204
static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:274
bitstream reader API header.
uint8_t idct_permutation[64]
idct input permutation.
Definition: dsputil.h:249
void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
in-loop deblocking filter for a single macroblock
Definition: cavs.c:106
int dist[2]
temporal distances from current frame to ref frames
Definition: cavs.h:171
int mby
Definition: cavs.h:184
void(* cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2)
Definition: cavsdsp.h:34
GetBitContext gb
Definition: cavs.h:168
uint8_t * cy
Definition: cavs.h:187
void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
Definition: h264chroma.c:38
#define cm
Definition: dvbsubdec.c:34
#define D_AVAIL
Definition: cavs.h:41
void(* qpel_mc_func)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
Definition: dsputil.h:84
static void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp)
Definition: cavs.c:506
Discrete Time axis x
uint8_t topleft_border_u
Definition: cavs.h:225
static void mv_pred_median(AVSContext *h, cavs_vector *mvP, cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC)
Definition: cavs.c:513
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:86
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
uint8_t * cu
Definition: cavs.h:187
Definition: cavs.h:66
int scale_den[2]
for scaling neighbouring MVs
Definition: cavs.h:234
AVSFrame cur
currently decoded frame
Definition: cavs.h:169
#define SET_PARAMS
Definition: cavs.c:89
int ff_cavs_next_mb(AVSContext *h)
save predictors for later macroblocks and increase macroblock address
Definition: cavs.c:632
void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type)
Definition: cavs.c:464
CAVSDSPContext cdsp
Definition: cavs.h:167
static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:266
uint8_t left_border_y[26]
Definition: cavs.h:223
#define C_AVAIL
Definition: cavs.h:40
void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
Definition: videodsp.c:37
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
static const uint8_t beta_tab[64]
Definition: cavs.c:42
void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, uint8_t **left, int block)
Definition: cavs.c:178
static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:325
int c_stride
Definition: cavs.h:213
external API header
int size
AVSFrame DPB[2]
reference frames
Definition: cavs.h:170
static const int8_t top_modifier_c[7]
Definition: cavs.c:63
#define B_AVAIL
Definition: cavs.h:39
uint8_t * cv
current MB sample pointers
Definition: cavs.h:187
void ff_cavs_load_intra_pred_chroma(AVSContext *h)
Definition: cavs.c:229
static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:256
int l_stride
Definition: cavs.h:213
qpel_mc_func put_cavs_qpel_pixels_tab[2][16]
Definition: cavsdsp.h:29
#define NOT_AVAIL
Definition: cavs.h:42
av_cold int ff_cavs_init(AVCodecContext *avctx)
Definition: cavs.c:727
uint8_t left_border_u[10]
Definition: cavs.h:223
static const uint8_t tc_tab[64]
Definition: cavs.c:49
const uint8_t ff_cavs_partition_flags[30]
Definition: cavsdata.c:24
int16_t * block
Definition: cavs.h:239
void ff_cavs_init_top_lines(AVSContext *h)
some predictions require data from the top-neighbouring macroblock.
Definition: cavs.c:711
void(* intra_pred_l[8])(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.h:227
const cavs_vector ff_cavs_dir_mv
mark block as "no prediction from this direction" e.g.
Definition: cavsdata.c:59
void(* h264_chroma_mc_func)(uint8_t *dst, uint8_t *src, int srcStride, int h, int x, int y)
Definition: h264chroma.h:24
h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]
Definition: h264chroma.h:28
DSPContext dsp
Definition: cavs.h:164
uint8_t left_border_v[10]
Definition: cavs.h:223
void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, enum cavs_mv_pred mode, enum cavs_block size, int ref)
Definition: cavs.c:539
static void modify_pred(const int8_t *mod_table, int *mode)
Definition: cavs.c:343
static const int8_t mv[256][2]
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:296
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
main external API structure.
static void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height, int delta, int list, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int src_x_offset, int src_y_offset, qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op, cavs_vector *mv)
Definition: cavs.c:379
int pred_mode_Y[3 *3]
luma pred mode cache 0: – B2 B3 3: A1 X0 X1 6: A3 X2 X3
Definition: cavs.h:211
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
cavs_block
Definition: cavs.h:112
#define SPLITV
Definition: cavs.h:55
int * top_pred_Y
Definition: cavs.h:212
static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:304
int idct_perm
Definition: cavsdsp.h:36
synthesis window for stochastic i
#define mid_pred
Definition: mathops.h:94
qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]
Definition: cavsdsp.h:30
void ff_init_scantable_permutation(uint8_t *idct_permutation, int idct_permutation_type)
Definition: dsputil.c:131
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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 all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
#define LOWPASS(ARRAY, INDEX)
Definition: cavs.c:293
uint8_t topleft_border_v
Definition: cavs.h:225
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:115
static const int8_t top_modifier_l[8]
Definition: cavs.c:61
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
cavs_mv_pred
Definition: cavs.h:103
int flags
availability flags of neighbouring macroblocks
Definition: cavs.h:185
function y
Definition: D.m:1
int luma_scan[4]
Definition: cavs.h:214
int mb_height
Definition: cavs.h:175
static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:247
int ff_cavs_init_pic(AVSContext *h)
Definition: cavs.c:676
void(* emulated_edge_mc)(uint8_t *buf, const uint8_t *src, ptrdiff_t linesize, int block_w, int block_h, int src_x, int src_y, int w, int h)
Copy a rectangular area of samples to a temporary buffer and replicate the border samples...
Definition: videodsp.h:58
h264_chroma_mc_func put_h264_chroma_pixels_tab[3]
Definition: h264chroma.h:27
#define REF_INTRA
Definition: cavs.h:43
static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
Definition: cavs.c:312
void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: dsputil.c:110
#define AV_RN64(p)
Definition: intreadwrite.h:360
static const cavs_vector un_mv
mark block as unavailable, i.e.
Definition: cavs.c:58
static void set_mvs(cavs_vector *mv, enum cavs_block size)
Definition: cavs.h:246
VideoDSPContext vdsp
Definition: cavs.h:166
exp golomb vlc stuff
H264ChromaContext h264chroma
Definition: cavs.h:165
static const uint8_t alpha_tab[64]
Definition: cavs.c:35
int mb_width
Definition: cavs.h:175
AVFrame * f
Definition: cavs.h:158
uint8_t * col_type_base
Definition: cavs.h:229
static void mc_part_std(AVSContext *h, int chroma_height, int delta, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int x_offset, int y_offset, qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put, qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg, cavs_vector *mv)
Definition: cavs.c:431