FFmpeg
h263.c
Go to the documentation of this file.
1 /*
2  * H.263/MPEG-4 backend for encoder and decoder
3  * Copyright (c) 2000,2001 Fabrice Bellard
4  * H.263+ support.
5  * Copyright (c) 2001 Juan J. Sierralta P
6  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
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 /**
26  * @file
27  * H.263/MPEG-4 codec.
28  */
29 
30 #include <limits.h>
31 
32 #include "avcodec.h"
33 #include "mpegvideo.h"
34 #include "h263.h"
35 #include "h263data.h"
36 #include "mathops.h"
37 #include "mpegutils.h"
38 #include "flv.h"
39 #include "mpeg4video.h"
40 
41 
43  const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
44  //FIXME a lot of that is only needed for !low_delay
45  const int wrap = s->b8_stride;
46  const int xy = s->block_index[0];
47 
48  s->current_picture.mbskip_table[mb_xy] = s->mb_skipped;
49 
50  if(s->mv_type != MV_TYPE_8X8){
51  int motion_x, motion_y;
52  if (s->mb_intra) {
53  motion_x = 0;
54  motion_y = 0;
55  } else if (s->mv_type == MV_TYPE_16X16) {
56  motion_x = s->mv[0][0][0];
57  motion_y = s->mv[0][0][1];
58  } else /*if (s->mv_type == MV_TYPE_FIELD)*/ {
59  int i;
60  motion_x = s->mv[0][0][0] + s->mv[0][1][0];
61  motion_y = s->mv[0][0][1] + s->mv[0][1][1];
62  motion_x = (motion_x>>1) | (motion_x&1);
63  for(i=0; i<2; i++){
64  s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
65  s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
66  }
67  s->current_picture.ref_index[0][4*mb_xy ] =
68  s->current_picture.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
69  s->current_picture.ref_index[0][4*mb_xy + 2] =
70  s->current_picture.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
71  }
72 
73  /* no update if 8X8 because it has been done during parsing */
74  s->current_picture.motion_val[0][xy][0] = motion_x;
75  s->current_picture.motion_val[0][xy][1] = motion_y;
76  s->current_picture.motion_val[0][xy + 1][0] = motion_x;
77  s->current_picture.motion_val[0][xy + 1][1] = motion_y;
78  s->current_picture.motion_val[0][xy + wrap][0] = motion_x;
79  s->current_picture.motion_val[0][xy + wrap][1] = motion_y;
80  s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
81  s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
82  }
83 
84  if(s->encoding){ //FIXME encoding MUST be cleaned up
85  if (s->mv_type == MV_TYPE_8X8)
86  s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
87  else if(s->mb_intra)
88  s->current_picture.mb_type[mb_xy] = MB_TYPE_INTRA;
89  else
90  s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
91  }
92 }
93 
94 int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
95 {
96  int x, y, wrap, a, c, pred_dc;
97  int16_t *dc_val;
98 
99  /* find prediction */
100  if (n < 4) {
101  x = 2 * s->mb_x + (n & 1);
102  y = 2 * s->mb_y + ((n & 2) >> 1);
103  wrap = s->b8_stride;
104  dc_val = s->dc_val[0];
105  } else {
106  x = s->mb_x;
107  y = s->mb_y;
108  wrap = s->mb_stride;
109  dc_val = s->dc_val[n - 4 + 1];
110  }
111  /* B C
112  * A X
113  */
114  a = dc_val[(x - 1) + (y) * wrap];
115  c = dc_val[(x) + (y - 1) * wrap];
116 
117  /* No prediction outside GOB boundary */
118  if(s->first_slice_line && n!=3){
119  if(n!=2) c= 1024;
120  if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
121  }
122  /* just DC prediction */
123  if (a != 1024 && c != 1024)
124  pred_dc = (a + c) >> 1;
125  else if (a != 1024)
126  pred_dc = a;
127  else
128  pred_dc = c;
129 
130  /* we assume pred is positive */
131  *dc_val_ptr = &dc_val[x + y * wrap];
132  return pred_dc;
133 }
134 
136  int qp_c;
137  const int linesize = s->linesize;
138  const int uvlinesize= s->uvlinesize;
139  const int xy = s->mb_y * s->mb_stride + s->mb_x;
140  uint8_t *dest_y = s->dest[0];
141  uint8_t *dest_cb= s->dest[1];
142  uint8_t *dest_cr= s->dest[2];
143 
144  /*
145  Diag Top
146  Left Center
147  */
148  if (!IS_SKIP(s->current_picture.mb_type[xy])) {
149  qp_c= s->qscale;
150  s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize, linesize, qp_c);
151  s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
152  }else
153  qp_c= 0;
154 
155  if(s->mb_y){
156  int qp_dt, qp_tt, qp_tc;
157 
158  if (IS_SKIP(s->current_picture.mb_type[xy - s->mb_stride]))
159  qp_tt=0;
160  else
161  qp_tt = s->current_picture.qscale_table[xy - s->mb_stride];
162 
163  if(qp_c)
164  qp_tc= qp_c;
165  else
166  qp_tc= qp_tt;
167 
168  if(qp_tc){
169  const int chroma_qp= s->chroma_qscale_table[qp_tc];
170  s->h263dsp.h263_v_loop_filter(dest_y, linesize, qp_tc);
171  s->h263dsp.h263_v_loop_filter(dest_y + 8, linesize, qp_tc);
172 
173  s->h263dsp.h263_v_loop_filter(dest_cb, uvlinesize, chroma_qp);
174  s->h263dsp.h263_v_loop_filter(dest_cr, uvlinesize, chroma_qp);
175  }
176 
177  if(qp_tt)
178  s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize + 8, linesize, qp_tt);
179 
180  if(s->mb_x){
181  if (qp_tt || IS_SKIP(s->current_picture.mb_type[xy - 1 - s->mb_stride]))
182  qp_dt= qp_tt;
183  else
184  qp_dt = s->current_picture.qscale_table[xy - 1 - s->mb_stride];
185 
186  if(qp_dt){
187  const int chroma_qp= s->chroma_qscale_table[qp_dt];
188  s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize, linesize, qp_dt);
189  s->h263dsp.h263_h_loop_filter(dest_cb - 8 * uvlinesize, uvlinesize, chroma_qp);
190  s->h263dsp.h263_h_loop_filter(dest_cr - 8 * uvlinesize, uvlinesize, chroma_qp);
191  }
192  }
193  }
194 
195  if(qp_c){
196  s->h263dsp.h263_h_loop_filter(dest_y + 8, linesize, qp_c);
197  if(s->mb_y + 1 == s->mb_height)
198  s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
199  }
200 
201  if(s->mb_x){
202  int qp_lc;
203  if (qp_c || IS_SKIP(s->current_picture.mb_type[xy - 1]))
204  qp_lc= qp_c;
205  else
206  qp_lc = s->current_picture.qscale_table[xy - 1];
207 
208  if(qp_lc){
209  s->h263dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
210  if(s->mb_y + 1 == s->mb_height){
211  const int chroma_qp= s->chroma_qscale_table[qp_lc];
212  s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize, linesize, qp_lc);
213  s->h263dsp.h263_h_loop_filter(dest_cb, uvlinesize, chroma_qp);
214  s->h263dsp.h263_h_loop_filter(dest_cr, uvlinesize, chroma_qp);
215  }
216  }
217  }
218 }
219 
220 void ff_h263_pred_acdc(MpegEncContext * s, int16_t *block, int n)
221 {
222  int x, y, wrap, a, c, pred_dc, scale, i;
223  int16_t *dc_val, *ac_val, *ac_val1;
224 
225  /* find prediction */
226  if (n < 4) {
227  x = 2 * s->mb_x + (n & 1);
228  y = 2 * s->mb_y + (n>> 1);
229  wrap = s->b8_stride;
230  dc_val = s->dc_val[0];
231  ac_val = s->ac_val[0][0];
232  scale = s->y_dc_scale;
233  } else {
234  x = s->mb_x;
235  y = s->mb_y;
236  wrap = s->mb_stride;
237  dc_val = s->dc_val[n - 4 + 1];
238  ac_val = s->ac_val[n - 4 + 1][0];
239  scale = s->c_dc_scale;
240  }
241 
242  ac_val += ((y) * wrap + (x)) * 16;
243  ac_val1 = ac_val;
244 
245  /* B C
246  * A X
247  */
248  a = dc_val[(x - 1) + (y) * wrap];
249  c = dc_val[(x) + (y - 1) * wrap];
250 
251  /* No prediction outside GOB boundary */
252  if(s->first_slice_line && n!=3){
253  if(n!=2) c= 1024;
254  if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
255  }
256 
257  if (s->ac_pred) {
258  pred_dc = 1024;
259  if (s->h263_aic_dir) {
260  /* left prediction */
261  if (a != 1024) {
262  ac_val -= 16;
263  for(i=1;i<8;i++) {
264  block[s->idsp.idct_permutation[i << 3]] += ac_val[i];
265  }
266  pred_dc = a;
267  }
268  } else {
269  /* top prediction */
270  if (c != 1024) {
271  ac_val -= 16 * wrap;
272  for(i=1;i<8;i++) {
273  block[s->idsp.idct_permutation[i]] += ac_val[i + 8];
274  }
275  pred_dc = c;
276  }
277  }
278  } else {
279  /* just DC prediction */
280  if (a != 1024 && c != 1024)
281  pred_dc = (a + c) >> 1;
282  else if (a != 1024)
283  pred_dc = a;
284  else
285  pred_dc = c;
286  }
287 
288  /* we assume pred is positive */
289  block[0]=block[0]*scale + pred_dc;
290 
291  if (block[0] < 0)
292  block[0] = 0;
293  else
294  block[0] |= 1;
295 
296  /* Update AC/DC tables */
297  dc_val[(x) + (y) * wrap] = block[0];
298 
299  /* left copy */
300  for(i=1;i<8;i++)
301  ac_val1[i] = block[s->idsp.idct_permutation[i << 3]];
302  /* top copy */
303  for(i=1;i<8;i++)
304  ac_val1[8 + i] = block[s->idsp.idct_permutation[i]];
305 }
306 
307 int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
308  int *px, int *py)
309 {
310  int wrap;
311  int16_t *A, *B, *C, (*mot_val)[2];
312  static const int off[4]= {2, 1, 1, -1};
313 
314  wrap = s->b8_stride;
315  mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
316 
317  A = mot_val[ - 1];
318  /* special case for first (slice) line */
319  if (s->first_slice_line && block<3) {
320  // we can't just change some MVs to simulate that as we need them for the B-frames (and ME)
321  // and if we ever support non rectangular objects than we need to do a few ifs here anyway :(
322  if(block==0){ //most common case
323  if(s->mb_x == s->resync_mb_x){ //rare
324  *px= *py = 0;
325  }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
326  C = mot_val[off[block] - wrap];
327  if(s->mb_x==0){
328  *px = C[0];
329  *py = C[1];
330  }else{
331  *px = mid_pred(A[0], 0, C[0]);
332  *py = mid_pred(A[1], 0, C[1]);
333  }
334  }else{
335  *px = A[0];
336  *py = A[1];
337  }
338  }else if(block==1){
339  if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
340  C = mot_val[off[block] - wrap];
341  *px = mid_pred(A[0], 0, C[0]);
342  *py = mid_pred(A[1], 0, C[1]);
343  }else{
344  *px = A[0];
345  *py = A[1];
346  }
347  }else{ /* block==2*/
348  B = mot_val[ - wrap];
349  C = mot_val[off[block] - wrap];
350  if(s->mb_x == s->resync_mb_x) //rare
351  A[0]=A[1]=0;
352 
353  *px = mid_pred(A[0], B[0], C[0]);
354  *py = mid_pred(A[1], B[1], C[1]);
355  }
356  } else {
357  B = mot_val[ - wrap];
358  C = mot_val[off[block] - wrap];
359  *px = mid_pred(A[0], B[0], C[0]);
360  *py = mid_pred(A[1], B[1], C[1]);
361  }
362  return *mot_val;
363 }
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:67
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:266
h263data.h
n
int n
Definition: avisynth_c.h:760
ff_h263_pred_acdc
void ff_h263_pred_acdc(MpegEncContext *s, int16_t *block, int n)
Definition: h263.c:220
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:54
mpegvideo.h
mpegutils.h
A
#define A(x)
Definition: vp56_arith.h:28
ff_h263_pred_motion
int16_t * ff_h263_pred_motion(MpegEncContext *s, int block, int dir, int *px, int *py)
Definition: h263.c:307
wrap
#define wrap(func)
Definition: neontest.h:65
ff_h263_update_motion_val
void ff_h263_update_motion_val(MpegEncContext *s)
Definition: h263.c:42
flv.h
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
s
#define s(width, name)
Definition: cbs_vp9.c:257
limits.h
IS_SKIP
#define IS_SKIP(a)
Definition: mpegutils.h:81
MB_TYPE_8x8
#define MB_TYPE_8x8
Definition: mpegutils.h:57
mathops.h
ff_h263_pred_dc
int ff_h263_pred_dc(MpegEncContext *s, int n, int16_t **dc_val_ptr)
Definition: h263.c:94
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:267
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint8_t
uint8_t
Definition: audio_convert.c:194
avcodec.h
mid_pred
#define mid_pred
Definition: mathops.h:97
ff_h263_loop_filter
void ff_h263_loop_filter(MpegEncContext *s)
Definition: h263.c:135
B
#define B
Definition: huffyuvdsp.h:32
mpeg4video.h
pred_dc
static void FUNC() pred_dc(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int log2_size, int c_idx)
Definition: hevcpred_template.c:390
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:81
MB_TYPE_INTRA
#define MB_TYPE_INTRA
Definition: mpegutils.h:73
h263.h