Applied patch #1155731, reducing the memory usage of the MPEG player by

about 8 MB.

svn-id: r17007
This commit is contained in:
Torbjörn Andersson 2005-03-06 14:12:40 +00:00
parent b7c2926a0b
commit e3105f926b
5 changed files with 183 additions and 72 deletions

View file

@ -26,11 +26,17 @@
#include "common/file.h"
#include "common/system.h"
#include "common/util.h"
#include "common/scaler/intern.h"
namespace Graphics {
BaseAnimationState::BaseAnimationState(SoundMixer *snd, OSystem *sys, int width, int height)
: MOVIE_WIDTH(width), MOVIE_HEIGHT(height), _snd(snd), _sys(sys) {
#ifndef BACKEND_8BIT
colortab = NULL;
rgb_2_pix = NULL;
bitFormat = 0;
#endif
}
BaseAnimationState::~BaseAnimationState() {
@ -42,6 +48,8 @@ BaseAnimationState::~BaseAnimationState() {
#ifndef BACKEND_8BIT
_sys->hideOverlay();
free(overlay);
free(colortab);
free(rgb_2_pix);
#endif
delete bgSoundStream;
#endif
@ -297,87 +305,194 @@ void BaseAnimationState::buildLookup(int p, int lines) {
#else
OverlayColor *BaseAnimationState::lookup = 0;
// The YUV to RGB conversion code is derived from SDL's YUV overlay code, which
// in turn appears to be derived from mpeg_play. The following copyright
// notices have been included in accordance with the original license. Please
// note that the term "software" in this context only applies to the two
// functions buildLookup() and plotYUV() below.
/**
* This function should be called when the screen changes to invalidate and,
* optionally, rebuild the lookup table.
* @param rebuild If true, rebuild the table.
*/
// Copyright (c) 1995 The Regents of the University of California.
// All rights reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without written agreement is
// hereby granted, provided that the above copyright notice and the following
// two paragraphs appear in all copies of this software.
//
// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
// CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
// PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
// FIXME: We will need to call the function from the game's main event loop
// as well, not just the cutscene players' ones.
// Copyright (c) 1995 Erik Corry
// All rights reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without written agreement is
// hereby granted, provided that the above copyright notice and the following
// two paragraphs appear in all copies of this software.
//
// IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
// THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
// BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
// FIXME: It would be nice with a heuristic to check if the table really does
// need to be rebuilt.
void BaseAnimationState::invalidateLookup(bool rebuild) {
free(lookup);
lookup = 0;
if (rebuild)
buildLookup();
}
// Portions of this software Copyright (c) 1995 Brown University.
// All rights reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without written agreement
// is hereby granted, provided that the above copyright notice and the
// following two paragraphs appear in all copies of this software.
//
// IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
// UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
// BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
void BaseAnimationState::buildLookup() {
if (lookup)
// Do we already have lookup tables for this bit format?
if (gBitFormat == bitFormat && colortab && rgb_2_pix)
return;
lookup = (OverlayColor *)calloc((BITDEPTH+1) * (BITDEPTH+1) * 256, sizeof(OverlayColor));
if (!lookup) {
warning("Not enough memory to allocate LUT - cannot play sequence");
return;
free(colortab);
free(rgb_2_pix);
colortab = (int16 *)malloc(4 * 256 * sizeof(int16));
int16 *Cr_r_tab = &colortab[0 * 256];
int16 *Cr_g_tab = &colortab[1 * 256];
int16 *Cb_g_tab = &colortab[2 * 256];
int16 *Cb_b_tab = &colortab[3 * 256];
rgb_2_pix = (uint16 *)malloc(3 * 768 * sizeof(uint16));
uint16 *r_2_pix_alloc = &rgb_2_pix[0 * 768];
uint16 *g_2_pix_alloc = &rgb_2_pix[1 * 768];
uint16 *b_2_pix_alloc = &rgb_2_pix[2 * 768];
int16 CR, CB;
int i;
// Generate the tables for the display surface
for (i = 0; i < 256; i++) {
// Gamma correction (luminescence table) and chroma correction
// would be done here. See the Berkeley mpeg_play sources.
CR = CB = (i - 128);
Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR);
Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR);
Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB);
}
int y, cb, cr;
int r, g, b;
int pos = 0;
// Set up entries 0-255 in rgb-to-pixel value tables.
for (cr = 0; cr <= BITDEPTH; cr++) {
for (cb = 0; cb <= BITDEPTH; cb++) {
for (y = 0; y < 256; y++) {
r = ((y - 16) * 256 + (int) (256 * 1.596) * ((cr << SHIFT) - 128)) / 256;
g = ((y - 16) * 256 - (int) (0.813 * 256) * ((cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
b = ((y - 16) * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
if (r < 0) r = 0;
else if (r > 255) r = 255;
if (g < 0) g = 0;
else if (g > 255) g = 255;
if (b < 0) b = 0;
else if (b > 255) b = 255;
lookup[pos++] = _sys->RGBToColor(r, g, b);
}
if (gBitFormat == 565) {
for (i = 0; i < 256; i++) {
r_2_pix_alloc[i + 256] = i >> (8 - 5);
r_2_pix_alloc[i + 256] <<= 11;
g_2_pix_alloc[i + 256] = i >> (8 - 6);
g_2_pix_alloc[i + 256] <<= 5;
b_2_pix_alloc[i + 256] = i >> (8 - 5);
// b_2_pix_alloc[i + 256] <<= 0;
}
} else if (gBitFormat == 555) {
for (i = 0; i < 256; i++) {
r_2_pix_alloc[i + 256] = i >> (8 - 5);
r_2_pix_alloc[i + 256] <<= 10;
g_2_pix_alloc[i + 256] = i >> (8 - 5);
g_2_pix_alloc[i + 256] <<= 5;
b_2_pix_alloc[i + 256] = i >> (8 - 5);
// b_2_pix_alloc[i + 256] <<= 0;
}
} else {
error("Unknown bit format %d", gBitFormat);
}
// Spread out the values we have to the rest of the array so that we do
// not need to check for overflow.
for (i = 0; i < 256; i++) {
r_2_pix_alloc[i] = r_2_pix_alloc[256];
r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
g_2_pix_alloc[i] = g_2_pix_alloc[256];
g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
b_2_pix_alloc[i] = b_2_pix_alloc[256];
b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
}
bitFormat = gBitFormat;
}
void BaseAnimationState::plotYUV(OverlayColor *lut, int width, int height, byte *const *dat) {
if (!lut)
return;
void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) {
OverlayColor *ptr = overlay + (MOVIE_HEIGHT - height) / 2 * MOVIE_WIDTH + (MOVIE_WIDTH - width) / 2;
byte *lum = dat[0];
byte *cr = dat[2];
byte *cb = dat[1];
byte *lum2 = lum + width;
int16 cr_r;
int16 crb_g;
int16 cb_b;
OverlayColor *row1 = ptr;
OverlayColor *row2 = ptr + MOVIE_WIDTH;
int x, y;
int ypos = 0;
int cpos = 0;
int linepos = 0;
for (y = 0; y < height; y += 2) {
for (x = 0; x < width; x += 2) {
int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH+1)) + ((dat[1][cpos] + ROUNDADD)>>SHIFT)) * 256;
cpos++;
register byte L;
ptr[linepos ] = lut[i + dat[0][ ypos ]];
ptr[MOVIE_WIDTH + linepos++] = lut[i + dat[0][width + ypos++]];
ptr[linepos ] = lut[i + dat[0][ ypos ]];
ptr[MOVIE_WIDTH + linepos++] = lut[i + dat[0][width + ypos++]];
cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256];
crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] + colortab[*cb + 2 * 256];
cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256];
++cr;
++cb;
L = *lum++;
*row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
L = *lum++;
*row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
// Now, do second row.
L = *lum2++;
*row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
L = *lum2++;
*row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
}
linepos += (2 * MOVIE_WIDTH - width);
ypos += width;
// These values are at the start of the next line, (due
// to the ++'s above), but they need to be at the start
// of the line after that.
lum += width;
lum2 += width;
row1 += (2 * MOVIE_WIDTH - width);
row2 += (2 * MOVIE_WIDTH - width);
}
}