mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
VIDEO: Implement setOutputPixelFormat() for BinkDecoder
This commit is contained in:
parent
d72fee204c
commit
adef12d993
@ -44,7 +44,6 @@ MoviePlayer *CreateBinkPlayer(bool demo) {
|
||||
|
||||
BinkPlayer::BinkPlayer(bool demo) : MoviePlayer(), _demo(demo) {
|
||||
_videoDecoder = new Video::BinkDecoder();
|
||||
_videoDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
|
||||
_subtitleIndex = _subtitles.begin();
|
||||
}
|
||||
|
||||
@ -205,7 +204,10 @@ bool BinkPlayer::loadFile(const Common::String &filename) {
|
||||
|
||||
Common::SeekableReadStream *bink = nullptr;
|
||||
bink = new Common::SeekableSubReadStream(stream, startBinkPos, stream->size(), DisposeAfterUse::YES);
|
||||
return _videoDecoder->loadStream(bink);
|
||||
if (!_videoDecoder->loadStream(bink))
|
||||
return false;
|
||||
_videoDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -65,7 +65,6 @@ bool MovieManager::registerMovie(const char *fileName, bool8 fade, bool8 loop) {
|
||||
g_theMusicManager->StopMusic();
|
||||
|
||||
_binkDecoder = new Video::BinkDecoder();
|
||||
_binkDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
|
||||
|
||||
Common::SeekableReadStream *stream = openDiskFileForBinaryStreamRead(fileName);
|
||||
if (!stream) {
|
||||
@ -74,6 +73,9 @@ bool MovieManager::registerMovie(const char *fileName, bool8 fade, bool8 loop) {
|
||||
if (!_binkDecoder->loadStream(stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_binkDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
|
||||
|
||||
if (_binkDecoder->getWidth() != SCREEN_WIDTH) {
|
||||
_x = (SCREEN_WIDTH / 2) - (_binkDecoder->getWidth() / 2);
|
||||
}
|
||||
|
@ -6182,8 +6182,6 @@ void OptionsManager::DrawSlideShow() {
|
||||
|
||||
// This slide is bink compressed
|
||||
Video::BinkDecoder *binkDecoder = new Video::BinkDecoder();
|
||||
binkDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
|
||||
|
||||
Common::MemoryReadStream *stream = new Common::MemoryReadStream((byte *)slideptr, slideLen);
|
||||
if (!stream) {
|
||||
Fatal_error("Failed open bink file");
|
||||
@ -6192,6 +6190,8 @@ void OptionsManager::DrawSlideShow() {
|
||||
Fatal_error("Failed open bink file");
|
||||
}
|
||||
|
||||
binkDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
|
||||
|
||||
// Verify image dimensions
|
||||
if (binkDecoder->getWidth() > SCREEN_WIDTH || binkDecoder->getHeight() > SCREEN_DEPTH)
|
||||
Fatal_error("Slide image is too large to fit screen!");
|
||||
|
@ -338,8 +338,8 @@ DragItem::DragItem(Myst3Engine *vm, uint id):
|
||||
|
||||
// Load the movie
|
||||
_movieStream = movieDesc.getData();
|
||||
_bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.loadStream(_movieStream);
|
||||
_bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.start();
|
||||
|
||||
const Graphics::Surface *frame = _bink.decodeNextFrame();
|
||||
|
@ -57,8 +57,8 @@ Dialog::Dialog(Myst3Engine *vm, uint id):
|
||||
|
||||
// Load the movie
|
||||
Common::SeekableReadStream *movieStream = movieDesc.getData();
|
||||
_bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.loadStream(movieStream);
|
||||
_bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.start();
|
||||
|
||||
const Graphics::Surface *frame = _bink.decodeNextFrame();
|
||||
|
@ -73,9 +73,9 @@ Movie::Movie(Myst3Engine *vm, uint16 id) :
|
||||
loadPosition(binkDesc.getVideoData());
|
||||
|
||||
Common::SeekableReadStream *binkStream = binkDesc.getData();
|
||||
_bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
_bink.loadStream(binkStream);
|
||||
_bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
|
||||
if (binkDesc.getType() == Archive::kMultitrackMovie || binkDesc.getType() == Archive::kDialogMovie) {
|
||||
uint language = ConfMan.getInt("audio_language");
|
||||
|
@ -1527,8 +1527,8 @@ void Puzzles::projectorLoadBitmap(uint16 bitmap) {
|
||||
// Rebuild the complete background image from the frames of the bink movie
|
||||
Common::SeekableReadStream *movieStream = movieDesc.getData();
|
||||
Video::BinkDecoder bink;
|
||||
bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
bink.loadStream(movieStream);
|
||||
bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
bink.start();
|
||||
|
||||
for (uint i = 0; i < 1024; i += 256) {
|
||||
@ -1554,8 +1554,8 @@ void Puzzles::projectorAddSpotItem(uint16 bitmap, uint16 x, uint16 y) {
|
||||
// Rebuild the complete background image from the frames of the bink movie
|
||||
Common::SeekableReadStream *movieStream = movieDesc.getData();
|
||||
Video::BinkDecoder bink;
|
||||
bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
bink.loadStream(movieStream);
|
||||
bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
bink.start();
|
||||
|
||||
const Graphics::Surface *frame = bink.decodeNextFrame();
|
||||
|
@ -360,8 +360,8 @@ bool MovieSubtitles::loadSubtitles(int32 id) {
|
||||
|
||||
// Load the movie
|
||||
Common::SeekableReadStream *movieStream = movie.getData();
|
||||
_bink.setDefaultHighColorFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.loadStream(movieStream);
|
||||
_bink.setOutputPixelFormat(Texture::getRGBAPixelFormat());
|
||||
_bink.start();
|
||||
|
||||
return true;
|
||||
|
@ -65,14 +65,14 @@ int MoviePlayer::load(const Common::String &filename, int flags, int image) {
|
||||
if (_video->isVideoLoaded())
|
||||
_video->close();
|
||||
|
||||
// Ensure that Bink will use our PixelFormat
|
||||
_video->setDefaultHighColorFormat(g_system->getScreenFormat());
|
||||
|
||||
if (!_video->loadFile(filename)) {
|
||||
warning("Failed to load video file %s", filename.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ensure that Bink will use our PixelFormat
|
||||
_video->setOutputPixelFormat(g_system->getScreenFormat());
|
||||
|
||||
_video->start();
|
||||
|
||||
debug(1, "Playing video %s", filename.c_str());
|
||||
|
@ -41,7 +41,6 @@ FMVScreen::FMVScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
_bitmap->setSamplingFilter(StarkSettings->getImageSamplingFilter());
|
||||
|
||||
_decoder = new Video::BinkDecoder();
|
||||
_decoder->setDefaultHighColorFormat(_bitmap->getBestPixelFormat());
|
||||
_decoder->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
|
||||
_surfaceRenderer = _gfx->createSurfaceRenderer();
|
||||
@ -82,6 +81,7 @@ void FMVScreen::play(const Common::String &name) {
|
||||
if (!_decoder->isVideoLoaded()) {
|
||||
error("Could not open %s", name.c_str());
|
||||
}
|
||||
_decoder->setOutputPixelFormat(_bitmap->getBestPixelFormat());
|
||||
_decoder->start();
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,9 @@ void VisualSmacker::loadBink(Common::SeekableReadStream *stream) {
|
||||
|
||||
_decoder = new Video::BinkDecoder();
|
||||
_decoder->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
// We need a format with alpha transparency, so we can't use _bitmap->getBestPixelFormat() here.
|
||||
_decoder->setDefaultHighColorFormat(Gfx::Driver::getRGBAPixelFormat());
|
||||
_decoder->loadStream(stream);
|
||||
// We need a format with alpha transparency, so we can't use _bitmap->getBestPixelFormat() here.
|
||||
_decoder->setOutputPixelFormat(Gfx::Driver::getRGBAPixelFormat());
|
||||
|
||||
init();
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
|
||||
uint32 videoFlags = _bink->readUint32LE();
|
||||
|
||||
// BIKh and BIKi swap the chroma planes
|
||||
addTrack(new BinkVideoTrack(width, height, getDefaultHighColorFormat(), frameCount,
|
||||
addTrack(new BinkVideoTrack(width, height, frameCount,
|
||||
Common::Rational(frameRateNum, frameRateDen), (id == kBIKhID || id == kBIKiID), videoFlags & kVideoFlagAlpha, id));
|
||||
|
||||
uint32 audioTrackCount = _bink->readUint32LE();
|
||||
@ -242,8 +242,8 @@ BinkDecoder::AudioInfo::~AudioInfo() {
|
||||
delete dct;
|
||||
}
|
||||
|
||||
BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id) :
|
||||
_frameCount(frameCount), _frameRate(frameRate), _swapPlanes(swapPlanes), _hasAlpha(hasAlpha), _id(id) {
|
||||
BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id) :
|
||||
_frameCount(frameCount), _frameRate(frameRate), _swapPlanes(swapPlanes), _hasAlpha(hasAlpha), _id(id), _surface(nullptr) {
|
||||
_curFrame = -1;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
@ -269,8 +269,8 @@ BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, const G
|
||||
}
|
||||
|
||||
// Make the surface even-sized:
|
||||
_surfaceHeight = height;
|
||||
_surfaceWidth = width;
|
||||
_surfaceHeight = _height = height;
|
||||
_surfaceWidth = _width = width;
|
||||
|
||||
if (height & 1) {
|
||||
_surfaceHeight++;
|
||||
@ -279,12 +279,11 @@ BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, const G
|
||||
_surfaceWidth++;
|
||||
}
|
||||
|
||||
_surface.create(_surfaceWidth, _surfaceHeight, format);
|
||||
// Since we over-allocate to make surfaces even-sized
|
||||
// we need to set the actual VIDEO size back into the
|
||||
// surface.
|
||||
_surface.h = height;
|
||||
_surface.w = width;
|
||||
_pixelFormat = g_system->getScreenFormat();
|
||||
|
||||
// Default to a 32bpp format, if in 8bpp mode
|
||||
if (_pixelFormat.bytesPerPixel == 1)
|
||||
_pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);
|
||||
|
||||
// Compute the video dimensions in blocks
|
||||
_yBlockWidth = (width + 7) >> 3;
|
||||
@ -323,7 +322,11 @@ BinkDecoder::BinkVideoTrack::~BinkVideoTrack() {
|
||||
_huffman[i] = 0;
|
||||
}
|
||||
|
||||
_surface.free();
|
||||
if (_surface) {
|
||||
_surface->free();
|
||||
delete _surface;
|
||||
_surface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Common::Rational BinkDecoder::getFrameRate() {
|
||||
@ -446,6 +449,16 @@ bool BinkDecoder::BinkVideoTrack::rewind() {
|
||||
void BinkDecoder::BinkVideoTrack::decodePacket(VideoFrame &frame) {
|
||||
assert(frame.bits);
|
||||
|
||||
if (!_surface) {
|
||||
_surface = new Graphics::Surface();
|
||||
_surface->create(_surfaceWidth, _surfaceHeight, _pixelFormat);
|
||||
// Since we over-allocate to make surfaces even-sized
|
||||
// we need to set the actual VIDEO size back into the
|
||||
// surface.
|
||||
_surface->h = _height;
|
||||
_surface->w = _width;
|
||||
}
|
||||
|
||||
if (_hasAlpha) {
|
||||
if (_id == kBIKiID)
|
||||
frame.bits->skip(32);
|
||||
@ -470,11 +483,11 @@ void BinkDecoder::BinkVideoTrack::decodePacket(VideoFrame &frame) {
|
||||
// to allow for odd-sized videos.
|
||||
if (_hasAlpha) {
|
||||
assert(_curPlanes[0] && _curPlanes[1] && _curPlanes[2] && _curPlanes[3]);
|
||||
YUVToRGBMan.convert420Alpha(&_surface, Graphics::YUVToRGBManager::kScaleITU, _curPlanes[0], _curPlanes[1], _curPlanes[2], _curPlanes[3],
|
||||
YUVToRGBMan.convert420Alpha(_surface, Graphics::YUVToRGBManager::kScaleITU, _curPlanes[0], _curPlanes[1], _curPlanes[2], _curPlanes[3],
|
||||
_surfaceWidth, _surfaceHeight, _yBlockWidth * 8, _uvBlockWidth * 8);
|
||||
} else {
|
||||
assert(_curPlanes[0] && _curPlanes[1] && _curPlanes[2]);
|
||||
YUVToRGBMan.convert420(&_surface, Graphics::YUVToRGBManager::kScaleITU, _curPlanes[0], _curPlanes[1], _curPlanes[2],
|
||||
YUVToRGBMan.convert420(_surface, Graphics::YUVToRGBManager::kScaleITU, _curPlanes[0], _curPlanes[1], _curPlanes[2],
|
||||
_surfaceWidth, _surfaceHeight, _yBlockWidth * 8, _uvBlockWidth * 8);
|
||||
}
|
||||
|
||||
@ -675,8 +688,8 @@ void BinkDecoder::BinkVideoTrack::mergeHuffmanSymbols(VideoFrame &video, byte *d
|
||||
}
|
||||
|
||||
void BinkDecoder::BinkVideoTrack::initBundles() {
|
||||
uint32 bw = (_surface.w + 7) >> 3;
|
||||
uint32 bh = (_surface.h + 7) >> 3;
|
||||
uint32 bw = (_width + 7) >> 3;
|
||||
uint32 bh = (_height + 7) >> 3;
|
||||
uint32 blocks = bw * bh;
|
||||
|
||||
for (int i = 0; i < kSourceMAX; i++) {
|
||||
@ -684,8 +697,8 @@ void BinkDecoder::BinkVideoTrack::initBundles() {
|
||||
_bundles[i].dataEnd = _bundles[i].data + blocks * 64;
|
||||
}
|
||||
|
||||
uint32 cbw[2] = { (uint32)((_surface.w + 7) >> 3), (uint32)((_surface.w + 15) >> 4) };
|
||||
uint32 cw [2] = { (uint32)( _surface.w ), (uint32)( _surface.w >> 1) };
|
||||
uint32 cbw[2] = { (uint32)((_width + 7) >> 3), (uint32)((_width + 15) >> 4) };
|
||||
uint32 cw [2] = { (uint32)( _width ), (uint32)( _width >> 1) };
|
||||
|
||||
// Calculate the lengths of an element count in bits
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -147,15 +147,16 @@ private:
|
||||
|
||||
class BinkVideoTrack : public FixedRateVideoTrack {
|
||||
public:
|
||||
BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id);
|
||||
BinkVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id);
|
||||
~BinkVideoTrack();
|
||||
|
||||
uint16 getWidth() const override { return _surface.w; }
|
||||
uint16 getHeight() const override{ return _surface.h; }
|
||||
Graphics::PixelFormat getPixelFormat() const override { return _surface.format; }
|
||||
uint16 getWidth() const override { return _width; }
|
||||
uint16 getHeight() const override{ return _height; }
|
||||
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
|
||||
bool setOutputPixelFormat(const Graphics::PixelFormat &format) { _pixelFormat = format; return true; }
|
||||
int getCurFrame() const override { return _curFrame; }
|
||||
int getFrameCount() const override { return _frameCount; }
|
||||
const Graphics::Surface *decodeNextFrame() override { return &_surface; }
|
||||
const Graphics::Surface *decodeNextFrame() override { return _surface; }
|
||||
bool isSeekable() const override{ return true; }
|
||||
bool seek(const Audio::Timestamp &time) override { return true; }
|
||||
bool rewind() override;
|
||||
@ -243,7 +244,10 @@ private:
|
||||
int _curFrame;
|
||||
int _frameCount;
|
||||
|
||||
Graphics::Surface _surface;
|
||||
Graphics::Surface *_surface;
|
||||
Graphics::PixelFormat _pixelFormat;
|
||||
uint16 _width;
|
||||
uint16 _height;
|
||||
int _surfaceWidth; ///< The actual surface width
|
||||
int _surfaceHeight; ///< The actual surface height
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user