1implement Mpegd; 2 3include "sys.m"; 4include "mpegio.m"; 5 6sys: Sys; 7idct: IDCT; 8 9Mpegi, Picture, Slice, MacroBlock, YCbCr, Pair: import Mpegio; 10 11intra_tab := array[64] of { 12 8, 16, 19, 22, 26, 27, 29, 34, 13 16, 16, 22, 24, 27, 29, 34, 37, 14 19, 22, 26, 27, 29, 34, 34, 38, 15 22, 22, 26, 27, 29, 34, 37, 40, 16 22, 26, 27, 29, 32, 35, 40, 48, 17 26, 27, 29, 32, 35, 40, 48, 58, 18 26, 27, 29, 34, 38, 46, 56, 69, 19 27, 29, 35, 38, 46, 56, 69, 83, 20}; 21 22nintra_tab := array[64] of { * => 16 }; 23 24CLOFF: con 256; 25 26intraQ, nintraQ: array of int; 27rtmp: array of array of int; 28rflag := array[6] of int; 29rforw, dforw, rback, dback: int; 30rforw2, dforw2, rback2, dback2: int; 31ydb, ydf, cdb, cdf: int; 32vflags: int; 33past := array[3] of int; 34pinit := array[3] of { * => 128 * 8 }; 35zeros := array[64] of { * => 0 }; 36zeros1: array of int; 37clamp := array[CLOFF + 256 + CLOFF] of byte; 38width, height, w2, h2: int; 39mpi, mps, yadj, cadj, yskip: int; 40I, B0: ref YCbCr; 41Ps := array[2] of ref YCbCr; 42Rs := array[2] of ref YCbCr; 43P, B, R, M, N: ref YCbCr; 44pn: int = 0; 45rn: int = 0; 46 47zig := array[64] of { 48 0, 1, 8, 16, 9, 2, 3, 10, 17, 49 24, 32, 25, 18, 11, 4, 5, 50 12, 19, 26, 33, 40, 48, 41, 34, 51 27, 20, 13, 6, 7, 14, 21, 28, 52 35, 42, 49, 56, 57, 50, 43, 36, 53 29, 22, 15, 23, 30, 37, 44, 51, 54 58, 59, 52, 45, 38, 31, 39, 46, 55 53, 60, 61, 54, 47, 55, 62, 63, 56}; 57 58init(m: ref Mpegi) 59{ 60 sys = load Sys Sys->PATH; 61 idct = load IDCT IDCT->PATH; 62 if (idct == nil) { 63 sys->print("could not open %s: %r\n", IDCT->PATH); 64 exit; 65 } 66 idct->init(); 67 width = m.width; 68 height = m.height; 69 w2 = width >> 1; 70 h2 = height >> 1; 71 mps = width >> 4; 72 mpi = mps * height >> 4; 73 yskip = 8 * width; 74 yadj = 16 * width - (width - 16); 75 cadj = 8 * w2 - (w2 - 8); 76 I = frame(); 77 Ps[0] = frame(); 78 Ps[1] = frame(); 79 Rs[0] = Ps[0]; 80 Rs[1] = Ps[1]; 81 B0 = frame(); 82 for (i := 0; i < CLOFF; i++) 83 clamp[i] = byte 0; 84 for (i = 0; i < 256; i++) 85 clamp[i + CLOFF] = byte i; 86 for (i = CLOFF + 256; i < CLOFF + 256 + CLOFF; i++) 87 clamp[i] = byte 255; 88 if (m.intra == nil) 89 intraQ = intra_tab; 90 else 91 intraQ = zigof(m.intra); 92 if (m.nintra == nil) 93 nintraQ = nintra_tab; 94 else 95 nintraQ = zigof(m.nintra); 96 rtmp = array[6] of array of int; 97 for (i = 0; i < 6; i++) 98 rtmp[i] = array[64] of int; 99 zeros1 = zeros[1:]; 100} 101 102zarray(n: int, v: byte): array of byte 103{ 104 return array[n] of { * => v }; 105} 106 107frame(): ref YCbCr 108{ 109 y := zarray(width * height, byte 0); 110 b := zarray(w2 * h2, byte 128); 111 r := zarray(w2 * h2, byte 128); 112 return ref YCbCr(y, b, r); 113} 114 115zigof(a: array of int): array of int 116{ 117 z := array[64] of int; 118 for (i := 0; i < 64; i++) 119 z[zig[i]] = a[i]; 120 return z; 121} 122 123invQ_intra(a: array of Pair, q: int, b: array of int) 124{ 125 (nil, t) := a[0]; 126 b[0] = t * 8; 127 b[1:] = zeros1; 128 n := 1; 129 i := 1; 130 while (n < len a) { 131 (r, l) := a[n++]; 132 i += r; 133 x := zig[i++]; 134 if (l > 0) { 135 v := l * q * intraQ[x] >> 3; 136 if (v > 2047) 137 b[x] = 2047; 138 else 139 b[x] = (v - 1) | 1; 140 } else { 141 v := (l * q * intraQ[x] + 7) >> 3; 142 if (v < -2048) 143 b[x] = -2048; 144 else 145 b[x] = v | 1; 146 } 147 #sys->print("%d %d %d %d\n", x, r, l, b[x]); 148 } 149} 150 151invQ_nintra(a: array of Pair, q: int, b: array of int) 152{ 153 b[0:] = zeros; 154 i := 0; 155 for (n := 0; n < len a; n++) { 156 (r, l) := a[n]; 157 i += r; 158 if (l == 0) { 159 raisex("zero level"); 160 i++; 161 continue; 162 } 163 x := zig[i++]; 164 if (l > 0) { 165 v := ((l << 1) + 1) * q * nintraQ[x] >> 4; 166 if (v > 2047) 167 b[x] = 2047; 168 else 169 b[x] = (v - 1) | 1; 170 } else { 171 v := (((l << 1) - 1) * q * nintraQ[x] + 15) >> 4; 172 if (v < -2048) 173 b[x] = -2048; 174 else 175 b[x] = v | 1; 176 } 177 #sys->print("%d %d %d %d\n", x, r, l, b[x]); 178 } 179} 180 181yzero(v: array of byte, base: int) 182{ 183 x := 0; 184 i := 8; 185 do { 186 n := base; 187 j := 8; 188 do 189 v[n++] = byte 0; 190 while (--j > 0); 191 base += width; 192 } while (--i > 0); 193} 194 195czero(v: array of byte, base: int) 196{ 197 x := 0; 198 i := 8; 199 do { 200 n := base; 201 j := 8; 202 do 203 v[n++] = byte 128; 204 while (--j > 0); 205 base += w2; 206 } while (--i > 0); 207 208} 209 210blockzero(d: ref YCbCr) 211{ 212 yzero(d.Y, ybase); 213 yzero(d.Y, ybase + 8); 214 yzero(d.Y, ybase + yskip); 215 yzero(d.Y, ybase + 8 + yskip); 216 czero(d.Cb, cbase); 217 czero(d.Cr, cbase); 218} 219 220ydistr(a: array of int, v: array of byte, base: int) 221{ 222 x := 0; 223 i := 8; 224 do { 225 n := base; 226 j := 8; 227 do 228 v[n++] = clamp[a[x++] + CLOFF]; 229 while (--j > 0); 230 base += width; 231 } while (--i > 0); 232} 233 234cdistr(a: array of int, v: array of byte, base: int) 235{ 236 x := 0; 237 i := 8; 238 do { 239 n := base; 240 j := 8; 241 do 242 v[n++] = clamp[a[x++] + CLOFF]; 243 while (--j > 0); 244 base += w2; 245 } while (--i > 0); 246 247} 248 249invQ_intra_block(b: array of array of Pair, q: int, pred: int, d: ref YCbCr) 250{ 251 a, dc: array of int; 252 if (pred) 253 dc = past; 254 else 255 dc = pinit; 256 p := dc[0]; 257 for (i := 0; i < 4; i++) { 258 a = rtmp[i]; 259 #sys->print("%d\n", i); 260 invQ_intra(b[i], q, a); 261 p += a[0]; 262 a[0] = p; 263 #sys->print("%d\n", a[0]); 264 idct->idct(a); 265 } 266 past[0] = p; 267 for (i = 4; i < 6; i++) { 268 p = dc[i - 3]; 269 a = rtmp[i]; 270 #sys->print("%d\n", i); 271 invQ_intra(b[i], q, a); 272 p += a[0]; 273 a[0] = p; 274 #sys->print("%d\n", a[0]); 275 past[i - 3] = p; 276 idct->idct(a); 277 } 278 ydistr(rtmp[0], d.Y, ybase); 279 ydistr(rtmp[1], d.Y, ybase + 8); 280 ydistr(rtmp[2], d.Y, ybase + yskip); 281 ydistr(rtmp[3], d.Y, ybase + 8 + yskip); 282 cdistr(rtmp[4], d.Cb, cbase); 283 cdistr(rtmp[5], d.Cr, cbase); 284} 285 286invQ_nintra_block(b: array of array of Pair, q: int) 287{ 288 for (i := 0; i < 6; i++) { 289 p := b[i]; 290 if (p != nil) { 291 a := rtmp[i]; 292 #sys->print("%d\n", i); 293 invQ_nintra(p, q, a); 294 idct->idct(a); 295 rflag[i] = 1; 296 } else 297 rflag[i] = 0; 298 } 299} 300 301mbr, ybase, cbase: int; 302 303nextmb() 304{ 305 if (--mbr == 0) { 306 ybase += yadj; 307 cbase += cadj; 308 mbr = mps; 309 } else { 310 ybase += 16; 311 cbase += 8; 312 } 313} 314 315copyblock(s, d: array of byte, b, n, w: int) 316{ 317 i := 8; 318 do { 319 d[b:] = s[b:b+n]; 320 b += w; 321 } while (--i > 0); 322} 323 324copyblockdisp(s, d: array of byte, b, n, w, p: int) 325{ 326 i := 8; 327 p += b; 328 do { 329 d[b:] = s[p:p+n]; 330 b += w; 331 p += w; 332 } while (--i > 0); 333} 334 335interpblock(s0, s1, d: array of byte, b, n, w, p0, p1: int) 336{ 337 i := 8; 338 do { 339 dx := b; 340 s0x := b + p0; 341 s1x := b + p1; 342 j := n; 343 do 344 d[dx++] = byte ((int s0[s0x++] + int s1[s1x++] + 1) >> 1); 345 while (--j > 0); 346 b += w; 347 } while (--i > 0); 348} 349 350deltablock(s: array of byte, r: array of int, d: array of byte, b, w, o: int) 351{ 352 rx := 0; 353 i := 8; 354 do { 355 dx := b; 356 sx := b + o; 357 j := 8; 358 do 359 d[dx++] = clamp[CLOFF + int s[sx++] + r[rx++]]; 360 while (--j > 0); 361 b += w; 362 } while (--i > 0); 363} 364 365deltainterpblock(s0, s1: array of byte, r: array of int, d: array of byte, b, w, o0, o1: int) 366{ 367 rx := 0; 368 i := 8; 369 do { 370 dx := b; 371 s0x := b + o0; 372 s1x := b + o1; 373 j := 8; 374 do 375 d[dx++] = clamp[CLOFF + ((int s0[s0x++] + int s1[s1x++] + 1) >> 1) + r[rx++]]; 376 while (--j > 0); 377 b += w; 378 } while (--i > 0); 379} 380 381dispblock(s, d: array of byte, n, b, w, o: int) 382{ 383 if (rflag[n]) 384 deltablock(s, rtmp[n], d, b, w, o); 385 else 386 copyblockdisp(s, d, b, 8, w, o); 387} 388 389genblock(s0, s1, d: array of byte, n, b, w, o0, o1: int) 390{ 391 if (rflag[n]) 392 deltainterpblock(s0, s1, rtmp[n], d, b, w, o0, o1); 393 else 394 interpblock(s0, s1, d, b, 8, w, o0, o1); 395} 396 397copymb() 398{ 399 copyblock(R.Y, P.Y, ybase, 16, width); 400 copyblock(R.Y, P.Y, ybase + yskip, 16, width); 401 copyblock(R.Cb, P.Cb, cbase, 8, w2); 402 copyblock(R.Cr, P.Cr, cbase, 8, w2); 403} 404 405deltamb() 406{ 407 dispblock(R.Y, P.Y, 0, ybase, width, 0); 408 dispblock(R.Y, P.Y, 1, ybase + 8, width, 0); 409 dispblock(R.Y, P.Y, 2, ybase + yskip, width, 0); 410 dispblock(R.Y, P.Y, 3, ybase + 8 + yskip, width, 0); 411 dispblock(R.Cb, P.Cb, 4, cbase, w2, 0); 412 dispblock(R.Cr, P.Cr, 5, cbase, w2, 0); 413} 414 415copymbforw() 416{ 417 copyblockdisp(N.Y, B.Y, ybase, 16, width, ydf); 418 copyblockdisp(N.Y, B.Y, ybase + yskip, 16, width, ydf); 419 copyblockdisp(N.Cb, B.Cb, cbase, 8, w2, cdf); 420 copyblockdisp(N.Cr, B.Cr, cbase, 8, w2, cdf); 421} 422 423copymbback() 424{ 425 copyblockdisp(M.Y, B.Y, ybase, 16, width, ydb); 426 copyblockdisp(M.Y, B.Y, ybase + yskip, 16, width, ydb); 427 copyblockdisp(M.Cb, B.Cb, cbase, 8, w2, cdb); 428 copyblockdisp(M.Cr, B.Cr, cbase, 8, w2, cdb); 429} 430 431copymbbackforw() 432{ 433 interpblock(M.Y, N.Y, B.Y, ybase, 16, width, ydb, ydf); 434 interpblock(M.Y, N.Y, B.Y, ybase + yskip, 16, width, ydb, ydf); 435 interpblock(M.Cb, N.Cb, B.Cb, cbase, 8, w2, cdb, cdf); 436 interpblock(M.Cr, N.Cr, B.Cr, cbase, 8, w2, cdb, cdf); 437} 438 439deltambforw() 440{ 441 dispblock(N.Y, B.Y, 0, ybase, width, ydf); 442 dispblock(N.Y, B.Y, 1, ybase + 8, width, ydf); 443 dispblock(N.Y, B.Y, 2, ybase + yskip, width, ydf); 444 dispblock(N.Y, B.Y, 3, ybase + 8 + yskip, width, ydf); 445 dispblock(N.Cb, B.Cb, 4, cbase, w2, cdf); 446 dispblock(N.Cr, B.Cr, 5, cbase, w2, cdf); 447} 448 449deltambback() 450{ 451 dispblock(M.Y, B.Y, 0, ybase, width, ydb); 452 dispblock(M.Y, B.Y, 1, ybase + 8, width, ydb); 453 dispblock(M.Y, B.Y, 2, ybase + yskip, width, ydb); 454 dispblock(M.Y, B.Y, 3, ybase + 8 + yskip, width, ydb); 455 dispblock(M.Cb, B.Cb, 4, cbase, w2, cdb); 456 dispblock(M.Cr, B.Cr, 5, cbase, w2, cdb); 457} 458 459deltambbackforw() 460{ 461 genblock(M.Y, N.Y, B.Y, 0, ybase, width, ydb, ydf); 462 genblock(M.Y, N.Y, B.Y, 1, ybase + 8, width, ydb, ydf); 463 genblock(M.Y, N.Y, B.Y, 2, ybase + yskip, width, ydb, ydf); 464 genblock(M.Y, N.Y, B.Y, 3, ybase + 8 + yskip, width, ydb, ydf); 465 genblock(M.Cb, N.Cb, B.Cb, 4, cbase, w2, cdb, cdf); 466 genblock(M.Cr, N.Cr, B.Cr, 5, cbase, w2, cdb, cdf); 467} 468 469deltambinterp() 470{ 471 case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { 472 Mpegio->MB_MF => 473 deltambforw(); 474 Mpegio->MB_MB => 475 deltambback(); 476 Mpegio->MB_MF | Mpegio->MB_MB => 477 deltambbackforw(); 478 * => 479 raisex("bad vflags"); 480 } 481} 482 483interpmb() 484{ 485 case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { 486 Mpegio->MB_MF => 487 copymbforw(); 488 Mpegio->MB_MB => 489 copymbback(); 490 Mpegio->MB_MF | Mpegio->MB_MB => 491 copymbbackforw(); 492 * => 493 raisex("bad vflags"); 494 } 495} 496 497Idecode(p: ref Picture): ref YCbCr 498{ 499 sa := p.slices; 500 n := 0; 501 mbr = mps; 502 ybase = 0; 503 cbase = 0; 504 for (i := 0; i < len sa; i++) { 505 pred := 0; 506 ba := sa[i].blocks; 507 for (j := 0; j < len ba; j++) { 508 invQ_intra_block(ba[j].rls, ba[j].qscale, pred, I); 509 nextmb(); 510 n++; 511 pred = 1; 512 } 513 } 514 if (n != mpi) 515 raisex("I mb count"); 516 R = I; 517 Rs[rn] = I; 518 rn ^= 1; 519 return I; 520} 521 522Pdecode(p: ref Picture): ref YCbCr 523{ 524 rforwp, dforwp: int; 525 md, c: int; 526 P = Ps[pn]; 527 N = R; 528 B = P; 529 pn ^= 1; 530 fs := 1 << p.forwfc; 531 fsr := fs << 5; 532 fsmin := -(fs << 4); 533 fsmax := (fs << 4) - 1; 534 sa := p.slices; 535 n := 0; 536 mbr = mps; 537 ybase = 0; 538 cbase = 0; 539 for (i := 0; i < len sa; i++) { 540 pred := 0; 541 ipred := 0; 542 ba := sa[i].blocks; 543 for (j := 0; j < len ba; j++) { 544 mb := ba[j]; 545 while (n < mb.addr) { 546 copymb(); 547 ipred = 0; 548 pred = 0; 549 nextmb(); 550 n++; 551 } 552 if (mb.flags & Mpegio->MB_I) { 553 invQ_intra_block(mb.rls, mb.qscale, ipred, P); 554 #blockzero(P); 555 ipred = 1; 556 pred = 0; 557 } else { 558 if (mb.flags & Mpegio->MB_MF) { 559 if (fs == 1 || mb.mhfc == 0) 560 md = mb.mhfc; 561 else if ((c = mb.mhfc) < 0) 562 md = (c + 1) * fs - mb.mhfr - 1; 563 else 564 md = (c - 1) * fs + mb.mhfr + 1; 565 if (pred) 566 md += rforwp; 567 if (md > fsmax) 568 rforw = md - fsr; 569 else if (md < fsmin) 570 rforw = md + fsr; 571 else 572 rforw = md; 573 rforwp = rforw; 574 if (fs == 1 || mb.mvfc == 0) 575 md = mb.mvfc; 576 else if ((c = mb.mvfc) < 0) 577 md = (c + 1) * fs - mb.mvfr - 1; 578 else 579 md = (c - 1) * fs + mb.mvfr + 1; 580 if (pred) 581 md += dforwp; 582 if (md > fsmax) 583 dforw = md - fsr; 584 else if (md < fsmin) 585 dforw = md + fsr; 586 else 587 dforw = md; 588 dforwp = dforw; 589 if (p.flags & Mpegio->FPFV) { 590 rforw2 = rforw; 591 dforw2 = dforw; 592 rforw <<= 1; 593 dforw <<= 1; 594 ydf = rforw2 + dforw2 * width; 595 cdf = (rforw2 >> 1) + (dforw2 >> 1) * w2; 596 } else { 597 if (rforw < 0) 598 rforw2 = (rforw + 1) >> 1; 599 else 600 rforw2 = rforw >> 1; 601 if (dforw < 0) 602 dforw2 = (dforw + 1) >> 1; 603 else 604 dforw2 = dforw >> 1; 605 ydf = (rforw >> 1) + (dforw >> 1) * width; 606 cdf = (rforw2 >> 1) + (dforw2 >> 1) * w2; 607 } 608 pred = 1; 609 if (mb.rls != nil) { 610 invQ_nintra_block(mb.rls, mb.qscale); 611 deltambforw(); 612 } else 613 copymbforw(); 614 } else { 615 if (mb.rls == nil) 616 raisex("empty delta"); 617 invQ_nintra_block(mb.rls, mb.qscale); 618 deltamb(); 619 pred = 0; 620 } 621 ipred = 0; 622 } 623 nextmb(); 624 n++; 625 } 626 } 627 while (n < mpi) { 628 copymb(); 629 nextmb(); 630 n++; 631 } 632 R = P; 633 Rs[rn] = P; 634 rn ^= 1; 635 return P; 636} 637 638Bdecode(p: ref Mpegio->Picture): ref Mpegio->YCbCr 639{ 640 return Bdecode2(p, Rs[rn ^ 1], Rs[rn]); 641} 642 643Bdecode2(p: ref Mpegio->Picture, f0, f1: ref Mpegio->YCbCr): ref Mpegio->YCbCr 644{ 645 rforwp, dforwp, rbackp, dbackp: int; 646 md, c: int; 647 M = f0; 648 N = f1; 649 B = B0; 650 fs := 1 << p.forwfc; 651 fsr := fs << 5; 652 fsmin := -(fs << 4); 653 fsmax := (fs << 4) - 1; 654 bs := 1 << p.backfc; 655 bsr := bs << 5; 656 bsmin := -(bs << 4); 657 bsmax := (bs << 4) - 1; 658 sa := p.slices; 659 n := 0; 660 mbr = mps; 661 ybase = 0; 662 cbase = 0; 663 for (i := 0; i < len sa; i++) { 664 ipred := 0; 665 rback = 0; 666 rforw = 0; 667 dback = 0; 668 dforw = 0; 669 rbackp = 0; 670 rforwp = 0; 671 dbackp = 0; 672 dforwp = 0; 673 rback2 = 0; 674 rforw2 = 0; 675 dback2 = 0; 676 dforw2 = 0; 677 ydb = 0; 678 ydf = 0; 679 cdb = 0; 680 cdf = 0; 681 ba := sa[i].blocks; 682 for (j := 0; j < len ba; j++) { 683 mb := ba[j]; 684 while (n < mb.addr) { 685 interpmb(); 686 nextmb(); 687 ipred = 0; 688 n++; 689 } 690 if (mb.flags & Mpegio->MB_I) { 691 invQ_intra_block(mb.rls, mb.qscale, ipred, B); 692 ipred = 1; 693 rback = 0; 694 rforw = 0; 695 dback = 0; 696 dforw = 0; 697 rbackp = 0; 698 rforwp = 0; 699 dbackp = 0; 700 dforwp = 0; 701 rback2 = 0; 702 rforw2 = 0; 703 dback2 = 0; 704 dforw2 = 0; 705 ydb = 0; 706 ydf = 0; 707 cdb = 0; 708 cdf = 0; 709 } else { 710 if (mb.flags & Mpegio->MB_MF) { 711 if (fs == 1 || mb.mhfc == 0) 712 md = mb.mhfc; 713 else if ((c = mb.mhfc) < 0) 714 md = (c + 1) * fs - mb.mhfr - 1; 715 else 716 md = (c - 1) * fs + mb.mhfr + 1; 717 md += rforwp; 718 if (md > fsmax) 719 rforw = md - fsr; 720 else if (md < fsmin) 721 rforw = md + fsr; 722 else 723 rforw = md; 724 rforwp = rforw; 725 if (fs == 1 || mb.mvfc == 0) 726 md = mb.mvfc; 727 else if ((c = mb.mvfc) < 0) 728 md = (c + 1) * fs - mb.mvfr - 1; 729 else 730 md = (c - 1) * fs + mb.mvfr + 1; 731 md += dforwp; 732 if (md > fsmax) 733 dforw = md - fsr; 734 else if (md < fsmin) 735 dforw = md + fsr; 736 else 737 dforw = md; 738 dforwp = dforw; 739 if (p.flags & Mpegio->FPFV) { 740 rforw2 = rforw; 741 dforw2 = dforw; 742 rforw <<= 1; 743 dforw <<= 1; 744 ydf = rforw2 + dforw2 * width; 745 cdf = (rforw2 >> 1) + (dforw2 >> 1) * w2; 746 } else { 747 if (rforw < 0) 748 rforw2 = (rforw + 1) >> 1; 749 else 750 rforw2 = rforw >> 1; 751 if (dforw < 0) 752 dforw2 = (dforw + 1) >> 1; 753 else 754 dforw2 = dforw >> 1; 755 ydf = (rforw >> 1) + (dforw >> 1) * width; 756 cdf = (rforw2 >> 1) + (dforw2 >> 1) * w2; 757 } 758 } 759 if (mb.flags & Mpegio->MB_MB) { 760 if (bs == 1 || mb.mhbc == 0) 761 md = mb.mhbc; 762 else if ((c = mb.mhbc) < 0) 763 md = (c + 1) * bs - mb.mhbr - 1; 764 else 765 md = (c - 1) * bs + mb.mhbr + 1; 766 md += rbackp; 767 if (md > bsmax) 768 rback = md - bsr; 769 else if (md < bsmin) 770 rback = md + bsr; 771 else 772 rback = md; 773 rbackp = rback; 774 if (bs == 1 || mb.mvbc == 0) 775 md = mb.mvbc; 776 else if ((c = mb.mvbc) < 0) 777 md = (c + 1) * bs - mb.mvbr - 1; 778 else 779 md = (c - 1) * bs + mb.mvbr + 1; 780 md += dbackp; 781 if (md > bsmax) 782 dback = md - bsr; 783 else if (md < bsmin) 784 dback = md + bsr; 785 else 786 dback = md; 787 dbackp = dback; 788 if (p.flags & Mpegio->FPBV) { 789 rback2 = rback; 790 dback2 = dback; 791 rback <<= 1; 792 dback <<= 1; 793 ydb = rback2 + dback2 * width; 794 cdb = (rback2 >> 1) + (dback2 >> 1) * w2; 795 } else { 796 if (rback < 0) 797 rback2 = (rback + 1) >> 1; 798 else 799 rback2 = rback >> 1; 800 if (dback < 0) 801 dback2 = (dback + 1) >> 1; 802 else 803 dback2 = dback >> 1; 804 ydb = (rback >> 1) + (dback >> 1) * width; 805 cdb = (rback2 >> 1) + (dback2 >> 1) * w2; 806 } 807 } 808 vflags = mb.flags; 809 if (mb.rls != nil) { 810 invQ_nintra_block(mb.rls, mb.qscale); 811 deltambinterp(); 812 } else 813 interpmb(); 814 ipred = 0; 815 } 816 nextmb(); 817 n++; 818 } 819 } 820 while (n < mpi) { 821 interpmb(); 822 nextmb(); 823 n++; 824 } 825 return B; 826} 827 828raisex(nil: string) 829{ 830 raise "decode error"; 831} 832