FFmpeg
h264_direct.c
Go to the documentation of this file.
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
3  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
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  * H.264 / AVC / MPEG-4 part10 direct mb/block decoding.
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27 
28 #include "avcodec.h"
29 #include "h264dec.h"
30 #include "h264_ps.h"
31 #include "mpegutils.h"
32 #include "rectangle.h"
33 #include "threadframe.h"
34 
35 #include <assert.h>
36 
37 static int get_scale_factor(const H264SliceContext *sl,
38  int poc, int poc1, int i)
39 {
40  int poc0 = sl->ref_list[0][i].poc;
41  int64_t pocdiff = poc1 - (int64_t)poc0;
42  int td = av_clip_int8(pocdiff);
43 
44  if (pocdiff != (int)pocdiff)
45  avpriv_request_sample(sl->h264->avctx, "pocdiff overflow");
46 
47  if (td == 0 || sl->ref_list[0][i].parent->long_ref) {
48  return 256;
49  } else {
50  int64_t pocdiff0 = poc - (int64_t)poc0;
51  int tb = av_clip_int8(pocdiff0);
52  int tx = (16384 + (FFABS(td) >> 1)) / td;
53 
54  if (pocdiff0 != (int)pocdiff0)
55  av_log(sl->h264->avctx, AV_LOG_DEBUG, "pocdiff0 overflow\n");
56 
57  return av_clip_intp2((tb * tx + 32) >> 6, 10);
58  }
59 }
60 
62  H264SliceContext *sl)
63 {
64  const int poc = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]
65  : h->cur_pic_ptr->poc;
66  const int poc1 = sl->ref_list[1][0].poc;
67  int i, field;
68 
69  if (FRAME_MBAFF(h))
70  for (field = 0; field < 2; field++) {
71  const int poc = h->cur_pic_ptr->field_poc[field];
72  const int poc1 = sl->ref_list[1][0].parent->field_poc[field];
73  for (i = 0; i < 2 * sl->ref_count[0]; i++)
75  get_scale_factor(sl, poc, poc1, i + 16);
76  }
77 
78  for (i = 0; i < sl->ref_count[0]; i++)
79  sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i);
80 }
81 
82 static void fill_colmap(const H264Context *h, H264SliceContext *sl,
83  int map[2][16 + 32], int list,
84  int field, int colfield, int mbafi)
85 {
86  const H264Picture *const ref1 = sl->ref_list[1][0].parent;
87  int j, old_ref, rfield;
88  int start = mbafi ? 16 : 0;
89  int end = mbafi ? 16 + 2 * sl->ref_count[0] : sl->ref_count[0];
90  int interl = mbafi || h->picture_structure != PICT_FRAME;
91 
92  /* bogus; fills in for missing frames */
93  memset(map[list], 0, sizeof(map[list]));
94 
95  for (rfield = 0; rfield < 2; rfield++) {
96  for (old_ref = 0; old_ref < ref1->ref_count[colfield][list]; old_ref++) {
97  int poc = ref1->ref_poc[colfield][list][old_ref];
98 
99  if (!interl)
100  poc |= 3;
101  // FIXME: store all MBAFF references so this is not needed
102  else if (interl && (poc & 3) == 3)
103  poc = (poc & ~3) + rfield + 1;
104 
105  for (j = start; j < end; j++) {
106  if (4 * sl->ref_list[0][j].parent->frame_num +
107  (sl->ref_list[0][j].reference & 3) == poc) {
108  int cur_ref = mbafi ? (j - 16) ^ field : j;
109  if (ref1->mbaff)
110  map[list][2 * old_ref + (rfield ^ field) + 16] = cur_ref;
111  if (rfield == field || !interl)
112  map[list][old_ref] = cur_ref;
113  break;
114  }
115  }
116  }
117  }
118 }
119 
121 {
122  H264Ref *const ref1 = &sl->ref_list[1][0];
123  H264Picture *const cur = h->cur_pic_ptr;
124  int list, field;
125  int sidx = (h->picture_structure & 1) ^ 1;
126  int ref1sidx = (ref1->reference & 1) ^ 1;
127 
128  /* Updates to cur_pic are not safe once ff_thread_finish_setup() has been
129  * called (other threads may already be reading these fields). */
130  if (!h->setup_finished) {
131  for (list = 0; list < sl->list_count; list++) {
132  cur->ref_count[sidx][list] = sl->ref_count[list];
133  for (int j = 0; j < sl->ref_count[list]; j++)
134  cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].parent->frame_num +
135  (sl->ref_list[list][j].reference & 3);
136  }
137 
138  if (h->picture_structure == PICT_FRAME) {
139  memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
140  memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0]));
141  }
142 
143  if (h->current_slice == 0) {
144  cur->mbaff = FRAME_MBAFF(h);
145  } else {
146  av_assert0(cur->mbaff == FRAME_MBAFF(h));
147  }
148  }
149 
150  sl->col_fieldoff = 0;
151 
152  if (sl->list_count != 2 || !sl->ref_count[1])
153  return;
154 
155  if (h->picture_structure == PICT_FRAME) {
156  int cur_poc = h->cur_pic_ptr->poc;
157  const int *col_poc = sl->ref_list[1][0].parent->field_poc;
158  if (col_poc[0] == INT_MAX && col_poc[1] == INT_MAX) {
159  av_log(h->avctx, AV_LOG_ERROR, "co located POCs unavailable\n");
160  sl->col_parity = 1;
161  } else
162  sl->col_parity = (FFABS(col_poc[0] - (int64_t)cur_poc) >=
163  FFABS(col_poc[1] - (int64_t)cur_poc));
164  ref1sidx =
165  sidx = sl->col_parity;
166  // FL -> FL & differ parity
167  } else if (!(h->picture_structure & sl->ref_list[1][0].reference) &&
168  !sl->ref_list[1][0].parent->mbaff) {
169  sl->col_fieldoff = 2 * sl->ref_list[1][0].reference - 3;
170  }
171 
173  return;
174 
175  for (list = 0; list < 2; list++) {
176  fill_colmap(h, sl, sl->map_col_to_list0, list, sidx, ref1sidx, 0);
177  if (FRAME_MBAFF(h))
178  for (field = 0; field < 2; field++)
180  field, 1);
181  }
182 }
183 
184 static void await_reference_mb_row(const H264Context *const h, H264Ref *ref,
185  int mb_y)
186 {
187  if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME))
188  return;
189 
190  int ref_field = ref->reference - 1;
191  int ref_field_picture = ref->parent->field_picture;
192  int ref_height = 16 * h->mb_height >> ref_field_picture;
193  int row = FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1);
194 
195  /* FIXME: It can be safe to access mb stuff
196  * even if pixels aren't deblocked yet. */
197 
198  ff_thread_await_progress(&ref->parent->tf, row,
199  ref_field_picture && ref_field);
200 
201  /* A frame references a field pair as a whole, so the wait above covers
202  * its bottom field only, while the colocated data is read from the field
203  * selected by col_parity. The two are decoded by different threads. */
204  if (ref_field_picture && !FIELD_PICTURE(h))
205  ff_thread_await_progress(&ref->parent->tf, row, 0);
206 }
207 
209  int *mb_type)
210 {
211  int b8_stride = 2;
212  int b4_stride = h->b_stride;
213  int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
214  int mb_type_col[2];
215  const int16_t (*l1mv0)[2], (*l1mv1)[2];
216  const int8_t *l1ref0, *l1ref1;
217  const int is_b8x8 = IS_8X8(*mb_type);
218  unsigned int sub_mb_type = MB_TYPE_L0L1;
219  int i8, i4;
220  int ref[2];
221  int mv[2];
222  int list;
223 
224  assert(sl->ref_list[1][0].reference & 3);
225 
226  await_reference_mb_row(h, &sl->ref_list[1][0],
227  sl->mb_y + !!IS_INTERLACED(*mb_type));
228 
229 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \
230  MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM)
231 
232  /* ref = min(neighbors) */
233  for (list = 0; list < 2; list++) {
234  int left_ref = sl->ref_cache[list][scan8[0] - 1];
235  int top_ref = sl->ref_cache[list][scan8[0] - 8];
236  int refc = sl->ref_cache[list][scan8[0] - 8 + 4];
237  const int16_t *C = sl->mv_cache[list][scan8[0] - 8 + 4];
238  if (refc == PART_NOT_AVAILABLE) {
239  refc = sl->ref_cache[list][scan8[0] - 8 - 1];
240  C = sl->mv_cache[list][scan8[0] - 8 - 1];
241  }
242  ref[list] = FFMIN3((unsigned)left_ref,
243  (unsigned)top_ref,
244  (unsigned)refc);
245  if (ref[list] >= 0) {
246  /* This is just pred_motion() but with the cases removed that
247  * cannot happen for direct blocks. */
248  const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
249  const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
250 
251  int match_count = (left_ref == ref[list]) +
252  (top_ref == ref[list]) +
253  (refc == ref[list]);
254 
255  if (match_count > 1) { // most common
256  mv[list] = pack16to32(mid_pred(A[0], B[0], C[0]),
257  mid_pred(A[1], B[1], C[1]));
258  } else {
259  assert(match_count == 1);
260  if (left_ref == ref[list])
261  mv[list] = AV_RN32A(A);
262  else if (top_ref == ref[list])
263  mv[list] = AV_RN32A(B);
264  else
265  mv[list] = AV_RN32A(C);
266  }
267  av_assert2(ref[list] < (sl->ref_count[list] << !!FRAME_MBAFF(h)));
268  } else {
269  int mask = ~(MB_TYPE_L0 << (2 * list));
270  mv[list] = 0;
271  ref[list] = -1;
272  if (!is_b8x8)
273  *mb_type &= mask;
274  sub_mb_type &= mask;
275  }
276  }
277  if (ref[0] < 0 && ref[1] < 0) {
278  ref[0] = ref[1] = 0;
279  if (!is_b8x8)
280  *mb_type |= MB_TYPE_L0L1;
281  sub_mb_type |= MB_TYPE_L0L1;
282  }
283 
284  if (!(is_b8x8 | mv[0] | mv[1])) {
285  fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
286  fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
287  fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
288  fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);
289  *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
292  return;
293  }
294 
295  if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
296  if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
297  mb_y = (sl->mb_y & ~1) + sl->col_parity;
298  mb_xy = sl->mb_x +
299  ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
300  b8_stride = 0;
301  } else {
302  mb_y += sl->col_fieldoff;
303  mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
304  }
305  goto single_col;
306  } else { // AFL/AFR/FR/FL -> AFR/FR
307  if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
308  mb_y = sl->mb_y & ~1;
309  mb_xy = (sl->mb_y & ~1) * h->mb_stride + sl->mb_x;
310  mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
311  mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
312  b8_stride = 2 + 4 * h->mb_stride;
313  b4_stride *= 6;
314  if (IS_INTERLACED(mb_type_col[0]) !=
315  IS_INTERLACED(mb_type_col[1])) {
316  mb_type_col[0] &= ~MB_TYPE_INTERLACED;
317  mb_type_col[1] &= ~MB_TYPE_INTERLACED;
318  }
319 
320  sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
321  if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
322  (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
323  !is_b8x8) {
324  *mb_type |= MB_TYPE_16x8 | MB_TYPE_DIRECT2; /* B_16x8 */
325  } else {
326  *mb_type |= MB_TYPE_8x8;
327  }
328  } else { // AFR/FR -> AFR/FR
329 single_col:
330  mb_type_col[0] =
331  mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
332 
333  sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
334  if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
335  *mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_16x16 */
336  } else if (!is_b8x8 &&
337  (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
338  *mb_type |= MB_TYPE_DIRECT2 |
339  (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
340  } else {
341  if (!h->ps.sps->direct_8x8_inference_flag) {
342  /* FIXME: Save sub mb types from previous frames (or derive
343  * from MVs) so we know exactly what block size to use. */
344  sub_mb_type += (MB_TYPE_8x8 - MB_TYPE_16x16); /* B_SUB_4x4 */
345  }
346  *mb_type |= MB_TYPE_8x8;
347  }
348  }
349  }
350 
351  await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
352 
353  l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
354  l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
355  l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
356  l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
357  if (!b8_stride) {
358  if (sl->mb_y & 1) {
359  l1ref0 += 2;
360  l1ref1 += 2;
361  l1mv0 += 2 * b4_stride;
362  l1mv1 += 2 * b4_stride;
363  }
364  }
365 
366  if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
367  int n = 0;
368  for (i8 = 0; i8 < 4; i8++) {
369  int x8 = i8 & 1;
370  int y8 = i8 >> 1;
371  int xy8 = x8 + y8 * b8_stride;
372  int xy4 = x8 * 3 + y8 * b4_stride;
373  int a, b;
374 
375  if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
376  continue;
377  sl->sub_mb_type[i8] = sub_mb_type;
378 
379  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
380  (uint8_t)ref[0], 1);
381  fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
382  (uint8_t)ref[1], 1);
383  if (!IS_INTRA(mb_type_col[y8]) && !sl->ref_list[1][0].parent->long_ref &&
384  ((l1ref0[xy8] == 0 &&
385  FFABS(l1mv0[xy4][0]) <= 1 &&
386  FFABS(l1mv0[xy4][1]) <= 1) ||
387  (l1ref0[xy8] < 0 &&
388  l1ref1[xy8] == 0 &&
389  FFABS(l1mv1[xy4][0]) <= 1 &&
390  FFABS(l1mv1[xy4][1]) <= 1))) {
391  a =
392  b = 0;
393  if (ref[0] > 0)
394  a = mv[0];
395  if (ref[1] > 0)
396  b = mv[1];
397  n++;
398  } else {
399  a = mv[0];
400  b = mv[1];
401  }
402  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4);
403  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4);
404  }
405  if (!is_b8x8 && !(n & 3))
406  *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
409  } else if (IS_16X16(*mb_type)) {
410  int a, b;
411 
412  fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
413  fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
414  if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
415  ((l1ref0[0] == 0 &&
416  FFABS(l1mv0[0][0]) <= 1 &&
417  FFABS(l1mv0[0][1]) <= 1) ||
418  (l1ref0[0] < 0 && !l1ref1[0] &&
419  FFABS(l1mv1[0][0]) <= 1 &&
420  FFABS(l1mv1[0][1]) <= 1 &&
421  h->x264_build > 33U))) {
422  a = b = 0;
423  if (ref[0] > 0)
424  a = mv[0];
425  if (ref[1] > 0)
426  b = mv[1];
427  } else {
428  a = mv[0];
429  b = mv[1];
430  }
431  fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
432  fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
433  } else {
434  int n = 0;
435  for (i8 = 0; i8 < 4; i8++) {
436  const int x8 = i8 & 1;
437  const int y8 = i8 >> 1;
438 
439  if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
440  continue;
441  sl->sub_mb_type[i8] = sub_mb_type;
442 
443  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4);
444  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4);
445  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
446  (uint8_t)ref[0], 1);
447  fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
448  (uint8_t)ref[1], 1);
449 
450  assert(b8_stride == 2);
451  /* col_zero_flag */
452  if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
453  (l1ref0[i8] == 0 ||
454  (l1ref0[i8] < 0 &&
455  l1ref1[i8] == 0 &&
456  h->x264_build > 33U))) {
457  const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1;
458  if (IS_SUB_8X8(sub_mb_type)) {
459  const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
460  if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
461  if (ref[0] == 0)
462  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2,
463  8, 0, 4);
464  if (ref[1] == 0)
465  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2,
466  8, 0, 4);
467  n += 4;
468  }
469  } else {
470  int m = 0;
471  for (i4 = 0; i4 < 4; i4++) {
472  const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
473  (y8 * 2 + (i4 >> 1)) * b4_stride];
474  if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
475  if (ref[0] == 0)
476  AV_ZERO32(sl->mv_cache[0][scan8[i8 * 4 + i4]]);
477  if (ref[1] == 0)
478  AV_ZERO32(sl->mv_cache[1][scan8[i8 * 4 + i4]]);
479  m++;
480  }
481  }
482  if (!(m & 3))
484  n += m;
485  }
486  }
487  }
488  if (!is_b8x8 && !(n & 15))
489  *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
492  }
493 }
494 
496  int *mb_type)
497 {
498  int b8_stride = 2;
499  int b4_stride = h->b_stride;
500  int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
501  int mb_type_col[2];
502  const int16_t (*l1mv0)[2], (*l1mv1)[2];
503  const int8_t *l1ref0, *l1ref1;
504  const int is_b8x8 = IS_8X8(*mb_type);
505  unsigned int sub_mb_type;
506  int i8, i4;
507 
508  assert(sl->ref_list[1][0].reference & 3);
509 
510  await_reference_mb_row(h, &sl->ref_list[1][0],
511  sl->mb_y + !!IS_INTERLACED(*mb_type));
512 
513  if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
514  if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
515  mb_y = (sl->mb_y & ~1) + sl->col_parity;
516  mb_xy = sl->mb_x +
517  ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
518  b8_stride = 0;
519  } else {
520  mb_y += sl->col_fieldoff;
521  mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
522  }
523  goto single_col;
524  } else { // AFL/AFR/FR/FL -> AFR/FR
525  if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
526  mb_y = sl->mb_y & ~1;
527  mb_xy = sl->mb_x + (sl->mb_y & ~1) * h->mb_stride;
528  mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
529  mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
530  b8_stride = 2 + 4 * h->mb_stride;
531  b4_stride *= 6;
532  if (IS_INTERLACED(mb_type_col[0]) !=
533  IS_INTERLACED(mb_type_col[1])) {
534  mb_type_col[0] &= ~MB_TYPE_INTERLACED;
535  mb_type_col[1] &= ~MB_TYPE_INTERLACED;
536  }
537 
538  sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
539  MB_TYPE_DIRECT2; /* B_SUB_8x8 */
540 
541  if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
542  (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
543  !is_b8x8) {
544  *mb_type |= MB_TYPE_16x8 | MB_TYPE_L0L1 |
545  MB_TYPE_DIRECT2; /* B_16x8 */
546  } else {
547  *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
548  }
549  } else { // AFR/FR -> AFR/FR
550 single_col:
551  mb_type_col[0] =
552  mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
553 
554  sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
555  MB_TYPE_DIRECT2; /* B_SUB_8x8 */
556  if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
557  *mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
558  MB_TYPE_DIRECT2; /* B_16x16 */
559  } else if (!is_b8x8 &&
560  (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
561  *mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 |
562  (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
563  } else {
564  if (!h->ps.sps->direct_8x8_inference_flag) {
565  /* FIXME: save sub mb types from previous frames (or derive
566  * from MVs) so we know exactly what block size to use */
567  sub_mb_type = MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
568  MB_TYPE_DIRECT2; /* B_SUB_4x4 */
569  }
570  *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
571  }
572  }
573  }
574 
575  await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
576 
577  l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
578  l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
579  l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
580  l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
581  if (!b8_stride) {
582  if (sl->mb_y & 1) {
583  l1ref0 += 2;
584  l1ref1 += 2;
585  l1mv0 += 2 * b4_stride;
586  l1mv1 += 2 * b4_stride;
587  }
588  }
589 
590  {
591  const int *map_col_to_list0[2] = { sl->map_col_to_list0[0],
592  sl->map_col_to_list0[1] };
593  const int *dist_scale_factor = sl->dist_scale_factor;
594  int ref_offset;
595 
596  if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {
597  map_col_to_list0[0] = sl->map_col_to_list0_field[sl->mb_y & 1][0];
598  map_col_to_list0[1] = sl->map_col_to_list0_field[sl->mb_y & 1][1];
599  dist_scale_factor = sl->dist_scale_factor_field[sl->mb_y & 1];
600  }
601  ref_offset = (sl->ref_list[1][0].parent->mbaff << 4) & (mb_type_col[0] >> 3);
602 
603  if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
604  int y_shift = 2 * !IS_INTERLACED(*mb_type);
605  assert(h->ps.sps->direct_8x8_inference_flag);
606 
607  for (i8 = 0; i8 < 4; i8++) {
608  const int x8 = i8 & 1;
609  const int y8 = i8 >> 1;
610  int ref0, scale;
611  const int16_t (*l1mv)[2] = l1mv0;
612 
613  if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
614  continue;
615  sl->sub_mb_type[i8] = sub_mb_type;
616 
617  fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
618  if (IS_INTRA(mb_type_col[y8])) {
619  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
620  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
621  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
622  continue;
623  }
624 
625  ref0 = l1ref0[x8 + y8 * b8_stride];
626  if (ref0 >= 0)
627  ref0 = map_col_to_list0[0][ref0 + ref_offset];
628  else {
629  ref0 = map_col_to_list0[1][l1ref1[x8 + y8 * b8_stride] +
630  ref_offset];
631  l1mv = l1mv1;
632  }
633  scale = dist_scale_factor[ref0];
634  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
635  ref0, 1);
636 
637  {
638  const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride];
639  int my_col = (mv_col[1] * (1 << y_shift)) / 2;
640  int mx = (scale * mv_col[0] + 128) >> 8;
641  int my = (scale * my_col + 128) >> 8;
642  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
643  pack16to32(mx, my), 4);
644  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
645  pack16to32(mx - mv_col[0], my - my_col), 4);
646  }
647  }
648  return;
649  }
650 
651  /* one-to-one mv scaling */
652 
653  if (IS_16X16(*mb_type)) {
654  int ref, mv0, mv1;
655 
656  fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);
657  if (IS_INTRA(mb_type_col[0])) {
658  ref = mv0 = mv1 = 0;
659  } else {
660  const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
661  : map_col_to_list0[1][l1ref1[0] + ref_offset];
662  const int scale = dist_scale_factor[ref0];
663  const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
664  int mv_l0[2];
665  mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
666  mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
667  ref = ref0;
668  mv0 = pack16to32(mv_l0[0], mv_l0[1]);
669  mv1 = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]);
670  }
671  fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
672  fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
673  fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
674  } else {
675  for (i8 = 0; i8 < 4; i8++) {
676  const int x8 = i8 & 1;
677  const int y8 = i8 >> 1;
678  int ref0, scale;
679  const int16_t (*l1mv)[2] = l1mv0;
680 
681  if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
682  continue;
683  sl->sub_mb_type[i8] = sub_mb_type;
684  fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
685  if (IS_INTRA(mb_type_col[0])) {
686  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
687  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
688  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
689  continue;
690  }
691 
692  assert(b8_stride == 2);
693  ref0 = l1ref0[i8];
694  if (ref0 >= 0)
695  ref0 = map_col_to_list0[0][ref0 + ref_offset];
696  else {
697  ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];
698  l1mv = l1mv1;
699  }
700  scale = dist_scale_factor[ref0];
701 
702  fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
703  ref0, 1);
704  if (IS_SUB_8X8(sub_mb_type)) {
705  const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
706  int mx = (scale * mv_col[0] + 128) >> 8;
707  int my = (scale * mv_col[1] + 128) >> 8;
708  fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
709  pack16to32(mx, my), 4);
710  fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
711  pack16to32(mx - mv_col[0], my - mv_col[1]), 4);
712  } else {
713  for (i4 = 0; i4 < 4; i4++) {
714  const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
715  (y8 * 2 + (i4 >> 1)) * b4_stride];
716  int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]];
717  mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
718  mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
719  AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]],
720  pack16to32(mv_l0[0] - mv_col[0],
721  mv_l0[1] - mv_col[1]));
722  }
723  }
724  }
725  }
726  }
727 }
728 
730  int *mb_type)
731 {
732  if (sl->direct_spatial_mv_pred)
733  pred_spatial_direct_motion(h, sl, mb_type);
734  else
735  pred_temp_direct_motion(h, sl, mb_type);
736 }
await_reference_mb_row
static void await_reference_mb_row(const H264Context *const h, H264Ref *ref, int mb_y)
Definition: h264_direct.c:184
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:33
A
#define A(x)
Definition: vpx_arith.h:28
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:83
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:57
H264SliceContext::mb_xy
int mb_xy
Definition: h264dec.h:232
H264SliceContext::ref_cache
int8_t ref_cache[2][5 *8]
Definition: h264dec.h:300
av_clip_int8
#define av_clip_int8
Definition: common.h:109
H264Ref
Definition: h264dec.h:167
H264Picture::ref_count
int ref_count[2][2]
number of entries in ref_poc (FIXME need per slice)
Definition: h264dec.h:141
H264Picture::ref_index
int8_t * ref_index[2]
RefStruct reference.
Definition: h264dec.h:130
int64_t
long long int64_t
Definition: coverity.c:34
MB_TYPE_16x8
#define MB_TYPE_16x8
Definition: mpegutils.h:42
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
mask
int mask
Definition: mediacodecdec_common.c:154
b
#define b
Definition: input.c:42
H264SliceContext::ref_count
unsigned int ref_count[2]
num_ref_idx_l0/1_active_minus1 + 1
Definition: h264dec.h:268
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:41
PICT_BOTTOM_FIELD
#define PICT_BOTTOM_FIELD
Definition: mpegutils.h:32
AV_WN32A
#define AV_WN32A(p, v)
Definition: intreadwrite.h:534
H264SliceContext::sub_mb_type
uint16_t sub_mb_type[4]
Definition: h264dec.h:304
mpegutils.h
H264SliceContext::dist_scale_factor
int dist_scale_factor[32]
Definition: h264dec.h:260
H264SliceContext::mb_x
int mb_x
Definition: h264dec.h:231
H264Picture::frame_num
int frame_num
frame_num (raw frame_num from slice header)
Definition: h264dec.h:134
H264SliceContext
Definition: h264dec.h:178
H264SliceContext::mv_cache
int16_t mv_cache[2][5 *8][2]
Motion vector cache.
Definition: h264dec.h:299
mx
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
Definition: dsp.h:57
H264SliceContext::map_col_to_list0
int map_col_to_list0[2][16+32]
Definition: h264dec.h:262
H264SliceContext::map_col_to_list0_field
int map_col_to_list0_field[2][2][16+32]
Definition: h264dec.h:263
H264Picture::ref_poc
int ref_poc[2][2][32]
POCs of the frames/fields used as reference (FIXME need per slice)
Definition: h264dec.h:140
pred_spatial_direct_motion
static void pred_spatial_direct_motion(const H264Context *const h, H264SliceContext *sl, int *mb_type)
Definition: h264_direct.c:208
scan8
static const uint8_t scan8[16 *3+3]
Definition: h264_parse.h:40
H264SliceContext::direct_spatial_mv_pred
int direct_spatial_mv_pred
Definition: h264dec.h:252
H264Context::avctx
AVCodecContext * avctx
Definition: h264dec.h:340
pack16to32
static av_always_inline uint32_t pack16to32(unsigned a, unsigned b)
Definition: h264_parse.h:127
C
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
Definition: writing_filters.txt:58
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
MB_TYPE_P1L0
#define MB_TYPE_P1L0
Definition: mpegutils.h:54
H264Picture::mbaff
int mbaff
1 -> MBAFF frame 0-> not MBAFF
Definition: h264dec.h:142
get_scale_factor
static int get_scale_factor(const H264SliceContext *sl, int poc, int poc1, int i)
Definition: h264_direct.c:37
AV_ZERO32
#define AV_ZERO32(d)
Definition: intreadwrite.h:662
FIELD_PICTURE
#define FIELD_PICTURE(h)
Definition: h264dec.h:65
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
B
#define B
Definition: huffyuv.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
field
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 field
Definition: writing_filters.txt:78
ff_h264_pred_direct_motion
void ff_h264_pred_direct_motion(const H264Context *const h, H264SliceContext *sl, int *mb_type)
Definition: h264_direct.c:729
my
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
Definition: dsp.h:57
MB_TYPE_8x16
#define MB_TYPE_8x16
Definition: mpegutils.h:43
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
threadframe.h
av_clip_intp2
#define av_clip_intp2
Definition: common.h:121
ff_thread_await_progress
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:652
H264Ref::parent
const H264Picture * parent
Definition: h264dec.h:175
MB_TYPE_8x8
#define MB_TYPE_8x8
Definition: mpegutils.h:44
MB_TYPE_P0L0
#define MB_TYPE_P0L0
Definition: mpegutils.h:53
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
IS_INTERLACED
#define IS_INTERLACED(a)
Definition: mpegutils.h:77
MB_TYPE_P0L1
#define MB_TYPE_P0L1
Definition: mpegutils.h:55
h264_ps.h
fill_colmap
static void fill_colmap(const H264Context *h, H264SliceContext *sl, int map[2][16+32], int list, int field, int colfield, int mbafi)
Definition: h264_direct.c:82
IS_INTRA
#define IS_INTRA(x, y)
rectangle.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
H264Picture::mb_type
uint32_t * mb_type
Definition: h264dec.h:125
ff_h264_direct_ref_list_init
void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext *sl)
Definition: h264_direct.c:120
MB_TYPE_INTERLACED
#define MB_TYPE_INTERLACED
Definition: mpegutils.h:45
H264SliceContext::mb_y
int mb_y
Definition: h264dec.h:231
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
H264SliceContext::slice_type_nos
int slice_type_nos
S free slice type (SI/SP are remapped to I/P)
Definition: h264dec.h:185
FRAME_MBAFF
#define FRAME_MBAFF(h)
Definition: h264dec.h:64
IS_DIRECT
#define IS_DIRECT(a)
Definition: mpegutils.h:78
IS_16X16
#define IS_16X16(a)
Definition: mpegutils.h:80
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1584
MB_TYPE_L0L1
#define MB_TYPE_L0L1
Definition: mpegutils.h:59
h264dec.h
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
ff_h264_direct_dist_scale_factor
void ff_h264_direct_dist_scale_factor(const H264Context *const h, H264SliceContext *sl)
Definition: h264_direct.c:61
H264Context
H264Context.
Definition: h264dec.h:338
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
H264SliceContext::col_fieldoff
int col_fieldoff
Definition: h264dec.h:254
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
H264SliceContext::list_count
unsigned int list_count
Definition: h264dec.h:269
avcodec.h
AV_RN32A
#define AV_RN32A(p)
Definition: intreadwrite.h:522
H264SliceContext::h264
const struct H264Context * h264
Definition: h264dec.h:179
mid_pred
#define mid_pred
Definition: mathops.h:115
U
#define U(x)
Definition: vpx_arith.h:37
H264Picture::field_poc
int field_poc[2]
top/bottom POC
Definition: h264dec.h:132
IS_SUB_8X8
#define IS_SUB_8X8(a)
Definition: h264dec.h:94
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:280
MB_TYPE_16x16_OR_INTRA
#define MB_TYPE_16x16_OR_INTRA
fill_rectangle
static void fill_rectangle(int x, int y, int w, int h)
Definition: ffplay.c:828
H264Picture
Definition: h264dec.h:112
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
PART_NOT_AVAILABLE
#define PART_NOT_AVAILABLE
Definition: h264pred.h:89
H264SliceContext::col_parity
int col_parity
Definition: h264dec.h:253
H264SliceContext::ref_list
H264Ref ref_list[2][48]
0..15: frame refs, 16..47: mbaff field refs.
Definition: h264dec.h:270
H264SliceContext::dist_scale_factor_field
int dist_scale_factor_field[2][32]
Definition: h264dec.h:261
pred_temp_direct_motion
static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext *sl, int *mb_type)
Definition: h264_direct.c:495
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
MB_TYPE_DIRECT2
#define MB_TYPE_DIRECT2
Definition: mpegutils.h:46
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
H264Ref::poc
int poc
Definition: h264dec.h:172
H264Picture::long_ref
int long_ref
1->long term reference 0->short term reference
Definition: h264dec.h:139
H264Ref::reference
int reference
Definition: h264dec.h:171
H264Picture::motion_val
int16_t(*[2] motion_val)[2]
Definition: h264dec.h:122
MB_TYPE_P1L1
#define MB_TYPE_P1L1
Definition: mpegutils.h:56