1 /************************************************************************
2 *
3 * recon.c, motion compensation routines for tmndecode (H.263 decoder)
4 * Copyright (C) 1995, 1996 Telenor R&D, Norway
5 *
6 * Contacts:
7 * Robert Danielsen <Robert.Danielsen@nta.no>
8 *
9 * Telenor Research and Development http://www.nta.no/brukere/DVC/
10 * P.O.Box 83 tel.: +47 63 84 84 00
11 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76
12 *
13 * Copyright (C) 1997 University of BC, Canada
14 * Modified by: Michael Gallant <mikeg@ee.ubc.ca>
15 * Guy Cote <guyc@ee.ubc.ca>
16 * Berna Erol <bernae@ee.ubc.ca>
17 *
18 * Contacts:
19 * Michael Gallant <mikeg@ee.ubc.ca>
20 *
21 * UBC Image Processing Laboratory http://www.ee.ubc.ca/image
22 * 2356 Main Mall tel.: +1 604 822 4051
23 * Vancouver BC Canada V6T1Z4 fax.: +1 604 822 5949
24 *
25 ************************************************************************/
26
27 /* Disclaimer of Warranty
28 *
29 * These software programs are available to the user without any license fee
30 * or royalty on an "as is" basis. The University of British Columbia
31 * disclaims any and all warranties, whether express, implied, or
32 * statuary, including any implied warranties or merchantability or of
33 * fitness for a particular purpose. In no event shall the
34 * copyright-holder be liable for any incidental, punitive, or
35 * consequential damages of any kind whatsoever arising from the use of
36 * these programs.
37 *
38 * This disclaimer of warranty extends to the user of these programs and
39 * user's customers, employees, agents, transferees, successors, and
40 * assigns.
41 *
42 * The University of British Columbia does not represent or warrant that the
43 * programs furnished hereunder are free of infringement of any
44 * third-party patents.
45 *
46 * Commercial implementations of H.263, including shareware, are subject to
47 * royalty fees to patent holders. Many of these patents are general
48 * enough such that they are unavoidable regardless of implementation
49 * design.
50 *
51 */
52
53
54
55 /* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and
56 * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de>
57 *
58 */
59
60
61 #include <stdio.h>
62 #include <stdlib.h>
63
64 #include "config.h"
65 #include "tmndec.h"
66 #include "global.h"
67
68 /* private prototypes */
69 static void recon_comp _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst,
70 int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int flag));
71 static void recon_comp_obmc _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int lx, int lx2, int comp, int w, int h, int x, int y));
72 static void rec _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
73 static void recon_bidir_average _ANSI_ARGS_ ((int bx, int by));
74 static void recc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
75 static void reco _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
76 static void rech _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
77 static void rechc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
78 static void recho _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
79 static void recv _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
80 static void recvc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
81 static void recvo _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
82 static void rec4 _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
83 static void rec4c _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
84 static void rec4o _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
85
86 void reconstruct (int bx, int by, int P, int bdx, int bdy, int MODB)
87 {
88 int w, h, lx, lx2, dx, dy, xp, yp, comp, sum;
89 int x, y, mode, xvec, yvec;
90 unsigned char *src[3];
91 int store_rtype;
92
93 x = bx / 16 + 1;
94 y = by / 16 + 1;
95 lx = coded_picture_width;
96
97 if (mv_outside_frame)
98 {
99 lx2 = coded_picture_width + 64;
100 src[0] = edgeframe[0];
101 src[1] = edgeframe[1];
102 src[2] = edgeframe[2];
103 } else
104 {
105 lx2 = coded_picture_width;
106 src[0] = prev_I_P_frame[0];
107 src[1] = prev_I_P_frame[1];
108 src[2] = prev_I_P_frame[2];
109 }
110
111 mode = modemap[y][x];
112
113 if (P)
114 {
115 /* P prediction */
116 if (use_4mv)
117 {
118 w = 8;
119 h = 8;
120 /* Y */
121 /* 4 MV can be used without OBMC in * deblocking filter mode */
122 if (overlapping_MC)
123 {
124 for (comp = 0; comp < 4; comp++)
125 {
126 xp = bx + ((comp & 1) << 3);
127 yp = by + ((comp & 2) << 2);
128 recon_comp_obmc (src[0], current_frame[0], lx, lx2, comp, w, h, xp, yp);
129 }
130 } else
131 {
132 if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
133 {
134 for (comp = 0; comp < 4; comp++)
135 {
136 dx = MV[0][comp + 1][y][x];
137 dy = MV[1][comp + 1][y][x];
138
139 xp = bx + ((comp & 1) << 3);
140 yp = by + ((comp & 2) << 2);
141 recon_comp (src[0], current_frame[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
142 }
143 } else
144 {
145 dx = MV[0][0][y][x];
146 dy = MV[1][0][y][x];
147 recon_comp (src[0], current_frame[0], lx, lx2, w << 1, h << 1, bx, by, dx, dy, 0);
148 }
149 }
150 /* Chroma */
151 if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
152 {
153
154 sum = MV[0][1][y][x] + MV[0][2][y][x] + MV[0][3][y][x] + MV[0][4][y][x];
155 dx = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
156
157 sum = MV[1][1][y][x] + MV[1][2][y][x] + MV[1][3][y][x] + MV[1][4][y][x];
158 dy = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
159
160 } else
161 {
162 dx = MV[0][0][y][x];
163 dy = MV[1][0][y][x];
164 /* chroma rounding */
165 dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
166 dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
167 }
168 lx >>= 1;
169 bx >>= 1;
170 lx2 >>= 1;
171 by >>= 1;
172 /* Chroma */
173 recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
174 recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
175 } else
176 { /* normal prediction mode */
177 /* P prediction */
178 w = 16;
179 h = 16;
180 dx = MV[0][0][y][x];
181 dy = MV[1][0][y][x];
182
183 /* Y */
184 recon_comp (src[0], current_frame[0], lx, lx2, w, h, bx, by, dx, dy, 0);
185
186 lx >>= 1;
187 w >>= 1;
188 bx >>= 1;
189 lx2 >>= 1;
190 h >>= 1;
191 by >>= 1;
192 /* chroma rounding */
193 dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
194 dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
195
196 /* Chroma */
197 recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
198 recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
199 }
200 } else
201 {
202 store_rtype = rtype;
203 rtype = 0;
204 /* B forward prediction */
205 if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_FRW_PRED || MODB == PBMODE_FRW_PRED))
206 {
207 w = 16;
208 h = 16;
209 dx = bdx;
210 dy = bdy;
211
212 /* Y */
213 recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
214
215 lx >>= 1;
216 w >>= 1;
217 bx >>= 1;
218 lx2 >>= 1;
219 h >>= 1;
220 by >>= 1;
221 /* chroma rounding */
222 dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
223 dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
224
225 /* Chroma */
226 recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
227 recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
228 } else if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_BCKW_PRED || MODB == PBMODE_BCKW_PRED))
229 {
230 lx2 = coded_picture_width;
231 src[0] = prev_I_P_frame[0];
232 src[1] = prev_I_P_frame[1];
233 src[2] = prev_I_P_frame[2];
234
235 w = 16;
236 h = 16;
237
238 /* Y */
239 recon_comp (current_frame[0], bframe[0], lx, lx2, w, h, bx, by, 0, 0, 0);
240
241 lx >>= 1;
242 w >>= 1;
243 bx >>= 1;
244 lx2 >>= 1;
245 h >>= 1;
246 by >>= 1;
247
248 /* Chroma */
249 recon_comp (current_frame[1], bframe[1], lx, lx2, w, h, bx, by, 0, 0, 1);
250 recon_comp (current_frame[2], bframe[2], lx, lx2, w, h, bx, by, 0, 0, 2);
251 } else
252 {
253 /* B bidir prediction */
254 if (pb_frame == IM_PB_FRAMES)
255 {
256 bdx = 0;
257 bdy = 0;
258 }
259 if (use_4mv && (mode == MODE_INTER4V || mode == MODE_INTER4V_Q))
260 {
261 w = 8;
262 h = 8;
263 /* Y */
264 xvec = yvec = 0;
265 for (comp = 0; comp < 4; comp++)
266 {
267 xvec += dx = (trb) * MV[0][comp + 1][y][x] / trd + bdx;
268 yvec += dy = (trb) * MV[1][comp + 1][y][x] / trd + bdy;
269 xp = bx + ((comp & 1) << 3);
270 yp = by + ((comp & 2) << 2);
271 recon_comp (src[0], bframe[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
272 }
273
274 /* chroma rounding (table 16/H.263) */
275 dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
276 dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
277
278 lx >>= 1;
279 bx >>= 1;
280 lx2 >>= 1;
281 by >>= 1;
282 /* Chroma */
283 recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
284 recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
285 } else
286 {
287 /* B bidir prediction with 16x16 blocks */
288 w = 16;
289 h = 16;
290
291 dx = (trb) * MV[0][0][y][x] / trd + bdx;
292 dy = (trb) * MV[1][0][y][x] / trd + bdy;
293 /* Y */
294 recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
295
296 lx >>= 1;
297 w >>= 1;
298 bx >>= 1;
299 lx2 >>= 1;
300 h >>= 1;
301 by >>= 1;
302
303 xvec = 4 * dx;
304 yvec = 4 * dy;
305
306 /* chroma rounding (table 16/H.263) */
307 dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
308 dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
309
310 /* Chroma */
311 recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
312 recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
313 }
314 }
315 rtype = store_rtype;
316 }
317 }
318
319 /**********************************************************************
320 *
321 * Name: reconstruct_true_B
322 * Description: Reconstructs true B MB
323 *
324 * Input: position, mb prediction type
325 * Returns:
326 * Side effects:
327 *
328 * Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca
329 *
330 ***********************************************************************/
331
332 void reconstruct_true_B (int bx, int by, int true_B_prediction_type)
333 {
334 int w, h, lx, lx2, dxf, dyf, dxb, dyb;
335 int x, y, mode;
336 int bx_chroma, by_chroma;
337 unsigned char *src_f[3], *src_b[3];
338
339 x = bx / 16 + 1;
340 y = by / 16 + 1;
341 lx = coded_picture_width;
342 w = 16;
343 h = 16;
344
345 lx2 = coded_picture_width + 64;
346 src_f[0] = edgeframe[0];
347 src_f[1] = edgeframe[1];
348 src_f[2] = edgeframe[2];
349 src_b[0] = nextedgeframe[0];
350 src_b[1] = nextedgeframe[1];
351 src_b[2] = nextedgeframe[2];
352
353 mode = modemap[y][x];
354
355 switch (true_B_prediction_type)
356 {
357
358 case B_DIRECT_PREDICTION:
359
360 dxf = (true_b_trb) * true_B_direct_mode_MV[0][y][x] / trd;
361 dyf = (true_b_trb) * true_B_direct_mode_MV[1][y][x] / trd;
362 dxb = (true_b_trb - trd) * true_B_direct_mode_MV[0][y][x] / trd;
363 dyb = (true_b_trb - trd) * true_B_direct_mode_MV[1][y][x] / trd;
364
365 /* Y */
366 recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
367 recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
368
369 lx >>= 1;
370 w >>= 1;
371 bx >>= 1;
372 lx2 >>= 1;
373 h >>= 1;
374 by >>= 1;
375
376 /* Chroma rounding (table 16/H.263) */
377 dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
378 dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
379 dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
380 dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
381
382 /* Chroma */
383 recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
384 recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
385 recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
386 recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
387
388 bx <<= 1;
389 by <<= 1;
390
391 /* Average forward and backward prediction. */
392 recon_bidir_average (bx, by);
393
394 break;
395
396 case B_FORWARD_PREDICTION:
397
398 w = 16;
399 h = 16;
400 dxf = MV[0][0][y][x];
401 dyf = MV[1][0][y][x];
402
403 /* Y */
404 recon_comp (src_f[0], bframe[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
405
406 lx >>= 1;
407 w >>= 1;
408 bx >>= 1;
409 lx2 >>= 1;
410 h >>= 1;
411 by >>= 1;
412
413 /* chroma rounding */
414 dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
415 dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
416
417 /* Chroma */
418 recon_comp (src_f[1], bframe[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
419 recon_comp (src_f[2], bframe[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
420
421 break;
422
423 case B_BACKWARD_PREDICTION:
424
425 w = 16;
426 h = 16;
427 dxb = MV[0][5][y][x];
428 dyb = MV[1][5][y][x];
429
430 /* Y */
431 recon_comp (src_b[0], bframe[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
432
433 lx >>= 1;
434 w >>= 1;
435 bx >>= 1;
436 lx2 >>= 1;
437 h >>= 1;
438 by >>= 1;
439 /* chroma rounding */
440 dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
441 dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
442
443 /* Chroma */
444 recon_comp (src_b[1], bframe[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
445 recon_comp (src_b[2], bframe[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
446
447 break;
448
449 case B_BIDIRECTIONAL_PREDICTION:
450
451 w = 16;
452 h = 16;
453
454 dxf = MV[0][0][y][x];
455 dyf = MV[1][0][y][x];
456 dxb = MV[0][5][y][x];
457 dyb = MV[1][5][y][x];
458
459 /* Y */
460 recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
461 recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
462
463 lx >>= 1;
464 w >>= 1;
465 lx2 >>= 1;
466 h >>= 1;
467
468 bx_chroma = bx >> 1;
469 by_chroma = by >> 1;
470
471
472 dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
473 dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
474 dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
475 dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
476
477 /* Chroma */
478 recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
479 recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
480 recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 1);
481 recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 2);
482
483 /* Average forward and backward prediction. */
484 recon_bidir_average (bx, by);
485
486 break;
487
488 default:
489
490 fprintf (stderr, "Illegal scalable prediction type in reconstruct_true_B (recon.c)\n");
491 exit (-1);
492 break;
493
494 }
495 }
496
497 /**********************************************************************
498 *
499 * Name: reconstruct_ei_ep
500 * Description: Reconstructs ei and ep MBs
501 *
502 * Input: position, mb prediction type
503 * Returns:
504 * Side effects:
505 *
506 * Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
507 *
508 ***********************************************************************/
509 void reconstruct_ei_ep (int bx, int by, int ei_ep_prediction_type)
510 {
511 int w, h, lx, lx2, dxf, dyf;
512 int x, y, mode;
513 int bx_chroma, by_chroma;
514 unsigned char *src_fwd[3], *src_up[3], *tmp_fwd[3], *tmp_up[3];
515
516 /* current_refererence frame should be upsampled already if spatial scalbility is in use */
517
518 x = bx / 16 + 1;
519 y = by / 16 + 1;
520 lx = coded_picture_width;
521 w = 16;
522 h = 16;
523
524 lx2 = coded_picture_width + 64;
525 src_fwd[0] = enhance_edgeframe[enhancement_layer_num-2][0];
526 src_fwd[1] = enhance_edgeframe[enhancement_layer_num-2][1];
527 src_fwd[2] = enhance_edgeframe[enhancement_layer_num-2][2];
528 src_up[0] = curr_reference_frame[0];
529 src_up[1] = curr_reference_frame[1];
530 src_up[2] = curr_reference_frame[2];
531
532 tmp_fwd[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
533 tmp_fwd[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
534 tmp_fwd[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
535 tmp_up[0] = tmp_enhance_up[enhancement_layer_num-2][0];
536 tmp_up[1] = tmp_enhance_up[enhancement_layer_num-2][1];
537 tmp_up[2] = tmp_enhance_up[enhancement_layer_num-2][2];
538
539 mode = modemap[y][x];
540
541 switch (ei_ep_prediction_type)
542 {
543
544 case EP_FORWARD_PREDICTION:
545
546 w = 16;
547 h = 16;
548 dxf = MV[0][0][y][x];
549 dyf = MV[1][0][y][x];
550
551 /* Y */
552 recon_comp (src_fwd[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
553
554 lx >>= 1;
555 w >>= 1;
556 bx >>= 1;
557 lx2 >>= 1;
558 h >>= 1;
559 by >>= 1;
560
561 /* chroma rounding */
562 dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
563 dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
564
565 /* Chroma */
566 recon_comp (src_fwd[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
567 recon_comp (src_fwd[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
568
569 break;
570
571 case EI_EP_UPWARD_PREDICTION:
572
573 /* Inter 16x16 */
574 w = 16;
575 h = 16;
576
577 /* Y */
578 recon_comp (src_up[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx, w, h, bx, by, 0, 0, 0);
579
580 lx >>= 1;
581 w >>= 1;
582 bx >>= 1;
583 lx2 >>= 1;
584 h >>= 1;
585 by >>= 1;
586
587 /* Chroma */
588 recon_comp (src_up[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx, w, h, bx, by, 0, 0, 1);
589 recon_comp (src_up[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx, w, h, bx, by, 0, 0, 2);
590
591 break;
592
593 case EP_BIDIRECTIONAL_PREDICTION:
594
595 w = 16;
596 h = 16;
597
598 dxf = MV[0][0][y][x];
599 dyf = MV[1][0][y][x];
600
601 /* Y */
602 recon_comp (src_fwd[0], tmp_fwd[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
603 recon_comp (src_up[0], tmp_up[0], lx, lx, w, h, bx, by, 0, 0, 0);
604
605 lx >>= 1;
606 w >>= 1;
607 lx2 >>= 1;
608 h >>= 1;
609
610 bx_chroma = bx >> 1;
611 by_chroma = by >> 1;
612
613
614 dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
615 dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
616
617 /* Chroma */
618 recon_comp (src_fwd[1], tmp_fwd[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
619 recon_comp (src_fwd[2], tmp_fwd[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
620 recon_comp (src_up[1], tmp_up[1], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 1);
621 recon_comp (src_up[2], tmp_up[2], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 2);
622
623 /* Average forward and backward prediction. */
624 recon_bidir_average (bx, by);
625
626 break;
627
628 default:
629
630 fprintf (stderr, "Illegal scalable prediction type in reconstruct_ei_ep (recon.c)\n");
631 exit (-1);
632
633 break;
634
635 }
636 }
637
638 static void recon_comp (unsigned char *src, unsigned char *dst,
639 int lx, int lx2, int w, int h, int x,
640 int y, int dx, int dy, int chroma)
641 {
642 int xint, xh, yint, yh;
643 unsigned char *s, *d;
644
645 xint = dx >> 1;
646 xh = dx & 1;
647 yint = dy >> 1;
648 yh = dy & 1;
649
650 /* origins */
651 s = src + lx2 * (y + yint) + x + xint;
652 d = dst + lx * y + x;
653
654 if (!xh && !yh)
655 if (w != 8)
656 rec (s, d, lx, lx2, h);
657 else
658 recc (s, d, lx, lx2, h);
659 else if (!xh && yh)
660 if (w != 8)
661 recv (s, d, lx, lx2, h);
662 else
663 recvc (s, d, lx, lx2, h);
664 else if (xh && !yh)
665 if (w != 8)
666 rech (s, d, lx, lx2, h);
667 else
668 rechc (s, d, lx, lx2, h);
669 else
670 /* if (xh && yh) */ if (w != 8)
671 rec4 (s, d, lx, lx2, h);
672 else
673 rec4c (s, d, lx, lx2, h);
674 }
675
676 static void rec (unsigned char *s, unsigned char *d,
677 int lx, int lx2, int h)
678 {
679 int j;
680
681 for (j = 0; j < h; j++)
682 {
683 d[0] = s[0];
684 d[1] = s[1];
685 d[2] = s[2];
686 d[3] = s[3];
687 d[4] = s[4];
688 d[5] = s[5];
689 d[6] = s[6];
690 d[7] = s[7];
691 d[8] = s[8];
692 d[9] = s[9];
693 d[10] = s[10];
694 d[11] = s[11];
695 d[12] = s[12];
696 d[13] = s[13];
697 d[14] = s[14];
698 d[15] = s[15];
699 s += lx2;
700 d += lx;
701 }
702 }
703
704 /**********************************************************************
705 *
706 * Name: recon_bidir_average
707 * Description: move average of bidir predicted blocks into current frame
708 *
709 * Input: absolute position of current MB
710 *
711 * Returns:
712 * Side effects:
713 *
714 * Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
715 *
716 ***********************************************************************/
717 static void recon_bidir_average (int bx, int by)
718 {
719 int i, iincr, cc, comp;
720 unsigned char *avg, *forw, *backw;
721 unsigned char *prev_frame[3], *next_frame[3], *curr[3];
722
723 /* B picture */
724 if (PCT_B == pict_type)
725 {
726 prev_frame[0] = tmp_f[0];
727 prev_frame[1] = tmp_f[1];
728 prev_frame[2] = tmp_f[2];
729 next_frame[0] = tmp_b[0];
730 next_frame[1] = tmp_b[1];
731 next_frame[2] = tmp_b[2];
732 curr[0] = current_frame[0];
733 curr[1] = current_frame[1];
734 curr[2] = current_frame[2];
735 }
736 /* EP picture */
737 else
738 {
739 prev_frame[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
740 prev_frame[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
741 prev_frame[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
742 next_frame[0] = tmp_enhance_up[enhancement_layer_num-2][0];
743 next_frame[1] = tmp_enhance_up[enhancement_layer_num-2][1];
744 next_frame[2] = tmp_enhance_up[enhancement_layer_num-2][2];
745 curr[0] = current_enhancement_frame[enhancement_layer_num-2][0];
746 curr[1] = current_enhancement_frame[enhancement_layer_num-2][1];
747 curr[2] = current_enhancement_frame[enhancement_layer_num-2][2];
748 }
749
750 for (comp = 0; comp < 6; ++comp)
751 {
752 cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
753
754 /* luminance */
755 if (cc == 0)
756 {
757 avg = curr[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
758 forw = prev_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
759 backw = next_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
760 iincr = coded_picture_width;
761 }
762 /* chrominance */
763 else
764 {
765 /* scale coordinates */
766 if (4 == comp)
767 {
768 bx >>= 1;
769 by >>= 1;
770 }
771 avg = curr[cc] + chrom_width * by + bx;
772 forw = prev_frame[cc] + chrom_width * by + bx;
773 backw = next_frame[cc] + chrom_width * by + bx;
774 iincr = chrom_width;
775 }
776
777 for (i = 0; i < 8; i++)
778 {
779 avg[0] = (forw[0] + backw[0]) / 2;
780 avg[1] = (forw[1] + backw[1]) / 2;
781 avg[2] = (forw[2] + backw[2]) / 2;
782 avg[3] = (forw[3] + backw[3]) / 2;
783 avg[4] = (forw[4] + backw[4]) / 2;
784 avg[5] = (forw[5] + backw[5]) / 2;
785 avg[6] = (forw[6] + backw[6]) / 2;
786 avg[7] = (forw[7] + backw[7]) / 2;
787 avg += iincr;
788 forw += iincr;
789 backw += iincr;
790 }
791 }
792 }
793
794
795 static void recc (unsigned char *s, unsigned char *d,
796 int lx, int lx2, int h)
797 {
798 int j;
799
800 for (j = 0; j < h; j++)
801 {
802 d[0] = s[0];
803 d[1] = s[1];
804 d[2] = s[2];
805 d[3] = s[3];
806 d[4] = s[4];
807 d[5] = s[5];
808 d[6] = s[6];
809 d[7] = s[7];
810 s += lx2;
811 d += lx;
812 }
813 }
814
815 static void reco (unsigned char *s, int *d, int lx, int lx2,
816 int addflag, int c, int xa, int xb,
817 int ya, int yb)
818 {
819 int i, j;
820 int *om;
821
822 om = &OM[c][ya][0];
823
824 if (!addflag)
825 {
826 for (j = ya; j < yb; j++)
827 {
828 for (i = xa; i < xb; i++)
829 {
830 d[i] = s[i] * om[i];
831 }
832 s += lx2;
833 d += lx;
834 om += 8;
835 }
836 } else
837 {
838 for (j = ya; j < yb; j++)
839 {
840 for (i = xa; i < xb; i++)
841 {
842 d[i] += s[i] * om[i];
843 }
844 s += lx2;
845 d += lx;
846 om += 8;
847 }
848 }
849 }
850
851 static void rech (unsigned char *s, unsigned char *d,
852 int lx, int lx2, int h)
853 {
854 unsigned char *dp, *sp;
855 int j;
856 unsigned int s1, s2;
857
858 sp = s;
859 dp = d;
860 for (j = 0; j < h; j++)
861 {
862 s1 = sp[0];
863 dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
864 dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
865 dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
866 dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
867 dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
868 dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
869 dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
870 dp[7] = (unsigned int) (s2 + (s1 = sp[8]) + 1 - rtype) >> 1;
871 dp[8] = (unsigned int) (s1 + (s2 = sp[9]) + 1 - rtype) >> 1;
872 dp[9] = (unsigned int) (s2 + (s1 = sp[10]) + 1 - rtype) >> 1;
873 dp[10] = (unsigned int) (s1 + (s2 = sp[11]) + 1 - rtype) >> 1;
874 dp[11] = (unsigned int) (s2 + (s1 = sp[12]) + 1 - rtype) >> 1;
875 dp[12] = (unsigned int) (s1 + (s2 = sp[13]) + 1 - rtype) >> 1;
876 dp[13] = (unsigned int) (s2 + (s1 = sp[14]) + 1 - rtype) >> 1;
877 dp[14] = (unsigned int) (s1 + (s2 = sp[15]) + 1 - rtype) >> 1;
878 dp[15] = (unsigned int) (s2 + sp[16] + 1 - rtype) >> 1;
879 sp += lx2;
880 dp += lx;
881 }
882 }
883
884 static void rechc (unsigned char *s, unsigned char *d,
885 int lx, int lx2, int h)
886 {
887 unsigned char *dp, *sp;
888 int j;
889 unsigned int s1, s2;
890
891 sp = s;
892 dp = d;
893 for (j = 0; j < h; j++)
894 {
895 s1 = sp[0];
896 dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
897 dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
898 dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
899 dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
900 dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
901 dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
902 dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
903 dp[7] = (unsigned int) (s2 + sp[8] + 1 - rtype) >> 1;
904 sp += lx2;
905 dp += lx;
906 }
907 }
908
909 static void recho (unsigned char *s, int *d, int lx, int lx2,
910 int addflag, int c, int xa, int xb, int ya, int yb)
911 {
912 int *dp, *om;
913 unsigned char *sp;
914 int i, j;
915
916 sp = s;
917 dp = d;
918 om = &OM[c][ya][0];
919
920 if (!addflag)
921 {
922 for (j = ya; j < yb; j++)
923 {
924 for (i = xa; i < xb; i++)
925 {
926 dp[i] = (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * om[i];
927 }
928 sp += lx2;
929 dp += lx;
930 om += 8;
931 }
932 } else
933 {
934 for (j = ya; j < yb; j++)
935 {
936 for (i = xa; i < xb; i++)
937 {
938 dp[i] += (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * OM[c][j][i];
939 }
940 sp += lx2;
941 dp += lx;
942 om += 8;
943 }
944 }
945 }
946
947 static void recv (unsigned char *s, unsigned char *d,
948 int lx, int lx2, int h)
949 {
950 unsigned char *dp, *sp, *sp2;
951 int j;
952
953 sp = s;
954 sp2 = s + lx2;
955 dp = d;
956 for (j = 0; j < h; j++)
957 {
958 dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
959 dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
960 dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
961 dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
962 dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
963 dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
964 dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
965 dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
966 dp[8] = (unsigned int) (sp[8] + sp2[8] + 1 - rtype) >> 1;
967 dp[9] = (unsigned int) (sp[9] + sp2[9] + 1 - rtype) >> 1;
968 dp[10] = (unsigned int) (sp[10] + sp2[10] + 1 - rtype) >> 1;
969 dp[11] = (unsigned int) (sp[11] + sp2[11] + 1 - rtype) >> 1;
970 dp[12] = (unsigned int) (sp[12] + sp2[12] + 1 - rtype) >> 1;
971 dp[13] = (unsigned int) (sp[13] + sp2[13] + 1 - rtype) >> 1;
972 dp[14] = (unsigned int) (sp[14] + sp2[14] + 1 - rtype) >> 1;
973 dp[15] = (unsigned int) (sp[15] + sp2[15] + 1 - rtype) >> 1;
974 sp += lx2;
975 sp2 += lx2;
976 dp += lx;
977 }
978 }
979
980 static void recvc (unsigned char *s, unsigned char *d,
981 int lx, int lx2, int h)
982 {
983 unsigned char *dp, *sp, *sp2;
984 int j;
985
986 sp = s;
987 sp2 = s + lx2;
988 dp = d;
989
990 for (j = 0; j < h; j++)
991 {
992 dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
993 dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
994 dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
995 dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
996 dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
997 dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
998 dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
999 dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
1000 sp += lx2;
1001 sp2 += lx2;
1002 dp += lx;
1003 }
1004 }
1005
1006 static void recvo (unsigned char *s, int *d, int lx, int lx2,
1007 int addflag, int c, int xa, int xb, int ya,
1008