Change the size detection a bit to recognize common video sizes, as the FOBJ codecs>=37 cannot always be trusted, since they can be embedded in a larger frame.
Unified · Split
| @@ -1603,6 +1603,7 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) · 1602 unmodified lines | |||
| 1603 | uint16_t w, h, parm2; | 1603 | uint16_t w, h, parm2; |
| 1604 | uint8_t codec, param; | 1604 | uint8_t codec, param; |
| 1605 | int16_t left, top; | 1605 | int16_t left, top; |
| 1606 | int fsc, sote; | ||
| 1606 | 1607 | ||
| 1607 | codec = bytestream2_get_byteu(gb); | 1608 | codec = bytestream2_get_byteu(gb); |
| 1608 | param = bytestream2_get_byteu(gb); | 1609 | param = bytestream2_get_byteu(gb); |
| @@ -1620,6 +1621,14 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) · 11 unmodified lines | |||
| 1620 | return 0; | 1621 | return 0; |
| 1621 | } | 1622 | } |
| 1622 | 1623 | ||
| 1624 | /* codecs with their own buffers */ | ||
| 1625 | fsc = (codec == 37 || codec == 47 || codec == 48); | ||
| 1626 | |||
| 1627 | /* special case for "Shadows of the Empire" videos */ | ||
| 1628 | sote = ((w == 640) && (h == 272) && (codec == 47)); | ||
| 1629 | if (sote) | ||
| 1630 | left = top = 0; | ||
| 1631 | |||
| 1623 | if (!ctx->have_dimensions) { | 1632 | if (!ctx->have_dimensions) { |
| 1624 | int xres, yres; | 1633 | int xres, yres; |
| 1625 | if (ctx->subversion < 2) { | 1634 | if (ctx->subversion < 2) { |
| @@ -1633,12 +1642,24 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) · 7 unmodified lines | |||
| 1633 | yres = h; | 1642 | yres = h; |
| 1634 | ctx->have_dimensions = 1; | 1643 | ctx->have_dimensions = 1; |
| 1635 | } else { | 1644 | } else { |
| 1636 | /* Rebel Assault 2: 424x260 internal size */ | 1645 | /* detect common sizes */ |
| 1637 | if (((left + w) == 424) && ((top + h) == 260)) | 1646 | xres = w + left; |
| 1647 | yres = h + top; | ||
| 1648 | if (sote) { | ||
| 1649 | /* SotE: has top=60 at all times to center video | ||
| 1650 | * inside the 640x480 game window | ||
| 1651 | */ | ||
| 1652 | xres = w; | ||
| 1653 | yres = h; | ||
| 1638 | ctx->have_dimensions = 1; | 1654 | ctx->have_dimensions = 1; |
| 1655 | } else if (((xres == 424) && (yres == 260)) || /* RA1 */ | ||
| 1656 | ((xres == 320) && (yres == 200)) || /* ft/dig/... */ | ||
| 1657 | ((xres == 640) && (yres == 480))) { /* ol/comi/mots... */ | ||
| 1658 | ctx->have_dimensions = 1; | ||
| 1659 | } | ||
| 1639 | 1660 | ||
| 1640 | xres = FFMAX(left + w, ctx->width); | 1661 | xres = FFMAX(xres, ctx->width); |
| 1641 | yres = FFMAX(top + h, ctx->height); | 1662 | yres = FFMAX(yres, ctx->height); |
| 1642 | } | 1663 | } |
| 1643 | 1664 | ||
| 1644 | if (ctx->width < xres || ctx->height < yres) { | 1665 | if (ctx->width < xres || ctx->height < yres) { |
| @@ -1652,8 +1673,7 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) · 7 unmodified lines | |||
| 1652 | } | 1673 | } |
| 1653 | } | 1674 | } |
| 1654 | } else { | 1675 | } else { |
| 1655 | if (((left + w > ctx->width) || (top + h > ctx->height)) | 1676 | if (((left + w > ctx->width) || (top + h > ctx->height)) && fsc) { |
| 1656 | && (codec >= 37)) { | ||
| 1657 | /* correct unexpected overly large frames: this happens | 1677 | /* correct unexpected overly large frames: this happens |
| 1658 | * for instance with The Dig's sq1.san video: it has a few | 1678 | * for instance with The Dig's sq1.san video: it has a few |
| 1659 | * (all black) 640x480 frames halfway in, while the rest is | 1679 | * (all black) 640x480 frames halfway in, while the rest is |
| @@ -1671,7 +1691,7 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) · 11 unmodified lines | |||
| 1671 | */ | 1691 | */ |
| 1672 | if (ctx->first_fob) { | 1692 | if (ctx->first_fob) { |
| 1673 | ctx->first_fob = 0; | 1693 | ctx->first_fob = 0; |
| 1674 | if (codec < 37) | 1694 | if (!fsc) |
| 1675 | memset(ctx->frm0, 0, ctx->frm0_size); | 1695 | memset(ctx->frm0, 0, ctx->frm0_size); |
| 1676 | } | 1696 | } |
| 1677 | 1697 | ||