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 
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)
87  else if(s->mb_intra)
89  else
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 }
IDCTDSPContext idsp
Definition: mpegvideo.h:230
int8_t * ref_index[2]
Definition: mpegpicture.h:62
void(* h263_v_loop_filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.h:28
int16_t(*[3] ac_val)[16]
used for MPEG-4 AC prediction, all 3 arrays must be continuous
Definition: mpegvideo.h:194
#define MB_TYPE_INTRA
Definition: mpegutils.h:73
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:36
int16_t(*[2][2] p_field_mv_table)[2]
MV table (2MV per MB) interlaced P-frame encoding.
Definition: mpegvideo.h:254
mpegvideo header.
int qscale
QP.
Definition: mpegvideo.h:204
int16_t * ff_h263_pred_motion(MpegEncContext *s, int block, int dir, int *px, int *py)
Definition: h263.c:307
int encoding
true if we are encoding (vs decoding)
Definition: mpegvideo.h:114
int field_select[2][2]
Definition: mpegvideo.h:277
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
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
H.263 tables.
#define MB_TYPE_16x16
Definition: mpegutils.h:54
Picture current_picture
copy of the current picture structure.
Definition: mpegvideo.h:180
int ff_h263_pred_dc(MpegEncContext *s, int n, int16_t **dc_val_ptr)
Definition: h263.c:94
int mb_height
number of MBs horizontally & vertically
Definition: mpegvideo.h:129
#define A(x)
Definition: vp56_arith.h:28
int16_t * dc_val[3]
used for MPEG-4 DC prediction, all 3 arrays must be continuous
Definition: mpegvideo.h:187
H263DSPContext h263dsp
Definition: mpegvideo.h:237
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint8_t * mbskip_table
Definition: mpegpicture.h:59
int mb_skipped
MUST BE SET only during DECODING.
Definition: mpegvideo.h:195
#define B
Definition: huffyuvdsp.h:32
#define wrap(func)
Definition: neontest.h:65
#define IS_SKIP(a)
Definition: mpegutils.h:81
int resync_mb_x
x position of last resync marker
Definition: mpegvideo.h:356
void ff_h263_loop_filter(MpegEncContext *s)
Definition: h263.c:135
int16_t(*[2] motion_val)[2]
Definition: mpegpicture.h:53
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)
#define s(width, name)
Definition: cbs_vp9.c:257
int n
Definition: avisynth_c.h:760
uint8_t idct_permutation[64]
IDCT input permutation.
Definition: idctdsp.h:96
int block_index[6]
index to current MB in block based arrays with edges
Definition: mpegvideo.h:293
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
#define MB_TYPE_8x8
Definition: mpegutils.h:57
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:266
int first_slice_line
used in MPEG-4 too to handle resync markers
Definition: mpegvideo.h:436
Libavcodec external API header.
void ff_h263_update_motion_val(MpegEncContext *s)
Definition: h263.c:42
ptrdiff_t linesize
line size, in bytes, may be different from width
Definition: mpegvideo.h:134
#define mid_pred
Definition: mathops.h:97
ptrdiff_t uvlinesize
line size, for chroma in bytes, may be different from width
Definition: mpegvideo.h:135
int h263_pred
use MPEG-4/H.263 ac/dc predictions
Definition: mpegvideo.h:105
int mv[2][4][2]
motion vectors for a macroblock first coordinate : 0 = forward 1 = backward second " : depend...
Definition: mpegvideo.h:276
int b8_stride
2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
Definition: mpegvideo.h:131
MpegEncContext.
Definition: mpegvideo.h:81
int8_t * qscale_table
Definition: mpegpicture.h:50
int mb_stride
mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 ...
Definition: mpegvideo.h:130
void ff_h263_pred_acdc(MpegEncContext *s, int16_t *block, int n)
Definition: h263.c:220
uint8_t * dest[3]
Definition: mpegvideo.h:295
const uint8_t * chroma_qscale_table
qscale -> chroma_qscale (H.263)
Definition: mpegvideo.h:190
uint32_t * mb_type
types and macros are defined in mpegutils.h
Definition: mpegpicture.h:56
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:267
int h263_aic_dir
AIC direction: 0 = left, 1 = top.
Definition: mpegvideo.h:376
#define MB_TYPE_L0
Definition: mpegutils.h:67
void(* h263_h_loop_filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.h:27