1 /* predict.cc, motion compensated prediction */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6 * Disclaimer of Warranty
7 *
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
15 *
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
18 *
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
21 * patents.
22 *
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
26 * design.
27 *
28 */
29 /* Modifications and enhancements (C) 2000/2001 Andrew Stevens */
30
31 /* These modifications are free software; you can redistribute it
32 * and/or modify it under the terms of the GNU General Public License
33 * as published by the Free Software Foundation; either version 2 of
34 * the License, or (at your option) any later version.
35 *
36 * This program is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 * General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with this program; if not, write to the Free Software
43 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
44 * 02111-1307, USA.
45 *
46 */
47
48
49 #include "config.h"
50 #include <assert.h>
51 #include "mjpeg_logging.h"
52 #include "mpeg2encoder.hh"
53 #include "mpeg2syntaxcodes.h"
54 #include "picture.hh"
55 #include "macroblock.hh"
56 #include "imageplanes.hh"
57 #include "predict_ref.h"
58
59
60 /* predict a rectangular block (all three components)
61 *
62 * src: source frame (Y,U,V)
63 * sfield: source field select (0: frame or top field, 1: bottom field)
64 * dst: destination frame (Y,U,V)
65 * dfield: destination field select (0: frame or top field, 1: bottom field)
66 *
67 * the following values are in luminance picture (frame or field) dimensions
68 * lx: distance of vertically adjacent pels (selects frame or field pred.)
69 * w,h: width and height of block (only 16x16 or 16x8 are used)
70 * x,y: coordinates of destination block
71 * dx,dy: half pel motion vector
72 * addflag: store or add (= average) prediction
73 */
74
pred(uint8_t * src[],int sfield,uint8_t * dst[],int dfield,int lx,int w,int h,int x,int y,int dx,int dy,bool addflag)75 void pred ( uint8_t *src[], int sfield,
76 uint8_t *dst[], int dfield,
77 int lx, int w, int h, int x, int y,
78 int dx, int dy, bool addflag
79 )
80 {
81 int cc;
82
83 for (cc=0; cc<3; cc++)
84 {
85 if (cc==1)
86 {
87 /* scale for color components */
88 /* vertical */
89 h >>= 1; y >>= 1; dy /= 2;
90 /* horizontal */
91 w >>= 1; x >>= 1; dx /= 2;
92 lx >>= 1;
93 }
94 ppred_comp( src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
95 lx,w,h,x,y,dx,dy, (int)addflag);
96 }
97 }
98
99
100
101 /* calculate derived motion vectors (DMV) for dual prime prediction
102 * dmvector[2]: differential motion vectors (-1,0,+1)
103 * mvx,mvy: motion vector (for same parity)
104 *
105 * DMV[2][2]: derived motion vectors (for opposite parity)
106 *
107 * uses global variables pict_struct and topfirst
108 *
109 * Notes:
110 * - all vectors are in field coordinates (even for frame pictures)
111 *
112 */
113
114 #ifndef DEBUG_DPME
115 static
116 #endif
calc_DMV(const Picture & picture,MotionVector DMV[Parity::dim],MotionVector & dmvector,int mvx,int mvy)117 void calc_DMV( const Picture &picture, /*int pict_struct, int topfirst,*/
118 MotionVector DMV[Parity::dim],
119 MotionVector &dmvector,
120 int mvx, int mvy
121 )
122 {
123 if (picture.pict_struct==FRAME_PICTURE)
124 {
125 if (picture.topfirst)
126 {
127 /* vector for prediction of top field from bottom field */
128 DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
129 DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
130
131 /* vector for prediction of bottom field from top field */
132 DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
133 DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
134 }
135 else
136 {
137 /* vector for prediction of top field from bottom field */
138 DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
139 DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
140
141 /* vector for prediction of bottom field from top field */
142 DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
143 DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
144 }
145 }
146 else
147 {
148 /* vector for prediction from field of opposite 'parity' */
149 DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
150 DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
151
152 /* correct for vertical field shift */
153 if (picture.pict_struct==TOP_FIELD)
154 DMV[0][1]--;
155 else
156 DMV[0][1]++;
157 }
158 }
159
160
161 /* form prediction for one macroblock
162 *
163 * lx: frame width (identical to global var `width')
164 *
165 * Notes:
166 * - when predicting a P type picture which is the second field of
167 * a frame, the same parity reference field is in oldref, while the
168 * opposite parity reference field is assumed to be in newref!
169 * - intra macroblocks are modelled to have a constant prediction of 128
170 * for all pels; this results in a DC DCT coefficient symmetric to 0
171 * - vectors for field prediction in frame pictures are in half pel frame
172 * coordinates (vertical component is twice the field value and always
173 * even)
174 *
175 * already covers dual prime (not yet used)
176 */
177
Predict()178 void MacroBlock::Predict()
179 {
180 const Picture &picture = ParentPicture();
181 const int bx = TopleftX();
182 const int by = TopleftY();
183 uint8_t **fwd_rec = picture.fwd_rec->Planes(); // Forward prediction
184 uint8_t **bwd_rec = picture.bwd_rec->Planes(); // Backward prediction
185 uint8_t **cur = picture.pred->Planes(); // Frame to predict
186 int lx = picture.encparams.phy_width;
187 int lx2 = picture.encparams.phy_width;
188
189 bool addflag;
190 int currentfield;
191 uint8_t **predframe;
192 MotionVector DMV[Parity::dim /*pred*/];
193
194 if (best_me->mb_type&MB_INTRA)
195 {
196 clearblock( cur,bx,by,
197 picture.pict_struct==BOTTOM_FIELD ? lx : 0,
198 lx2);
199 return;
200 }
201
202 addflag = false; /* first prediction is stored, second is added and averaged */
203
204 if ((best_me->mb_type & MB_FORWARD) || (picture.pict_type==P_TYPE))
205 {
206 /* forward prediction, including zero MV in P pictures */
207
208 if (picture.pict_struct==FRAME_PICTURE)
209 {
210 /* frame picture */
211
212 if ( (best_me->motion_type==MC_FRAME)
213 || !(best_me->mb_type & MB_FORWARD))
214 {
215 /* frame-based prediction in frame picture */
216 pred( fwd_rec,0,cur,0,
217 lx,16,16,bx,by,best_me->MV[0][0][0],best_me->MV[0][0][1],false);
218 }
219 else if (best_me->motion_type==MC_FIELD)
220 {
221 /* field-based prediction in frame picture
222 *
223 * note scaling of the vertical coordinates (by, MV[][0][1])
224 * from frame to field!
225 */
226
227 /* top field prediction */
228 pred(fwd_rec,best_me->field_sel[0][0],cur,0,
229 lx<<1,16,8,bx,by>>1,
230 best_me->MV[0][0][0],best_me->MV[0][0][1]>>1,false);
231
232 /* bottom field prediction */
233 pred(fwd_rec,best_me->field_sel[1][0],cur,1,
234 lx<<1,16,8,bx,by>>1,
235 best_me->MV[1][0][0],best_me->MV[1][0][1]>>1,false);
236 }
237 else if (best_me->motion_type==MC_DMV)
238 {
239 /* dual prime prediction calculate derived motion vectors */
240 calc_DMV(picture,
241 DMV,
242 best_me->dualprimeMV,
243 best_me->MV[0][0][0],
244 best_me->MV[0][0][1]>>1);
245
246
247 /* predict top field from top field */
248 pred(fwd_rec,0,cur,0,
249 lx<<1,16,8,bx,by>>1,
250 best_me->MV[0][0][0],best_me->MV[0][0][1]>>1,false);
251
252 /* predict bottom field from bottom field */
253 pred(fwd_rec,1,cur,1,
254 lx<<1,16,8,bx,by>>1,
255 best_me->MV[0][0][0],best_me->MV[0][0][1]>>1,false);
256
257 /* predict and add to top field from bottom field */
258 pred(fwd_rec,1,cur,0,
259 lx<<1,16,8,bx,by>>1,
260 DMV[0][0],DMV[0][1],true);
261
262
263 /* predict and add to bottom field from top field */
264 pred(fwd_rec,0,cur,1,
265 lx<<1,16,8,bx,by>>1,
266 DMV[1][0],DMV[1][1],true);
267 }
268 else
269 {
270 /* invalid motion_type in frame picture */
271 mjpeg_error_exit1("Internal: invalid motion_type");
272 }
273 }
274 else /* TOP_FIELD or BOTTOM_FIELD */
275 {
276 /* field picture */
277
278 currentfield = (picture.pict_struct==BOTTOM_FIELD);
279
280 /* determine which frame to use for prediction */
281 if ((picture.pict_type==P_TYPE) && picture.secondfield
282 && (currentfield!=best_me->field_sel[0][0]))
283 predframe = bwd_rec; /* same frame */
284 else
285 predframe = fwd_rec; /* previous frame */
286
287 if ( best_me->motion_type==MC_FIELD
288 || !(best_me->mb_type & MB_FORWARD))
289 {
290 /* field-based prediction in field picture */
291 pred(predframe,best_me->field_sel[0][0],cur,currentfield,
292 lx<<1,16,16,bx,by,
293 best_me->MV[0][0][0],best_me->MV[0][0][1],false);
294 }
295 else if (best_me->motion_type==MC_16X8)
296 {
297 /* 16 x 8 motion compensation in field picture */
298
299 /* upper half */
300 pred(predframe,best_me->field_sel[0][0],cur,currentfield,
301 lx<<1,16,8,bx,by,
302 best_me->MV[0][0][0],best_me->MV[0][0][1],false);
303
304 /* determine which frame to use for lower half prediction */
305 if ((picture.pict_type==P_TYPE) && picture.secondfield
306 && (currentfield!=best_me->field_sel[1][0]))
307 predframe = bwd_rec; /* same frame */
308 else
309 predframe = fwd_rec; /* previous frame */
310
311 /* lower half */
312 pred(predframe,best_me->field_sel[1][0],cur,currentfield,
313 lx<<1,16,8,bx,by+8,
314 best_me->MV[1][0][0],best_me->MV[1][0][1],false);
315 }
316 else if (best_me->motion_type==MC_DMV)
317 {
318 /* dual prime prediction */
319
320 /* determine which frame to use for prediction */
321 if (picture.secondfield)
322 predframe = bwd_rec; /* same frame */
323 else
324 predframe = fwd_rec; /* previous frame */
325
326 /* calculate derived motion vectors */
327 calc_DMV(picture,
328 DMV,best_me->dualprimeMV,
329 best_me->MV[0][0][0],
330 best_me->MV[0][0][1]);
331
332 /* predict from field of same parity */
333 pred(fwd_rec,currentfield,cur,currentfield,
334 lx<<1,16,16,bx,by,
335 best_me->MV[0][0][0],best_me->MV[0][0][1],false);
336
337 /* predict from field of opposite parity */
338 pred(predframe,!currentfield,cur,currentfield,
339 lx<<1,16,16,bx,by,
340 DMV[0][0],DMV[0][1],true);
341 }
342 else
343 {
344 /* invalid motion_type in field picture */
345 mjpeg_error_exit1("Internal: invalid motion_type");
346 }
347 }
348 addflag = true; /* next prediction (if any) will be averaged with this one */
349 }
350
351 if (best_me->mb_type & MB_BACKWARD)
352 {
353 /* backward prediction */
354
355 if (picture.pict_struct==FRAME_PICTURE)
356 {
357 /* frame picture */
358
359 if (best_me->motion_type==MC_FRAME)
360 {
361 /* frame-based prediction in frame picture */
362 pred(bwd_rec,0,cur,0,
363 lx,16,16,bx,by,
364 best_me->MV[0][1][0],best_me->MV[0][1][1],addflag);
365 }
366 else
367 {
368 /* field-based prediction in frame picture
369 *
370 * note scaling of the vertical coordinates (by, MV[][1][1])
371 * from frame to field!
372 */
373
374 /* top field prediction */
375 pred(bwd_rec,best_me->field_sel[0][1],cur,0,
376 lx<<1,16,8,bx,by>>1,
377 best_me->MV[0][1][0],best_me->MV[0][1][1]>>1,addflag);
378
379 /* bottom field prediction */
380 pred(bwd_rec,best_me->field_sel[1][1],cur,1,
381 lx<<1,16,8,bx,by>>1,
382 best_me->MV[1][1][0],best_me->MV[1][1][1]>>1,addflag);
383 }
384 }
385 else /* TOP_FIELD or BOTTOM_FIELD */
386 {
387 /* field picture */
388
389 currentfield = (picture.pict_struct==BOTTOM_FIELD);
390
391 if (best_me->motion_type==MC_FIELD)
392 {
393 /* field-based prediction in field picture */
394 pred(bwd_rec,best_me->field_sel[0][1],cur,currentfield,
395 lx<<1,16,16,bx,by,
396 best_me->MV[0][1][0],best_me->MV[0][1][1],addflag);
397 }
398 else if (best_me->motion_type==MC_16X8)
399 {
400 /* 16 x 8 motion compensation in field picture */
401
402 /* upper half */
403 pred(bwd_rec,best_me->field_sel[0][1],cur,currentfield,
404 lx<<1,16,8,bx,by,
405 best_me->MV[0][1][0],best_me->MV[0][1][1],addflag);
406
407 /* lower half */
408 pred(bwd_rec,best_me->field_sel[1][1],cur,currentfield,
409 lx<<1,16,8,bx,by+8,
410 best_me->MV[1][1][0],best_me->MV[1][1][1],addflag);
411 }
412 else
413 {
414 /* invalid motion_type in field picture */
415 mjpeg_error_exit1("Internal: invalid motion_type");
416 }
417 }
418 }
419 }
420